CACS151 C Programming

C ProgrammingUnit 113 min read

C Basics: Structure, Process Models, and Programming Approaches

Unit 1 of C Programming introduces the foundational concepts of C, including its structure, programming techniques (top-down vs. bottom-up), software process models, and the Program Development Life Cycle (PDLC). It covers keywords, operators, header files, and the role of arrays and functions in programming, with prac

TAKEAWAYS:

  • Understand the structure of a C program (preprocessor directives, functions, main function) and its execution flow.
  • Differentiate between top-down and bottom-up programming approaches and their real-world applications.
  • Define cohesion and coupling and explain their importance in modular programming.
  • Learn about keywords, operators, and header files in C and their roles in program development.
  • Recognize the Program Development Life Cycle (PDLC) and its phases.
  • Apply C programming concepts to solve real-world problems, such as managing employee data or finding array elements.

The Structure of a C Program

A C program is organized into functions, with the main() function serving as the entry point. It consists of:

  • Preprocessor directives (e.g., #include, #define).
  • Variable declarations (data types, storage classes).
  • Functions (modular code blocks).
  • Statements (instructions executed sequentially).

Visual: Basic C Program Structure

flowchart TD
    A["Preprocessor Directives\n(#include, #define)"] --> B["Function Declarations\n(prototypes)"]
    B --> C["main() Function\n(entry point)"]
    C --> D["Statements\n(control structures, loops)"]
    C --> E["Other Functions\n(modular code)"]
    D --> F["End of Program"]
    E --> F

Example: Simple C Program

#include <stdio.h>  // Preprocessor directive (header file)

int main() {        // Main function (entry point)
    printf("Hello, World!");  // Statement
    return 0;       // Exit status
}

Trace:

Step Action Output/State
1 #include <stdio.h> Loads standard I/O
2 int main() Program starts
3 printf("Hello, World!"); Prints "Hello, World!"
4 return 0; Program exits

Programming Techniques: Top-Down vs. Bottom-Up

Definitions:

  • Top-Down Approach:

    • Start with the main function and break it into sub-functions.
    • Modular design (e.g., main() calls calculate() and display()).
    • Easier debugging but requires careful planning.
  • Bottom-Up Approach:

    • Start with small, reusable functions and combine them.
    • Reusable modules but harder to test initially.

Comparison Table:

Feature Top-Down Approach Bottom-Up Approach
Starting Point Main function Small functions
Complexity High initial complexity Low initial complexity
Testing Easier (module-by-module) Harder (integration testing)
Reusability Lower Higher
Example main() → calculate() → add() add(), subtract() → calculate()

Real-World Example: eSewa (Nepal)

  • Top-Down: The main() function handles user login, while sub-functions manage payment processing (process_payment()) and transaction history (show_history()).
  • Bottom-Up: Reusable functions like validate_user() and generate_receipt() are combined to build the payment system.

Cohesion and Coupling

Definitions:

  • Cohesion: Measures how closely related the tasks of a module are.

    • High cohesion: Module does one thing well (e.g., calculate_tax()).
    • Low cohesion: Module does multiple unrelated tasks (e.g., misc_utils() handling I/O, math, and strings).
  • Coupling: Measures how dependent modules are on each other.

    • Low coupling: Modules interact minimally (e.g., passing data via parameters).
    • High coupling: Modules are tightly dependent (e.g., one module directly accesses another’s variables).

Visual: Cohesion and Coupling in Modules

graph LR
    A["High Cohesion\nSingle Responsibility"] --> B["Low Coupling\nIndependent Modules"]
    C["Low Cohesion\nMultiple Tasks"] --> D["High Coupling\nTight Dependencies"]

Example: Khalti Payment System

  • High Cohesion: The verify_payment() function only checks transaction validity.
  • Low Coupling: verify_payment() takes transaction_id as input and returns a boolean, without accessing other modules’ data.

Keywords, Operators, and Header Files

1. Keywords (Reserved Words)

C has 32 keywords (e.g., int, if, return, while). These cannot be reused as identifiers. Example Keywords:

auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while

2. Operators

C supports 7 types of operators:

Type Example Operators Example Usage
Arithmetic +, -, *, /, % sum = a + b;
Relational ==, !=, >, <, >=, <= if (a > b)
Logical &&, ||, ! if (a > 0 && b < 10)
Assignment =, +=, -=, *=, /= x += 5;
Bitwise &, |, ^, ~, <<, >> mask = a & 0xFF;
Special sizeof, ? : (ternary) max = (a > b) ? a : b;
Miscellaneous ,, &, * (address-of) int *ptr = &x;

3. Header Files

Header files (.h) contain function declarations, macros, and type definitions. Common Header Files:

Header File Purpose
<stdio.h> Input/Output functions (printf, scanf)
<stdlib.h> Memory allocation (malloc), utilities
<math.h> Mathematical functions (sin, sqrt)
<string.h> String operations (strcpy, strlen)
<ctype.h> Character handling (isalpha, tolower)

Example: Using stdio.h

#include <stdio.h>  // Required for printf/scanf

int main() {
    printf("Enter a number: ");
    int num;
    scanf("%d", &num);  // Reads input
    printf("You entered: %d\n", num);
    return 0;
}

Software Process Models

Definitions:

  • Software Process Model: A framework defining phases of software development.
  • Common Models:
    1. Waterfall Model: Linear, sequential phases (requirements → design → implementation → testing → maintenance).
    2. Prototyping Model: Build a working model first, then refine.
    3. Spiral Model: Iterative with risk analysis at each cycle.
    4. Agile Model: Flexible, incremental development (e.g., Scrum).

Visual: Waterfall Model Phases

flowchart TD
    A["Requirements\nAnalysis"] --> B["System\nDesign"]
    B --> C["Implementation\n(Coding)"]
    C --> D["Testing"]
    D --> E["Deployment"]
    E --> F["Maintenance"]

Real-World Example: Pathao (Ride-Hailing App)

  • Waterfall: Initial phases defined requirements (user login, ride booking) before coding.
  • Agile: Later iterations added features like Pathao Pay and driver incentives incrementally.

Program Development Life Cycle (PDLC)

PDLC consists of 7 phases:

  1. Requirements Gathering: Identify user needs (e.g., "Ncell needs a billing system").
  2. System Design: High-level architecture (e.g., database, UI, backend).
  3. Algorithm Design: Pseudocode for critical functions (e.g., calculate_bill()).
  4. Coding: Write C programs (e.g., main.c, billing.c).
  5. Testing: Debug and validate (e.g., unit tests for calculate_tax()).
  6. Deployment: Release to users (e.g., NEPSE trading platform).
  7. Maintenance: Fix bugs, update features (e.g., Daraz adding new payment methods).

Example: NTC Billing System

  1. Requirement: Automate electricity bill generation.
  2. Design: Use arrays to store customer data and functions to calculate bills.
  3. Code:
    #include <stdio.h>
    #define MAX_CUSTOMERS 100
    
    void calculate_bill(float units, float *bill) {
        *bill = units * 3.5;  // Rate: NPR 3.5 per unit
    }
    
    int main() {
        float units, bill;
        printf("Enter units consumed: ");
        scanf("%f", &units);
        calculate_bill(units, &bill);
        printf("Bill: %.2f\n", bill);
        return 0;
    }
    
  4. Test: Verify with inputs like units = 100 → bill = 350.00.
  5. Deploy: Integrate with NTC’s central system.

Why Arrays and Functions Are Essential

Arrays

  • Definition: Contiguous memory locations storing same data type.
  • Why Use Arrays?
    • Store multiple values efficiently (e.g., employee ages).
    • Enable batch processing (e.g., sorting, searching).
  • Example: Second Largest Age in an Array
    #include <stdio.h>
    #define N 30
    
    int find_second_largest(int ages[N]) {
        int first = second = -1;
        for (int i = 0; i < N; i++) {
            if (ages[i] > first) {
                second = first;
                first = ages[i];
            } else if (ages[i] > second && ages[i] != first) {
                second = ages[i];
            }
        }
        return second;
    }
    
    int main() {
        int ages[N] = {25, 30, 22, 28, 35, ...};  // 30 employees
        printf("Second largest age: %d\n", find_second_largest(ages));
        return 0;
    }
    
    Trace:
    Step first second Action
    1 -1 -1 Initialize
    2 25 -1 ages[0] = 25 > first
    3 30 25 ages[1] = 30 > first
    ... ... ... Update second for 28, 35, etc.
    30 35 30 Final second = 30

Functions

  • Definition: Reusable code blocks performing specific tasks.
  • Why Use Functions?
    • Modularity: Break programs into manageable parts.
    • Reusability: Call the same function multiple times (e.g., calculate_tax()).
    • Easier Debugging: Test functions independently.
  • Example: Smallest Number in an Array
    #include <stdio.h>
    #define N 5
    
    int find_min(int arr[N]) {
        int min = arr[0];
        for (int i = 1; i < N; i++) {
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        return min;
    }
    
    int main() {
        int numbers[N] = {10, 5, 20, 15, 8};
        printf("Smallest number: %d\n", find_min(numbers));
        return 0;
    }
    
    Trace:
    Step min arr[i] Action
    1 10 5 5 < 10 → min = 5
    2 5 20 20 > 5 → no change
    3 5 15 15 > 5 → no change
    4 5 8 8 > 5 → no change
    5 5 - Return 5

In the Real World

  1. eSewa (Nepal):

    • Arrays: Store transaction records (e.g., transactions[1000] for 1000 users).
    • Functions: process_payment() handles deductions and updates balances.
    • Coupling: Low coupling between authenticate_user() and generate_receipt().
  2. Khalti:

    • Top-Down Approach: main() orchestrates login, payment, and confirmation flows.
    • Header Files: <openssl/ssl.h> for secure transactions.
  3. NTC Billing System:

    • Arrays: customer_data[5000] stores meter readings for 5000 households.
    • Functions: calculate_surcharge() applies penalties for late payments.
  4. Daraz Order Processing:

    • Queues: Orders are stored in a FIFO queue (order_queue) for sequential processing.
    • Functions: ship_order() and update_inventory() are modular and reusable.
  5. NEPSE Trading Platform:

    • PDLC: Follows a spiral model for iterative updates (e.g., adding new stock indices).
    • Cohesion: execute_trade() handles only trading logic, not UI or database.

Exam Tip

  1. Definitions:

    • Memorize keywords, operators, and header files (e.g., <stdio.h> for I/O).
    • Differentiate top-down vs. bottom-up with examples (e.g., eSewa vs. Khalti).
  2. Program Structure:

    • Always include #include <stdio.h> in programs.
    • Structure answers with:
      • Preprocessor directives (e.g., #define).
      • main() function as the entry point.
      • Modular functions (e.g., calculate(), display()).
  3. Cohesion and Coupling:

    • High cohesion = one task per function (e.g., validate_input()).
    • Low coupling = pass data via parameters, not global variables.
  4. PDLC:

    • List 7 phases in order: requirements → design → algorithm → coding → testing → deployment → maintenance.
    • Relate to real-world systems (e.g., NTC billing, Daraz orders).
  5. Arrays and Functions:

    • For array questions, trace steps (e.g., finding second largest).
    • For functions, show prototypes and calling statements in main().
  6. Common Mistakes to Avoid:

    • Forgetting to initialize variables (e.g., int second = -1).
    • Using global variables (leads to high coupling).
    • Not returning values from functions (e.g., return min;).

mindmap
  root((C Programming Basics))
    Key Concepts
      Structure of C Program
        Preprocessor Directives
        main() Function
        Functions
      Programming Techniques
        Top-Down Approach
        Bottom-Up Approach
    Modularity
      Cohesion
        High Cohesion
        Low Cohesion
      Coupling
        Low Coupling
        High Coupling
    Language Elements
      Keywords
      Operators
        Arithmetic
        Relational
        Logical
      Header Files
        stdio.h
        stdlib.h
    Development Process
      Software Process Models
        Waterfall
        Agile
      PDLC
        Requirements
        Design
        Implementation
        Testing
        Deployment
        Maintenance
    Practical Applications
      Arrays
        Storing Multiple Values
        Batch Processing
      Functions
        Reusability
        Modularity

Based on the TU BCA syllabus for C Programming (CACS151), unit 1.

Discussion

Loading…