Variables, Control Structures, and Calculations in C

Learning Outcomes and Core Program Control Constructs

A computer program is essentially a sequence of instructions that tells a computer what data to work with, what calculations to perform, what decisions to make, and what operations to repeat. Mastery of procedural programming in C requires understanding three fundamental control structures that dictate program execution flow: sequence, selection, and repetition (iteration).

Sequence represents the simplest control flow, where instructions execute sequentially one after another in a linear progression (Instruction 1 followed by Instruction 2, Instruction 3, and Instruction 4).

Selection allows a program to evaluate logical conditions and choose between alternative paths of execution. The basic logic follows: IF a condition is true, execute a specific block of code; ELSE, execute a different block of code.

Repetition, or iteration, enables a program to execute a set of instructions multiple times based on a logical test. The fundamental structure operates such that WHILE a specified condition evaluates to true, the program continues to repeat those instructions. Together, sequence, selection, and repetition form the complete foundation of procedural programming.

Variables, Data Types, and Naming Conventions

A variable is a named location in the computer's memory used to store a value that can change while a program executes. Conceptually, a variable functions like a labelled storage box. For instance, declaring int age; instructs the program to reserve an integer memory slot labelled age. Assigning a value via age = 20; places the value 2020 inside that labelled container. Alternatively, a variable can be declared and initialized simultaneously in a single statement: int age = 20;.

Every variable in C must be explicitly declared with a specific data type prior to its use. The general syntax for variable declaration is data_type variable_name;. Common variable declarations include int age;, float temperature;, double salary;, and char grade;. Multiple variables sharing the exact same data type can be declared together in a comma-separated list, such as int age, year, marks;. However, declaring each variable on its own line enhances code readability and clarity.

Common C Data Types and Examples

C provides standard primitive data types tailored to specific categories of information:

  • int: Used for storing whole numbers (integers) without decimal points. Example value: 2525. Example declaration: int students = 45;.

  • float: Used for storing single-precision decimal numbers. Example value: 25.525.5. Example declaration: float temperature = 27.5;.

  • double: Used for storing double-precision decimal numbers, providing greater numeric precision for decimal calculations. Example value: 25.5678925.56789. Example declaration: double salary = 125000.75;.

  • char: Used for storing a single character. Example value: 'A'. Example declaration: char grade = 'A';.

A critical syntax rule governs character and text representation in C. Single character literals assigned to a char variable must always be enclosed in single quotation marks (e.g., char grade = 'A';). Conversely, text strings used in functions such as output statements must always be enclosed in double quotation marks (e.g., printf("Hello");).

Variable names in C must adhere to strict syntactical rules:

  1. Names can contain uppercase and lowercase letters, digits, and underscores (_).

  2. Names cannot start with a digit.

  3. Names cannot contain spaces.

  4. Names cannot be reserved C keywords (such as int, float, or return).

Valid variable names include age, studentAge, student_age, marks1, and totalMarks. Invalid variable names include 2marks (because it starts with a numeric digit), student age (because it contains a space), and float (because it is a reserved language keyword).

C is strictly case-sensitive. Consequently, age, Age, and AGE represent three entirely distinct variable identifiers in memory. Beyond legal syntax, good programming practice dictates choosing self-documenting, descriptive variable names. Using identifiers like studentAge, averageMarks, and monthlySalary communicates clear semantic meaning, whereas arbitrary identifiers such as x, a, or z obfuscate code purpose.

Variable Declaration, Initialization, Constants, and Input

When a variable value must remain unchanged throughout the entire execution of a program, C provides the const qualifier to declare named constants. Defining a constant prevents accidental modification. For example, const float PI = 3.14159; fixes the value of PI. Any subsequent attempt to reassign PI (e.g., PI = 4.0;) results in a compilation error.

To accept dynamic input from a user via the keyboard, C utilizes the standard input function scanf(). This function reads formatted data from standard input and stores it into the specified variable's memory address. The address-of operator & must prefix non-pointer variables inside scanf() calls to supply the memory address where the entered value should be written.

#include <stdio.h>

int main() {
    int age;
    printf("Enter your age: ");
    scanf("%d", &age);
    printf("You are %d years old.", age);
    return 0;
}
Common Format Specifiers for scanf

Format specifiers inside scanf() and printf() inform the program how to interpret input and output bytes:

  • %d: Format specifier for integer (int) data types.

  • %f: Format specifier for single-precision floating-point (float) data types.

  • %lf: Format specifier for double-precision floating-point (double) data types.

  • %c: Format specifier for single character (char) data types.

Practice scenarios regarding variable declarations and input handling highlight proper syntax application:

  1. Declaring standard student variables: int age; for student age, float averageMark; for average mark, char grade; for grade, and int registrationNumber; for registration number.

  2. Evaluating validity: int age; is valid; float average; is valid; int 2students; is invalid (starts with a digit); char grade; is valid; int student age; is invalid (contains a space); double salary; is valid.

  3. Code output analysis: Given int x = 10; int y = 20; printf("%d", x + y);, the program evaluates the sum 10+2010 + 20 and displays 30.

Arithmetic Operations, Operators, and Mathematical Expressions

Computations are essential to software execution. C provides standard binary arithmetic operators to perform mathematical calculations across numeric values and variables.

Arithmetic Operators in C

The basic arithmetic operators in C are:

  • +: Addition operator, e.g., a + b.

  • -: Subtraction operator, e.g., a - b.

  • *: Multiplication operator, e.g., a * b.

  • /: Division operator, e.g., a / b.

  • %: Remainder (modulus) operator, e.g., a % b.

Executing basic calculations in C yields specific outputs based on operator semantics:

#include <stdio.h>

int main() {
    int a = 20;
    int b = 6;
    printf("Addition = %d
", a + b);
    printf("Subtraction = %d
", a - b);
    printf("Multiplication = %d
", a * b);
    printf("Division = %d
", a / b);
    printf("Remainder = %d
", a % b);
    return 0;
}

Running this code produces the exact output: Addition = 26 Subtraction = 14 Multiplication = 120 Division = 3 Remainder = 2

Integer division requires careful attention. When both operands in a division operation are integers, C discards any fractional decimal remainder and performs truncated integer division. For example, evaluating int result; result = 7 / 2; assigns 3 to result rather than 3.5. To preserve decimal precision, at least one operand must be a floating-point literal or explicitly cast: float result = 7.0 / 2.0; or using type casting: float result = (float)7 / 2;.

The modulus operator % computes the integer remainder after division. Evaluating 17 % 5 produces 2 because 17÷5=317 \div 5 = 3 with a remainder of 22. A frequent practical application of the modulus operator is testing whether an integer is even or odd using if (number % 2 == 0).

The assignment operator = stores the evaluated value of the expression on its right-hand side into the variable specified on its left-hand side. It denotes value storage rather than mathematical equivalence. C provides compound assignment operators that combine arithmetic with assignment:

  • x += 5; is equivalent to x = x + 5;

  • x -= 5; is equivalent to x = x - 5;

  • x *= 5; is equivalent to x = x * 5;

  • x /= 5; is equivalent to x = x / 5;

For incrementing and decrementing integer values by 1, C offers unary operators:

  • x++; increments x by 1. For example, if int count = 5;, executing count++; modifies count to 6.

  • x--; decrements x by 1. Executing count--; modifies count back to 5.

Operator precedence dictates the evaluation order of mathematical expressions. Multiplication, division, and modulus carry higher precedence than addition and subtraction. In int result = 10 + 5 * 2;, multiplication occurs first (5×2=105 \times 2 = 10), followed by addition (10+10=2010 + 10 = 20), yielding 20. Standard parentheses () override default precedence rules: result = (10 + 5) * 2; computes 10+5=1510 + 5 = 15 first, then multiplies by 22 to yield 30.

Practice calculations evaluate as follows:

  1. Given int a = 15; int b = 4;:

    • a + b evaluates to 19

    • a - b evaluates to 11

    • a * b evaluates to 60

    • a / b evaluates to 3

    • a % b evaluates to 3

  2. Program execution trace: Given int x = 10; x += 5; x *= 2; printf("%d", x);, x becomes 15 after x += 5, then 30 after x *= 2. The output is 30.

  3. Expression evaluation: int result = 10 + 5 * 2; produces 20.

  4. Rectangle area computation formula: Area=length×width\text{Area} = \text{length} \times \text{width}.

  5. Temperature conversion formula from Celsius (CC) to Fahrenheit (FF): F=(C×95)+32F = \left(C \times \frac{9}{5}\right) + 32.

Program Sequence and Sequential Execution Analysis

Sequential control flow dictates that instructions execute sequentially in exact top-to-bottom order. Consider the basic summation sequence:

#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;
    int sum;
    sum = a + b;
    printf("Sum = %d", sum);
    return 0;
}

The precise execution sequence follows eight distinct steps:

  1. Declare variable a.

  2. Assign value 10 to a.

  3. Declare variable b.

  4. Assign value 20 to b.

  5. Declare variable sum.

  6. Calculate a + b (10+2010 + 20).

  7. Store the result (30) in sum.

  8. Display sum.

An integrated sequence example calculates total and average marks for a student across three subjects:

#include <stdio.h>

int main() {
    float programming;
    float mathematics;
    float database;
    float total;
    float average;

    programming = 70;
    mathematics = 65;
    database = 80;

    total = programming + mathematics + database;
    average = total / 3;

    printf("Total = %.2f
", total);
    printf("Average = %.2f
", average);

    return 0;
}

The resulting output is: Total = 215.00 Average = 71.67

The format specifier %.2f formats floating-point values to exactly two decimal places.

Tracing sequential code modifications demonstrates variable state tracking: Given int a = 5; int b = 10; int c; c = a + b; a = c * 2; printf("%d %d %d", a, b, c);:

  1. a initialized to 5, b to 10.

  2. c receives 5 + 10 = 15.

  3. a receives 15 * 2 = 30.

  4. printf outputs 30 10 15.

Selection and Decision-Making Constructs

Selection statements allow programs to make decisions and execute alternate code paths based on logical comparisons.

Relational Operators in C

Relational operators compare two values and evaluate to true (non-zero) or false (0):

  • >: Greater than

  • <: Less than

  • >=: Greater than or equal to

  • <=: Less than or equal to

  • ==: Equal to

  • !=: Not equal to

A critical distinction exists between = and ==. The single equals operator = performs variable assignment (e.g., x = 10; stores 10 in x), whereas the double equals operator == checks equality (e.g., x == 10 tests whether x is equal to 10).

The simple if statement executes a code block only if its condition evaluates to true:

if (condition) {
    statement;
}

For instance, if (age >= 18) { printf("Adult"); } displays "Adult" when age is 18 or greater.

The if...else structure provides a two-way branch:

#include <stdio.h>

int main() {
    int mark;
    printf("Enter mark: ");
    scanf("%d", &mark);

    if (mark >= 50) {
        printf("Pass");
    } else {
        printf("Fail");
    }

    return 0;
}

Multi-way decisions utilize chained if...else if...else structures. Conditions are evaluated sequentially from top to bottom. As soon as one condition evaluates to true, its associated code block executes, and all remaining else if branches are completely bypassed.

if (mark >= 70) {
    printf("A");
} else if (mark >= 60) {
    printf("B");
} else if (mark >= 50) {
    printf("C");
} else if (mark >= 40) {
    printf("D");
} else {
    printf("Fail");
}

Grading scale mapping:

  • Marks 70 to 100: Grade A

  • Marks 60 to 69: Grade B

  • Marks 50 to 59: Grade C

  • Marks 40 to 49: Grade D

  • Marks below 40: Fail

Logical operators combine multiple logical conditions:

  • && (AND): Evaluates to true only if all individual conditions are true. Example: if (age >= 18 && age <= 35) requires age to be within the range [18, 35].

  • || (OR): Evaluates to true if at least one individual condition is true. Example: if (day == 6 || day == 7) evaluates to true if day is either 6 or 7.

  • ! (NOT): Inverts the logical state of a condition.

Nested if statements place an entire if block inside another if block:

if (mark >= 50) {
    if (mark >= 70) {
        printf("Excellent");
    } else {
        printf("Pass");
    }
} else {
    printf("Fail");
}

When evaluating discrete integer or character constants, the switch statement offers a clean alternative to extended if...else if chains:

int choice;
printf("1. Add
2. Subtract
3. Multiply
");
scanf("%d", &choice);

switch (choice) {
    case 1:
        printf("Addition selected");
        break;
    case 2:
        printf("Subtraction selected");
        break;
    case 3:
        printf("Multiplication selected");
        break;
    default:
        printf("Invalid choice");
}

The break; statement terminates the switch block. Omitting break; causes execution to fall through into subsequent case blocks regardless of whether their values match.

Selection practice traces:

  1. Evaluating int x = 15;: Checking if (x > 20) (false), else if (x > 10) (true) prints B.

  2. Simple calculator using switch: maps menu inputs 1, 2, 3, 4 to Addition, Subtraction, Multiplication, and Division respectively.

Iteration and Repetition Structures

Loops execute a block of instructions repeatedly while a specified logical condition remains true. C supports three primary loop constructs: for, while, and do...while.

The for loop consolidates initialization, condition testing, and variable updating into a single header:

for (initialization; condition; update) {
    statements;
}

For example, printing numbers from 1 to 10:

for (int i = 1; i <= 10; i++) {
    printf("%d
", i);
}

The three components function as follows: int i = 1 sets the starting value (initialization); i <= 10 tests whether execution should continue (condition); i++ increments the counter after each iteration (update).

Iteration Trace Table for a For Loop

Tracing for (int i = 1; i <= 5; i++):

  • Iteration 1: i = 1, Condition 1 <= 5 is true, Output 1

  • Iteration 2: i = 2, Condition 2 <= 5 is true, Output 2

  • Iteration 3: i = 3, Condition 3 <= 5 is true, Output 3

  • Iteration 4: i = 4, Condition 4 <= 5 is true, Output 4

  • Iteration 5: i = 5, Condition 5 <= 5 is true, Output 5

  • Iteration 6: i = 6, Condition 6 <= 5 is false, Loop stops

Accumulating values inside a loop requires an accumulator variable initialized before the loop starts:

#include <stdio.h>

int main() {
    int sum = 0;
    for (int i = 1; i <= 5; i++) {
        sum = sum + i;
    }
    printf("Sum = %d", sum);
    return 0;
}
Variable Trace Table for Sum Calculation

Tracing variable state changes across iterations:

  • Start: sum = 0

  • i = 1: sum = 0 + 1 = 1

  • i = 2: sum = 1 + 2 = 3

  • i = 3: sum = 3 + 3 = 6

  • i = 4: sum = 6 + 4 = 10

  • i = 5: sum = 10 + 5 = 15

  • Final Output: Sum = 15

The while loop checks its test condition before executing the loop body:

int i = 1;
while (i <= 5) {
    printf("%d
", i);
    i++;
}

Because condition testing occurs before entry, a while loop executes zero times if the condition is initially false.

The do...while loop checks its test condition after executing the loop body:

int i = 1;
do {
    printf("%d
", i);
    i++;
} while (i <= 5);

Because condition testing occurs at the end of an iteration, a do...while loop is guaranteed to execute its body at least once.

Comparison of Loop Structures in C

Loop structure comparison guidelines:

  • for loop: Condition checked before execution; minimum executions = 0. Best used when the total number of iterations is known in advance.

  • while loop: Condition checked before execution; minimum executions = 0. Best used when iteration depends on a dynamic condition.

  • do...while loop: Condition checked after execution; minimum executions = 1. Best used when the operation must execute at least once (e.g., menu prompting).

Generating a multiplication table combining input and iteration:

#include <stdio.h>

int main() {
    int number;
    printf("Enter a number: ");
    scanf("%d", &number);

    for (int i = 1; i <= 12; i++) {
        printf("%d x %d = %d
", number, i, number * i);
    }

    return 0;
}

Combining loops with selection constructs allows processing specific data subsets. For example, printing all even numbers from 1 to 20:

for (int i = 1; i <= 20; i++) {
    if (i % 2 == 0) {
        printf("%d
", i);
    }
}

Counting matching events utilizes a counter variable incremented inside conditional blocks. Counting how many numbers between 1 and 100 are divisible by 5:

int count = 0;
for (int i = 1; i <= 100; i++) {
    if (i % 5 == 0) {
        count++;
    }
}
printf("Count = %d", count);

Loop practice outputs:

  1. Converting for (int i = 1; i <= 10; i++) { printf("%d ", i); } to a while loop requires initializing int i = 1; before while (i <= 10), and placing i++; inside the loop body.

  2. Tracing int i = 1; while (i <= 5) { printf("%d ", i); i++; } outputs 1 2 3 4 5.

Integrated Application and Practical Code Analysis

Combining variables, input, output, calculations, selection, and repetition forms complete procedural applications. The following integrated program performs student mark analysis across a dynamic class size:

#include <stdio.h>

int main() {
    int numberOfStudents;
    int mark;
    int total = 0;
    int passCount = 0;

    printf("Enter number of students: ");
    scanf("%d", &numberOfStudents);

    for (int i = 1; i <= numberOfStudents; i++) {
        printf("Enter mark for student %d: ", i);
        scanf("%d", &mark);
        total = total + mark;

        if (mark >= 50) {
            passCount++;
        }
    }

    float average = (float) total / numberOfStudents;

    printf("
Total marks = %d
", total);
    printf("Average mark = %.2f
", average);
    printf("Students who passed = %d
", passCount);

    return 0;
}
Mapping Concepts to Implementation in Integrated Example

Mapping fundamental programming concepts to their specific implementation constructs in the integrated application:

  • Variables: Implemented via mark, total, and passCount.

  • Input: Implemented via scanf().

  • Output: Implemented via printf().

  • Calculation: Implemented via total + mark and (float) total / numberOfStudents.

  • Selection: Implemented via if (mark >= 50).

  • Loop: Implemented via for (int i = 1; i <= numberOfStudents; i++).

  • Counter: Implemented via passCount++.

  • Type conversion: Implemented via explicit cast (float) total.

  • Sequence: Implemented via overall sequential statement execution.

End-of-Lecture Assessment and Exercises

Part A — Concepts:

  1. A variable in C is a named memory location used to store a value that can change during program execution.

  2. Four common C data types are int, float, double, and char.

  3. The operator = is the assignment operator used to store a value in a variable, whereas == is a relational operator used to compare two values for equality.

  4. The three main types of loops in C are for, while, and do...while.

Part B — Code Tracing:

  1. Trace and output for int x = 10; int y = 3;:

    • printf("%d ", x / y); performs integer division (10/310 / 3) and displays 3.

    • printf("%d ", x % y); calculates remainder (10%310 \% 3) and displays 1.

  2. Trace and output for int mark = 67;:

    • mark >= 70 is false.

    • mark >= 60 is true (67 >= 60), so the program displays B.

  3. Trace and output for loop summation:

    • sum initializes to 0.

    • Loop adds 1+2+3+4+5=151 + 2 + 3 + 4 + 5 = 15.

    • Output displays 15.

Part C — Programming Solutions:

Question 8: Program determining whether an integer is even or odd:

#include <stdio.h>

int main() {
    int num;
    printf("Enter an integer: ");
    scanf("%d", &num);

    if (num % 2 == 0) {
        printf("%d is even.
", num);
    } else {
        printf("%d is odd.
", num);
    }

    return 0;
}

Question 9: Program processing five student marks to display total, average, and passing count:

#include <stdio.h>

int main() {
    int mark;
    int total = 0;
    int passCount = 0;

    for (int i = 1; i <= 5; i++) {
        printf("Enter mark %d: ", i);
        scanf("%d", &mark);
        total += mark;

        if (mark >= 50) {
            passCount++;
        }
    }

    float average = (float) total / 5;

    printf("Total = %d
", total);
    printf("Average = %.2f
", average);
    printf("Pass Count = %d
", passCount);

    return 0;
}

Question 10: Program displaying numbers between 1 and 100 divisible by both 3 and 5:

#include <stdio.h>

int main() {
    for (int i = 1; i <= 100; i++) {
        if (i % 3 == 0 && i % 5 == 0) {
            printf("%d
", i);
        }
    }
    return 0;
}

Key Programming Rules, Principles, and Frameworks

Mastery of procedural C programming rests upon five core rules:

  1. Every variable must have an explicitly defined type (e.g., int age;, float average;, char grade;).

  2. Assignment is fundamentally distinct from equality (x = 10; stores a value, whereas x == 10 evaluates equality).

  3. Programs execute sequentially unless control structures redirect execution flow (Sequence -> Selection -> Repetition).

  4. Logical conditions evaluate to true or false to drive selection decisions (if (mark >= 50)).

  5. Loop constructs require four core elements: Start (initialization), Condition, Body, and Update. Always ask: "What changes every time the loop executes?" to avoid creating infinite loops.

Standard procedural C program architecture:

#include <stdio.h>

int main() {
    // 1. Declare variables
    // 2. Get input
    // 3. Perform calculations
    // 4. Make decisions
    // 5. Repeat operations where necessary
    // 6. Display results
    return 0;
}

Developing strong code tracing capabilities and mentally predicting program output prior to execution builds the mental execution model necessary for writing robust, error-free software independently.