C Programming Overview
0%
Full Course
#include <stdio.h> int main(){ printf("Hello!"); return 0; }
int *ptr = &var; *ptr = 42; printf("%d",*ptr);
struct Student{ char name[50]; int roll; float marks; };
malloc(sizeof(int)*n); calloc(n,sizeof(int)); realloc(ptr,newSize); free(ptr);
📚 Complete C Programming — All 40+ Topics with Commented Code
just say "Visca Barça" and star coding

Master
C Programming with
Pavel Ibrahim

Every topic from basics to advanced — with fully commented code examples, flowcharts, tables, and a 20-question quiz. Your ultimate C reference.

40+
Topics
80+
Code Examples
100%
Commented
20
Quiz Qs
🔰 Topic 1

Introduction to Programming

Programming is the art of giving step-by-step instructions to a computer to solve problems.

💻
What is Programming?
Bridging human logic and machine

A program is a set of instructions written in a language the computer understands. Computers only understand binary (0s and 1s), so languages bridge the gap. C is called a middle-level language.

Types of Languages Machine Lang → Assembly → C/C++ (Middle) → Python/Java (High). C combines readability with direct hardware access.
hello_world.c
/* =============================================
   Program : Hello, World!
   Purpose : Print text to screen — simplest C program
   How     : printf() outputs to stdout
   ============================================= */

#include <stdio.h>  /* Standard I/O header — gives us printf(), scanf()
                         Without this, printf won't be recognized */

/* main() — the ENTRY POINT of every C program
   Execution always starts here, not anywhere else
   'int' means it returns an integer to the OS */
int main() {

    /* printf() — print formatted text to console
       \n = newline character (moves cursor to next line) */
    printf("Hello, World!\n");

    /* return 0 — signals OS that program ran successfully
       Non-zero return values indicate errors */
    return 0;
}
Output: Hello, World!
🪜
Steps to Write a Program
From problem to working code
1
Understand the Problem
Read carefully — what input, what output?
2
Design Algorithm
Write step-by-step logic in plain English
3
Draw Flowchart
Visualize logic with standard symbols
4
Write Code in C
Translate algorithm to C syntax
5
Compile with GCC
gcc program.c -o output
6
Test & Debug
Run, verify output, fix any errors
LevelLanguageExample
MachineBinary01001010
LowAssemblyMOV AX, 5
MiddleC, C++int x = 5;
HighPythonx = 5
🧮
Basic Arithmetic Program
Simple calculations in C
arithmetic.c
/* =============================================
   Program : Basic Arithmetic Operations
   Purpose : Demonstrate all 5 arithmetic operators in C
   Input   : None (uses hardcoded values)
   Output  : Results of addition, subtraction, multiplication, division, modulus
   ============================================= */

#include <stdio.h>  /* Include standard input/output library
                         Provides printf() function for output */

int main() {  /* main() function - program entry point
                     int return type indicates program status to OS */

    /* Variable declarations with initialization
       int data type stores whole numbers (no decimals)
       Multiple variables can be declared in one line */
    int a = 10, b = 5;

    /* ARITHMETIC OPERATORS IN C:
       + (addition), - (subtraction), * (multiplication)
       / (division), % (modulus/remainder) */

    /* Addition operator: adds two numbers */
    printf("Addition: %d + %d = %d\n", a, b, a + b);

    /* Subtraction operator: subtracts second number from first */
    printf("Subtraction: %d - %d = %d\n", a, b, a - b);

    /* Multiplication operator: multiplies two numbers */
    printf("Multiplication: %d * %d = %d\n", a, b, a * b);

    /* Division operator: divides first number by second
       Integer division truncates decimal part (no rounding) */
    printf("Division: %d / %d = %d\n", a, b, a / b);

    /* Modulus operator: gives remainder after division
       Useful for checking even/odd, cycling through ranges */
    printf("Modulus: %d %% %d = %d\n", a, b, a % b);

    /* Return 0 indicates successful program execution */

int main() {  /* main() function - program entry point
                     int return type indicates program status to OS */

    /* Variable declarations with initialization
       int data type stores whole numbers (no decimals)
       Multiple variables can be declared in one line */
    int a = 10, b = 5;

    /* ARITHMETIC OPERATORS IN C:
       + (addition), - (subtraction), * (multiplication)
       / (division), % (modulus/remainder) */

    /* Addition operator: adds two numbers */
    printf("Addition: %d + %d = %d\n", a, b, a + b);

    /* Subtraction operator: subtracts second number from first */
    printf("Subtraction: %d - %d = %d\n", a, b, a - b);

    /* Multiplication operator: multiplies two numbers */
    printf("Multiplication: %d * %d = %d\n", a, b, a * b);

    /* Division operator: divides first number by second
       Integer division truncates decimal part (no rounding) */
    printf("Division: %d / %d = %d\n", a, b, a / b);

    /* Modulus operator: gives remainder after division
       Useful for checking even/odd, cycling through ranges */
    printf("Modulus: %d %% %d = %d\n", a, b, a % b);

    /* Return 0 indicates successful program execution */
    return 0;
}
Output: Addition: 10 + 5 = 15
Subtraction: 10 - 5 = 5
Multiplication: 10 * 5 = 50
Division: 10 / 5 = 2
Modulus: 10 % 5 = 0
🔄
Input and Output Example
Reading user input
input_output.c
/* =============================================
   Program : Input and Output Demonstration
   Purpose : Show how to read user input and display formatted output
   Input   : User's name (string), age (integer), height (float)
   Output  : Personalized greeting with user data
   ============================================= */

#include <stdio.h>  /* Include standard I/O library
                         Provides printf() for output and scanf() for input */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATIONS:
       Different data types for different kinds of data
       Variables declared but not initialized (will be set by user input) */

    int age;           /* Integer variable for whole numbers (age in years) */
    char name[50];      /* Character array for strings (up to 49 chars + null terminator) */
    float height;       /* Float variable for decimal numbers (height in meters) */

    /* INPUT OPERATIONS USING scanf():
       scanf() reads formatted input from keyboard (stdin)
       Format specifiers tell scanf what type of data to expect */

    /* Prompt user and read string input
       %s format reads until whitespace (space, tab, newline) */
    printf("Enter your name: ");
    scanf("%s", name);  /* Note: NO & needed for arrays (name is already an address) */

    /* Prompt user and read integer input
       %d format reads whole numbers, &age gives address of age variable */
    printf("Enter your age: ");
    scanf("%d", &age);  /* & (address-of operator) required for non-array variables */

    /* Prompt user and read float input
       %f format reads decimal numbers */
    printf("Enter your height in meters: ");
    scanf("%f", &height);

    /* OUTPUT OPERATIONS USING printf():
       printf() displays formatted text to screen (stdout)
       Format specifiers (%s, %d, %f) are replaced with variable values */

    printf("\nHello %s!\n", name);                    /* %s for strings */
    printf("You are %d years old.\n", age);           /* %d for integers */
    printf("Your height is %.2f meters.\n", height);  /* %.2f for float with 2 decimal places */

    /* Program completed successfully */
    return 0;
}
Sample Input: John
25
1.75
Sample Output: Hello John!
You are 25 years old.
Your height is 1.75 meters.
🔰 Topic 2

Algorithm

A finite, well-defined, step-by-step procedure to solve a problem. Every program starts as an algorithm.

📋
Properties & Examples
Input, Output, Finite, Definite, Effective
5 Properties (IOFED): Input (0 or more) · Output (at least 1) · Finiteness (must terminate) · Effectiveness (feasible steps) · Definiteness (clear & unambiguous)
sum_two_numbers.c
/* =============================================
   Program : Sum of Two Numbers Algorithm
   Purpose : Demonstrate basic algorithm implementation
   Algorithm Steps:
   1. START
   2. Read A and B (Input)
   3. SUM = A + B (Process)
   4. Print SUM (Output)
   5. STOP (Finite)
   ============================================= */

#include <stdio.h>  /* Include standard I/O library for printf/scanf */

int main() {  /* Program entry point - execution begins here */

    /* VARIABLE DECLARATION:
       Reserve memory space for three integer variables
       int data type stores whole numbers (-2^31 to +2^31-1) */
    int a, b, sum;

    /* INPUT PHASE:
       Prompt user for input and read two integers
       scanf uses & (address-of operator) to store values in variables */
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);

    /* PROCESSING PHASE:
       Calculate sum using arithmetic addition operator (+)
       Result stored in sum variable */
    sum = a + b;

    /* OUTPUT PHASE:
       Display result using printf with format specifier %d for integers */
    printf("Sum = %d\n", sum);

    /* PROGRAM TERMINATION:
       Return 0 indicates successful execution to operating system */
    return 0;
}
largest_of_three.c
/* =============================================
   Program : Find Largest of Three Numbers
   Purpose : Demonstrate conditional logic (if-else-if)
   Algorithm:
   1. Read three numbers A, B, C
   2. Compare A with B and C
   3. If A > B AND A > C, A is largest
   4. Else if B > C, B is largest
   5. Else C is largest
   ============================================= */

#include <stdio.h>  /* Standard I/O library for input/output functions */

int main() {  /* Main function - program execution starts here */

    /* VARIABLE DECLARATION:
       Three integer variables to store user input */
    int a, b, c;

    /* INPUT: Read three integers from user */
    printf("Enter 3 numbers: ");
    scanf("%d %d %d", &a, &b, &c);

    /* CONDITIONAL LOGIC - DECISION MAKING:
       Use logical AND (&&) operator to check multiple conditions
       if-else-if ladder executes only the first true condition */

    /* CONDITION 1: Check if A is largest
       A > B AND A > C means A is greater than both others */
    if(a > b && a > c)
        printf("Largest: %d\n", a);

    /* CONDITION 2: If A is not largest, check if B > C
       Since A is not largest, we only need to compare B and C */
    else if(b > c)
        printf("Largest: %d\n", b);

    /* CONDITION 3: If neither A nor B is largest, C must be largest
       This handles the case where C >= B and A is not largest */
    else
        printf("Largest: %d\n", c);

    /* Program termination with success status */
    return 0;
}
🔢
More Algorithm Examples
Factorial, Simple Interest, Prime Check
factorial.c
/* =============================================
   Program : Factorial Calculation
   Purpose : Calculate n! (n factorial) using iterative approach
   Formula : n! = 1 × 2 × 3 × ... × n
   Examples: 5! = 120, 3! = 6, 0! = 1
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf/scanf */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       n: user input (factorial to calculate)
       i: loop counter variable
       fact: stores factorial result (long long for large values)
       Initialized to 1 because factorial starts with multiplication by 1 */
    int n, i;
    long long fact = 1;  /* long long can hold up to 20! (2.43×10^18) */

    /* INPUT: Get the number to calculate factorial of */
    printf("Enter n: ");
    scanf("%d", &n);

    /* ITERATIVE FACTORIAL CALCULATION:
       for loop structure: initialization; condition; increment
       i starts at 1, continues while i <= n, increments i each iteration
       Example: 5! = 1×2×3×4×5 = 120 */
    for(i = 1; i <= n; i++) {
        fact *= i;  /* Compound assignment: fact = fact * i */
    }

    /* OUTPUT: Display result
       %d for int (n), %lld for long long (fact) */
    printf("%d! = %lld\n", n, fact);

    /* Program completed successfully */
    return 0;
}
simple_interest.c
/* =============================================
   Program : Simple Interest Calculator
   Purpose : Calculate simple interest using the formula
   Formula  : SI = (Principal × Rate × Time) / 100
   Variables: P = Principal amount, R = Rate %, T = Time in years
   Example  : P=1000, R=5, T=2 → SI = (1000×5×2)/100 = 100
   ============================================= */

#include <stdio.h>  /* Standard I/O library for input/output operations */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       All variables are float type to handle decimal values
       p: principal amount (initial money)
       r: rate of interest (percentage)
       t: time period (years)
       si: simple interest (result) */
    float p, r, t, si;  /* float provides 6-7 decimal digits precision */

    /* INPUT: Read principal, rate, and time from user */
    printf("Principal Rate Time: ");
    scanf("%f %f %f", &p, &r, &t);

    /* CALCULATION: Apply Simple Interest Formula
       SI = (P × R × T) / 100
       Parentheses ensure correct order of operations */
    si = (p * r * t) / 100;

    /* OUTPUT: Display result with 2 decimal places
       %.2f format specifier shows exactly 2 decimal digits */
    printf("Simple Interest = %.2f\n", si);

    /* Program completed successfully */
    return 0;
}
prime_check.c
/* =============================================
   Program : Prime Number Checker
   Purpose : Determine if a number is prime or composite
   Definition: Prime number has exactly 2 factors (1 and itself)
   Examples  : 2, 3, 5, 7, 11 are prime; 4, 6, 8, 9 are not
   Algorithm : Check divisibility from 2 to sqrt(n)
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf/scanf */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       n: number to check for primality
       i: loop counter for divisibility testing
       isPrime: flag variable (1=true, 0=false) - assume prime initially */
    int n, i, isPrime = 1;  /* Flag initialized to 1 (true/assume prime) */

    /* INPUT: Get number to test from user */
    printf("Enter number: ");
    scanf("%d", &n);

    /* SPECIAL CASE HANDLING:
       Numbers less than 2 are not prime by definition
       0 and 1 have only 1 factor (themselves) */
    if(n < 2)
        isPrime = 0;  /* Set flag to false (not prime) */

    /* PRIME CHECKING ALGORITHM:
       Only check divisibility up to sqrt(n) for efficiency
       If n has a factor > sqrt(n), it must also have one < sqrt(n)
       Start from 2 (smallest prime) up to sqrt(n) */
    for(i = 2; i * i <= n; i++) {
        /* If n is divisible by i (remainder is 0), then n is not prime */
        if(n % i == 0) {  /* Modulus operator gives remainder */
            isPrime = 0;  /* Found a factor, so not prime */
            break;  /* No need to check further factors */
        }
    }

    /* OUTPUT: Display result using conditional (ternary) operator
       condition ? value_if_true : value_if_false */
    printf("%d is %s\n", n, isPrime ? "Prime" : "Not Prime");

    /* Program completed successfully */
    return 0;
}
🔢
More Algorithm Examples
Fibonacci, Armstrong Number, Palindrome
fibonacci.c
/* =============================================
   Program : Fibonacci Series Generator
   Purpose : Generate first n Fibonacci numbers
   Definition: Each number is sum of two preceding ones
   Sequence  : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
   Formula   : F(n) = F(n-1) + F(n-2), where F(0)=0, F(1)=1
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf/scanf */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       n: how many Fibonacci numbers to generate
       a, b, c: Fibonacci sequence variables
       a=0 (first number), b=1 (second number), c=next number */
    int n, a = 0, b = 1, c;

    /* INPUT: Get count of Fibonacci numbers to display */
    printf("Enter n: ");
    scanf("%d", &n);

    /* OUTPUT HEADER: Display series label */
    printf("Fibonacci: ");

    /* FIBONACCI GENERATION LOOP:
       for loop runs n times to generate n Fibonacci numbers
       int i=1: start from 1st iteration
       i<=n: continue while i is less than or equal to n
       i++: increment i by 1 each iteration */
    for(int i = 1; i <= n; i++) {
        /* Print current Fibonacci number */
        printf("%d ", a);

        /* Calculate next Fibonacci number: sum of previous two */
        c = a + b;  /* Next = current + previous */

        /* Shift values for next iteration:
           Current becomes previous, next becomes current */
        a = b;    /* Move b to a (previous becomes current) */
        b = c;    /* Move c to b (next becomes current) */
    }

    /* OUTPUT: New line after series */
    printf("\n");

    /* Program completed successfully */
    return 0;
}
armstrong.c
/* =============================================
   Program : Armstrong Number Checker
   Purpose : Check if a number equals sum of its digits raised to power of digit count
   Definition: Armstrong number = sum of each digit^number_of_digits
   Examples  : 153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153 ✓
               9474 = 9^4 + 4^4 + 7^4 + 4^4 = 6561 + 256 + 2401 + 256 = 9474 ✓
   ============================================= */

#include <stdio.h>  /* Standard I/O library */
#include <math.h>   /* Math library for pow() function */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       n: original number to check
       temp: temporary copy for processing (preserves original n)
       sum: accumulates sum of digits^digits (starts at 0)
       digits: count of digits in the number */
    int n, temp, sum = 0, digits = 0;

    /* INPUT: Get number to check from user */
    printf("Enter number: ");
    scanf("%d", &n);

    /* PRESERVE ORIGINAL: Make a copy for digit counting */
    temp = n;

    /* PHASE 1: COUNT DIGITS
       Divide by 10 repeatedly until number becomes 0
       Each division removes rightmost digit */
    while(temp != 0) {
        digits++;        /* Increment digit counter */
        temp /= 10;  /* Remove rightmost digit */
    }

    /* RESET TEMP: Restore original number for digit processing */
    temp = n;

    /* PHASE 2: CALCULATE SUM OF DIGITS^DIGITS
       Extract each digit and raise to power of total digits */
    while(temp != 0) {
        int digit = temp % 10;  /* Extract rightmost digit */
        sum += pow(digit, digits);  /* Add digit^digits to sum */
        temp /= 10;           /* Remove processed digit */
    }

    /* PHASE 3: CHECK AND OUTPUT RESULT
       Compare sum with original number */
    if(sum == n)
        printf("%d is Armstrong\n", n);
    else
        printf("%d is not Armstrong\n", n);

    /* Program completed successfully */
    return 0;
}
palindrome.c
/* =============================================
   Program : Palindrome Number Checker
   Purpose : Check if a number reads the same forwards and backwards
   Definition: Palindrome number remains same when digits reversed
   Examples  : 121 (121 reversed is 121) ✓
               12321 (12321 reversed is 12321) ✓
               123 (123 reversed is 321) ✗
   Algorithm : Reverse the number and compare with original
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf/scanf */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       n: original number to check
       rev: reversed number (starts at 0, built digit by digit)
       temp: temporary copy for processing (preserves original n) */
    int n, rev = 0, temp;

    /* INPUT: Get number to check from user */
    printf("Enter number: ");
    scanf("%d", &n);

    /* PRESERVE ORIGINAL: Make a copy for reversal process */
    temp = n;

    /* PALINDROME CHECK ALGORITHM: REVERSE THE NUMBER
       Process each digit from right to left
       Build reversed number by shifting digits left and adding new digit */
    while(temp != 0) {
        /* Extract rightmost digit and shift reversed number left */
        rev = rev * 10 + temp % 10;

        /* Mathematical breakdown for 123:
           First iteration:  rev = 0*10 + 123%10 = 0 + 3 = 3, temp=12
           Second iteration: rev = 3*10 + 12%10 = 30 + 2 = 32, temp=1
           Third iteration:  rev = 32*10 + 1%10 = 320 + 1 = 321, temp=0 */

        temp /= 10;  /* Remove rightmost digit from temp */
    }

    /* COMPARISON AND OUTPUT:
       If reversed number equals original, it's a palindrome */
    if(rev == n)
        printf("%d is Palindrome\n", n);
    else
        printf("%d is not Palindrome\n", n);

    /* Program completed successfully */
    return 0;
}
🔰 Topic 3

Flowchart

A pictorial representation of an algorithm using standard symbols connected by arrows showing the flow of logic.

📊
Standard Flowchart Symbols
ANSI/ISO standard shapes
SymbolShapeUsed For
TerminalOval / Rounded RectSTART and STOP points
ProcessRectangleCalculation, assignment
DecisionDiamondYes/No condition
I/OParallelogramInput (read) and Output (print)
Flow LineArrow →Direction of execution
ConnectorCircleConnect parts of flowchart
Sub-routineDouble-sided rectFunction call
Rules: Exactly one START and one STOP. Decision diamonds always have YES and NO exits. All paths must eventually reach STOP.
START
Read N
N % 2 == 0?
YES ↓
Print "Even"
NO ↓
Print "Odd"
STOP
💻
Flowchart → C Code
Even/Odd and Loop examples
even_odd.c
#include <stdio.h>
int main() {
    int n;
    printf("Enter a number: ");
    scanf("%d", &n);

    /* % is the modulo (remainder) operator
       10 % 2 = 0  (even), 7 % 2 = 1 (odd) */
    if(n % 2 == 0)
        printf("%d is Even\n", n);
    else
        printf("%d is Odd\n", n);
    return 0;
}
print_1_to_n.c (Loop flowchart)
#include <stdio.h>
int main() {
    int n, i;
    printf("Enter N: "); scanf("%d",&n);

    /* Loop flowchart → for loop in C
       Init: i=1, Condition: i<=n, Update: i++
       Body: print i */
    for(i=1; i<=n; i++) {
        printf("%d ", i);  /* prints 1 2 3 ... N */
    }
    printf("\n");
    return 0;
}
🔄
More Flowchart Examples
Sum of N numbers, Maximum of three
sum_n_numbers.c
#include <stdio.h>
int main() {
    int n, i, sum=0;
    printf("Enter N: "); scanf("%d",&n);

    /* Loop to sum 1 to N */
    for(i=1; i<=n; i++) {
        sum += i;
    }
    printf("Sum of 1 to %d = %d\n", n, sum);
    return 0;
}
max_of_three.c
#include <stdio.h>
int main() {
    int a, b, c, max;
    printf("Enter 3 numbers: ");
    scanf("%d %d %d", &a, &b, &c);

    /* Find maximum using nested if-else */
    if(a > b) {
        if(a > c)
            max = a;
        else
            max = c;
    } else {
        if(b > c)
            max = b;
        else
            max = c;
    }
    printf("Maximum = %d\n", max);
    return 0;
}
grade_calculation.c
#include <stdio.h>
int main() {
    int marks;
    printf("Enter marks (0-100): ");
    scanf("%d", &marks);

    /* Multiple decision points */
    if(marks >= 90)
        printf("Grade: A\n");
    else if(marks >= 80)
        printf("Grade: B\n");
    else if(marks >= 70)
        printf("Grade: C\n");
    else if(marks >= 60)
        printf("Grade: D\n");
    else
        printf("Grade: F\n");
    return 0;
}
🔰 Topic 4

Pseudocode

An informal, English-like description of an algorithm. No strict syntax rules — just logical clarity to plan before coding.

📝
Pseudocode Keywords
Common conventions
START / ENDINPUT / READOUTPUT / PRINTIF / ELSE / ENDIFWHILE / ENDWHILEFOR / ENDFORSET / LETCALL functionRETURN value
Pseudocode: Bubble Sort
START
  INPUT array A of n numbers
  FOR i = 0 to n-2
    FOR j = 0 to n-i-2
      IF A[j] > A[j+1] THEN
        SWAP A[j] and A[j+1]
      ENDIF
    ENDFOR
  ENDFOR
  OUTPUT sorted array A
END
🔄
Pseudocode → C Implementation
Converting to real code
bubble_sort.c
#include <stdio.h>
int main() {
    int a[] = {64,34,25,12,22};  /* array to sort */
    int n = 5, i, j, temp;

    /* Outer loop: each pass moves the next largest to end
       We need n-1 passes for n elements */
    for(i=0; i<n-1; i++) {

        /* Inner loop: compare adjacent elements
           Already-sorted portion at end shrinks each pass */
        for(j=0; j<n-i-1; j++) {
            if(a[j] > a[j+1]) {
                /* Swap: use temp variable to hold one value */
                temp    = a[j];
                a[j]   = a[j+1];
                a[j+1] = temp;
            }
        }
    }
    /* Print sorted array */
    for(i=0; i<n; i++) printf("%d ", a[i]);
    return 0;
}
🔢
More Pseudocode Examples
Linear Search, Binary Search
Pseudocode: Linear Search
START
  INPUT array A of n elements
  INPUT key to search
  SET found = FALSE
  SET position = -1
  FOR i = 0 to n-1
    IF A[i] == key THEN
      SET found = TRUE
      SET position = i
      BREAK
    ENDIF
  ENDFOR
  IF found THEN
    OUTPUT "Found at position " + position
  ELSE
    OUTPUT "Not found"
  ENDIF
END
linear_search.c
#include <stdio.h>
int main() {
    int a[] = {10,20,30,40,50};
    int n = 5, key, i, found = 0, pos = -1;

    printf("Enter number to search: ");
    scanf("%d", &key);

    /* Linear search: check each element */
    for(i=0; i<n; i++) {
        if(a[i] == key) {
            found = 1;
            pos = i;
            break;  /* stop searching */
        }
    }

    if(found)
        printf("Found at position %d\n", pos);
    else
        printf("Not found\n");
    return 0;
}
Pseudocode: Binary Search
START
  INPUT sorted array A of n elements
  INPUT key to search
  SET low = 0, high = n-1
  SET found = FALSE
  WHILE low <= high
    SET mid = (low + high) / 2
    IF A[mid] == key THEN
      SET found = TRUE
      SET position = mid
      BREAK
    ELSE IF A[mid] < key THEN
      SET low = mid + 1
    ELSE
      SET high = mid - 1
    ENDIF
  ENDWHILE
  IF found THEN
    OUTPUT "Found at position " + position
  ELSE
    OUTPUT "Not found"
  ENDIF
END
binary_search.c
#include <stdio.h>
int main() {
    int a[] = {10,20,30,40,50};  /* must be sorted */
    int n = 5, key, low=0, high=n-1, mid, found=0, pos=-1;

    printf("Enter number to search: ");
    scanf("%d", &key);

    /* Binary search: divide and conquer */
    while(low <= high) {
        mid = (low + high) / 2;

        if(a[mid] == key) {
            found = 1;
            pos = mid;
            break;
        } else if(a[mid] < key) {
            low = mid + 1;  /* search right half */
        } else {
            high = mid - 1; /* search left half */
        }
    }

    if(found)
        printf("Found at position %d\n", pos);
    else
        printf("Not found\n");
    return 0;
}
🔰 Topic 5

History of C Language

From BCPL in 1967 to C17 today — the fascinating evolution of the world's most influential programming language.

Evolution Timeline
1960 to present
1960 — ALGOL
ALGOrithmic Language introduced structured programming. Foundation for all modern languages.
1967 — BCPL
Martin Richards (Cambridge) created Basic Combined Programming Language. No data types — everything a machine word.
1969 — B Language
Ken Thompson at Bell Labs created B based on BCPL. Used to write early Unix utilities on PDP-7.
1972 — C is Born! 🎉
Dennis Ritchie created C at Bell Laboratories, Murray Hill, NJ. Designed to rewrite the Unix OS in a portable language.
1973 — Unix Rewritten in C
The Unix kernel was rewritten entirely in C — proving C's power for systems programming. A historic milestone.
1978 — K&R Book
Brian Kernighan & Dennis Ritchie publish "The C Programming Language." Still considered the definitive C reference.
1989 — ANSI C / C89
First official standardization by ANSI. Added function prototypes, void type, standardized libraries.
1999 — C99
Added: // comments, inline functions, variable-length arrays, long long int, <stdbool.h>, designated initializers.
2011 — C11
Multi-threading (_Thread_local), _Generic, anonymous structs/unions, better Unicode (<uchar.h>).
2018 — C17 (Current Standard)
Bug fixes and defect reports from C11. No major new features but cleaner, more correct standard.
👨‍💻
Dennis Ritchie — Father of C
Sep 9, 1941 – Oct 12, 2011
Dennis MacAlistair Ritchie worked at Bell Labs 1967–2007. Created C and co-developed Unix with Ken Thompson. His work is the invisible foundation of every modern computer system.
🏆 Awards: Turing Award (1983) with Ken Thompson · National Medal of Technology (1998) · Japan Prize (2011)
"C is quirky, flawed, and an enormous success." — Dennis Ritchie
c_influenced_languages.c
/* Languages directly influenced by C:
   
   C++     (1983) — Bjarne Stroustrup — adds OOP to C
   Java    (1995) — James Gosling     — "write once, run anywhere"
   C#      (2000) — Anders Hejlsberg — Microsoft .NET
   PHP     (1994) — Rasmus Lerdorf   — web scripting
   JavaScript(95) — Brendan Eich     — web browsers
   Go      (2009) — Google           — systems programming
   Rust    (2010) — Mozilla          — memory-safe systems lang
   Python  ——————— uses C-style syntax and concepts
   
   C is truly the "Mother of All Languages" !
   
   Even your OS kernel is written mostly in C:
   Linux kernel   → 97% C
   Windows kernel → C and C++
   macOS kernel   → C and Objective-C    */
🔰 Topic 6

Features of C Language

Why C remains the backbone of systems programming 50+ years after its creation.

Fast & Efficient
Compiles directly to machine code — minimal overhead, maximum speed
🔧
Low-Level Access
Direct memory manipulation via pointers — hardware-level control
🌍
Portable Code
ANSI C programs compile and run on virtually any platform
🏗️
Structured
Functions, loops, conditions for clean, maintainable code
📚
Rich Libraries
stdio, math, string, stdlib, time, ctype and more
🎯
Modular
Break programs into functions and multiple source files
🔁
Extensible
Add features via custom and third-party libraries
🧮
Middle-Level
Combines high-level readability with low-level hardware access
🔰 Topic 7

Structure of a C Program

Every C program follows a standard structure with up to 6 sections — from documentation to sub-programs.

🏗️
6 Sections Explained
Standard program layout
1. Documentation
/* Author, Date, Description — comments only */
2. Preprocessor
#include <stdio.h> #include <math.h>
3. Definitions
#define PI 3.14159 #define MAX 100
4. Global Decl.
int globalVar; void myFunc(); /* prototypes */
5. main() Func.
int main() { /* body */ return 0; }
6. Sub-programs
User-defined functions defined below main()
💻
Complete Structure Example
All 6 sections annotated
full_structure.c
/* ====== SECTION 1: Documentation ======
   Program  : Area Calculator
   Author   : Your Name
   Date     : 2024
   Purpose  : Calculate area of circle & rectangle
   ======================================= */

/* ====== SECTION 2: Preprocessor / Link ====== */
#include <stdio.h>    /* Standard I/O: printf, scanf */
#include <math.h>     /* Math functions: sqrt, pow, M_PI */

/* ====== SECTION 3: Macro Definitions ====== */
#define PI  3.14159f  /* Constant for pi value */
#define MAX 100      /* Maximum array size */

/* ====== SECTION 4: Global Declarations ====== */
int programCount = 0;  /* Global: accessible from ALL functions */

/* Function PROTOTYPE (declaration) — tells compiler
   this function will be defined later below main() */
float circleArea(float r);
float rectArea(float l, float w);

/* ====== SECTION 5: main() Function ====== */
int main() {
    float r, l, w;  /* LOCAL variables — only visible in main() */

    printf("Enter circle radius: ");
    scanf("%f", &r);
    printf("Circle Area = %.2f\n", circleArea(r));

    printf("Enter rect L W: ");
    scanf("%f %f", &l, &w);
    printf("Rect Area = %.2f\n", rectArea(l,w));

    return 0;  /* 0 = success, 1 = error */
}

/* ====== SECTION 6: Sub-programs ====== */
/* Formula: π × r² */
float circleArea(float r) {
    return PI * r * r;
}

/* Formula: length × width */
float rectArea(float l, float w) {
    return l * w;
}
🔰 Topic 8

Compilation Process

How C source code transforms into a runnable executable — 4 internal stages.

📝
Source Code
program.c
🔍
Preprocessor
program.i
⚙️
Compiler
program.s
🔧
Assembler
program.o
🔗
Linker
program.exe
🚀
Run
In RAM
⚙️
Stage Details & GCC Commands
Each compilation stage explained
StageInput→OutputDoes What
Preprocessor.c → .iExpands #include, #define, removes comments
Compiler.i → .sTranslates to Assembly, checks syntax
Assembler.s → .oConverts Assembly to binary machine code
Linker.o → .exeLinks object files + library files together
gcc_commands.sh
# FULL compilation in one step (most common usage)
gcc program.c -o program

# Step-by-step compilation:
gcc -E program.c -o program.i   # Step 1: Preprocess only
gcc -S program.i -o program.s   # Step 2: Compile to Assembly
gcc -c program.s -o program.o   # Step 3: Assemble to object
gcc program.o   -o program      # Step 4: Link to executable

# Recommended beginner command (-Wall shows all warnings)
gcc -Wall -g program.c -o program

# With math library (needed for sqrt, pow, sin, etc.)
gcc program.c -o program -lm

# Using C11 standard
gcc -std=c11 -Wall program.c -o program

# Run the compiled program
./program      # Linux/macOS
program.exe    # Windows
Types of Errors
Know when each error occurs
Error TypeWhen?Example
Syntax ErrorCompile timeMissing ; or { }
Semantic ErrorCompile timeint + "hello"
Linker ErrorLink timeUndefined function
Runtime ErrorDuring executionDivision by zero
Logical ErrorWrong outputWrong formula used
error_examples.c
/* SYNTAX ERROR — missing semicolon */
int main() {
    int x = 5   /* ← ERROR: missing ; here! */
    return 0;
}

/* RUNTIME ERROR — divide by zero */
int main() {
    int a = 10 / 0;  /* ← program CRASHES at runtime */
    return 0;
}

/* LOGICAL ERROR — wrong formula (compiles fine!) */
#define PI 3.14159
float area(float r) {
    return 2 * PI * r;  /* ← should be PI*r*r */
}
🔤 Fundamentals

Character Set & Tokens

🔡
Valid Characters in C
What characters can you type?
CategoryCharacters
UppercaseA B C … Z (26 letters)
Lowercasea b c … z (26 letters)
Digits0 1 2 3 4 5 6 7 8 9
Special Symbols! @ # $ % ^ & * ( ) _ - + = [ ] { } | ; : ' " , . < > ? / ~ \
WhitespaceSpace, Tab(\t), Newline(\n), CR(\r)
C is case-sensitive! int, INT, and Int are three DIFFERENT identifiers. Keywords are always lowercase.
🔖
Tokens — Smallest Units
6 types of tokens in C
Token TypeExamples
Keywordsint, if, for, while, return, void
Identifiersmain, myVar, sum, calculateArea
Constants42, 3.14f, 'A', "hello"
Operators+ - * / % == != && || << >>
Punctuators; , { } ( ) [ ] .
String Literals"Hello World"
tokens_example.c
/* In this line: int sum = a + b;
   int   → keyword (token type 1)
   sum   → identifier (token type 2)
   =     → operator (token type 4)
   a     → identifier (token type 2)
   +     → operator (token type 4)
   b     → identifier (token type 2)
   ;     → punctuator (token type 5)
   Total: 7 tokens in one statement! */

int sum = a + b;
🔤 Fundamentals

Keywords & Identifiers

🗝️
32 Reserved Keywords (C89)
Cannot be used as variable names
autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile
C99 added: inline, restrict, _Bool, _Complex C11 added: _Thread_local, _Atomic, _Generic
🏷️
Identifier Naming Rules
Rules for valid names in C
Start with letter or underscore _
myVar, _count, sum1 — all valid
Can contain letters, digits 0-9, _
student_name, num2, _private — valid
Cannot start with a digit
1num, 2sum — INVALID
Cannot use keywords as names
int, for as variable names — INVALID
No spaces or special chars (except _)
my var, sum@, a-b — INVALID
Convention: camelCase for variables (totalMarks), UPPER_CASE for macros (MAX_SIZE), PascalCase for structs (StudentRecord)
🔤 Fundamentals

Constants & Variables

🔒
Constants — Fixed Values
Values that never change during execution
constants.c
#include <stdio.h>

/* METHOD 1: #define MACRO — no memory allocated
   Preprocessor replaces PI with 3.14159 everywhere
   before compilation even begins */
#define PI       3.14159
#define MAX_SIZE 100
#define GREETING "Hello"

int main() {

    /* METHOD 2: const keyword — type-safe, has memory
       Compiler ENFORCES that you can't change the value */
    const float  gravity  = 9.81f;  /* m/s² */
    const int    days     = 7;
    const char   grade    = 'A';

    /* Different numeric constant notations */
    int decimal = 255;    /* normal base-10 integer */
    int octal   = 0377;   /* prefix 0 = octal: 0377 = 255 */
    int hex     = 0xFF;   /* prefix 0x = hex: 0xFF = 255 */
    int binary  = 0b11111111; /* C99: 0b = binary = 255 */

    printf("All equal: %d %d %d\n", decimal, octal, hex);

    /* Character constant — stored as ASCII integer value
       'A' = 65, 'a' = 97, '0' = 48 */
    printf("Grade: %c = ASCII %d\n", grade, grade);

    /* Float constant suffixes:
       3.14    = double by default
       3.14f   = float (less precision, less memory)
       3.14L   = long double (more precision) */
    printf("PI macro: %f\n", PI);     /* 3.141590 */
    printf("Gravity: %.2f\n", gravity); /* 9.81 */

    return 0;
}
📦
Variables — Named Memory Locations
Containers for data that can change
Syntax: data_type variable_name = initial_value;
Variables must be declared before use. Local variables have garbage values if not initialized!
variables.c
#include <stdio.h>

/* GLOBAL variable — declared OUTSIDE all functions
   Lives for the entire program duration
   Initialized to 0 automatically by the compiler
   Accessible from any function in any file */
int globalCount = 0;
float globalRate = 5.5;

int main() {

    /* LOCAL variables — declared INSIDE function/block
       Only accessible within this { } block
       NOT automatically initialized — contain random garbage! */
    int    age    = 20;         /* integer */
    float  height = 5.9f;       /* single-precision float */
    double pi     = 3.14159265; /* double precision */
    char   grade  = 'A';         /* single character */
    char   name[] = "Alice";     /* string = char array */

    /* Declare multiple variables of same type at once */
    int x = 1, y = 2, z;  /* z has garbage value! */
    z = x + y;              /* now z has a valid value */

    printf("Age: %d\n",      age);
    printf("Height: %.1f\n", height);
    printf("Pi: %lf\n",     pi);
    printf("Name: %s\n",    name);
    printf("x+y = %d\n",   z);

    return 0;
}
🔤 Fundamentals

Data Types & Type Modifiers

📐
All Data Types & Sizes
Primary + Modified types
TypeSizeRangeFormat
char1 byte-128 to 127%c
unsigned char1 byte0 to 255%c
short int2 bytes-32,768 to 32,767%hd
int4 bytes-2.1B to 2.1B%d
unsigned int4 bytes0 to 4.2B%u
long int4/8 bytesVery large range%ld
long long int8 bytes±9.2 × 10¹⁸%lld
float4 bytes3.4E±38 (6 digits)%f
double8 bytes1.7E±308 (15 digits)%lf
long double10–16 bytes3.4E±4932 (18 digits)%Lf
void0 bytesNo value
sizeof_demo.c
#include <stdio.h>
int main() {
    /* sizeof() — built-in operator that returns
       the SIZE of a type or variable in bytes */
    printf("char:        %zu bytes\n", sizeof(char));
    printf("int:         %zu bytes\n", sizeof(int));
    printf("float:       %zu bytes\n", sizeof(float));
    printf("double:      %zu bytes\n", sizeof(double));
    printf("long long:   %zu bytes\n", sizeof(long long));
    printf("long double: %zu bytes\n", sizeof(long double));

    /* sizeof also works on variables */
    int arr[10];
    printf("arr[10] size: %zu bytes\n", sizeof(arr));  /* 40 */
    printf("elements: %zu\n", sizeof(arr)/sizeof(arr[0])); /* 10 */
    return 0;
}
🔄
Type Casting
Converting between data types
Implicit: compiler auto-converts (lower→higher type, safe)
Explicit: programmer forces conversion using (type) — may lose data
type_casting.c
#include <stdio.h>
int main() {

    /* IMPLICIT CASTING — automatic (int promoted to float) */
    int   i = 5;
    float f = i;   /* int 5 auto-converts to float 5.0 */
    printf("Implicit int→float: %f\n", f);  /* 5.000000 */

    /* PROBLEM: int / int = int (fractional part LOST!)
       7 / 2 = 3, NOT 3.5 */
    printf("Wrong:   %d\n", 7/2);            /* 3 !! */

    /* EXPLICIT CASTING: (float) forces conversion
       Now 7 becomes 7.0 before dividing */
    printf("Correct: %.2f\n", (float)7/2);   /* 3.50 */

    /* char to int — reveals ASCII value */
    char ch = 'A';
    printf("ASCII of 'A' = %d\n", (int)ch);   /* 65 */

    /* double → int truncates (does NOT round!) */
    double d = 9.999;
    printf("Truncated: %d\n", (int)d);         /* 9, not 10! */

    /* Promotion hierarchy (low → high = safe):
       char → short → int → long → float → double → long double */
    char  c = 10;
    short s = 200;
    int   result = c + s;  /* both promoted to int automatically */
    printf("Result: %d\n", result);  /* 210 */

    return 0;
}
📥 Input / Output

printf() & scanf()

📤
printf() — Formatted Output
Print any data type to the screen
printf_complete.c
/* =============================================
   Program : Complete printf() Format Specifiers Guide
   Purpose : Demonstrate all major printf() formatting options
   Input   : None (uses hardcoded values)
   Output  : Various formatted outputs showing different specifiers
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() function */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATIONS:
       Different data types to demonstrate various format specifiers */
    int   age  = 21;         /* Integer variable */
    float gpa  = 3.857f;     /* Float variable (f suffix for float literal) */
    char  init = 'J';        /* Single character */
    char  name[] = "Alice";  /* Character array (string) */

    /* BASIC FORMAT SPECIFIERS:
       %d = decimal integer, %f = float, %c = character, %s = string */

    printf("Integer:  %d\n",  age);    /* %d: prints integer as decimal */
    printf("Float:    %f\n",  gpa);    /* %f: prints float with 6 decimal places */
    printf("2 decimals: %.2f\n", gpa); /* %.2f: float with exactly 2 decimal places */
    printf("Char:     %c\n",  init);   /* %c: prints single character */
    printf("String:   %s\n",  name);   /* %s: prints null-terminated string */

    /* MULTIPLE VALUES IN ONE PRINTF:
       Arguments must match format specifiers in exact order */
    printf("%s is %d years old, GPA: %.2f\n", name, age, gpa);

    /* WIDTH AND ALIGNMENT FORMATTING:
       Field width controls minimum characters printed
       Default is right-aligned, - makes left-aligned */
    printf("|%10d|\n",  42);   /* %10d: right-align in 10-char field */
    printf("|%-10d|\n", 42);   /* %-10d: left-align in 10-char field */
    printf("|%010d|\n", 42);   /* %010d: pad with zeros on left */
    printf("|%+d|\n",   42);   /* %+d: always show + sign for positive */

    /* DIFFERENT NUMBER BASES:
       Same number displayed in different bases */
    printf("Decimal: %d\n", 255);   /* %d: base 10 (default) */
    printf("Octal:   %o\n", 255);   /* %o: base 8 (octal) */
    printf("Hex:     %x\n", 255);   /* %x: base 16 (hex lowercase) */
    printf("Hex-UP:  %X\n", 255);   /* %X: base 16 (hex uppercase) */

    /* SCIENTIFIC NOTATION:
       %e displays float in scientific notation */
    printf("Scientific: %e\n", 3456.789);  /* %e: exponential notation */

    /* Program completed successfully */
    return 0;
}
📥
scanf() & Format Specifiers
Read keyboard input into variables
SpecifierTypeUsage
%dintscanf("%d", &n)
%iint (auto-detects base)scanf("%i", &n)
%ffloatscanf("%f", &x)
%lfdoublescanf("%lf", &d)
%Lflong doublescanf("%Lf", &ld)
%ccharscanf("%c", &ch)
%sstring (no spaces)scanf("%s", str)
%ldlong intscanf("%ld", &l)
%lldlong longscanf("%lld", &ll)
%uunsigned intscanf("%u", &u)
%ooctal intscanf("%o", &n)
%xhex intscanf("%x", &n)
escape_sequences.c
/* =============================================
   Program : Escape Sequences in C
   Purpose : Demonstrate special characters in strings
   Escape sequences start with backslash (\) followed by a character
   They represent characters that are difficult to type or have special meaning
   ============================================= */

/* ESCAPE SEQUENCES REFERENCE:
   \n = newline character (moves cursor to next line)
   \t = horizontal tab (moves cursor to next tab stop, usually 8 spaces)
   \r = carriage return (moves cursor to beginning of current line)
   \b = backspace (moves cursor back one character position)
   \\ = literal backslash character (since \ has special meaning)
   \' = literal single quote character (for char literals)
   \" = literal double quote character (for string literals)
   \0 = null character (terminates strings, ASCII value 0)
   \a = alert/bell character (produces audible beep)
   \f = form feed (new page in printers, newline in terminals)
   \v = vertical tab (moves down to next vertical tab stop)
   \xHH = character with hex value HH (e.g., \x41 = 'A')
   \OOO = character with octal value OOO (e.g., \101 = 'A') */

#include <stdio.h>  /* Standard I/O library for printf() */

int main() {  /* Program entry point */

    /* NEWLINE ESCAPE SEQUENCE:
       \n moves output to the next line */
    printf("Line1\nLine2\n");      /* Prints "Line1" then moves to next line, prints "Line2" */

    /* TAB ESCAPE SEQUENCE:
       \t creates horizontal spacing (typically 8 characters) */
    printf("Col1\tCol2\tCol3\n"); /* Creates table-like columns with tab spacing */

    /* QUOTE ESCAPE SEQUENCES:
       Since double quotes delimit strings, we need \" to include them inside */
    printf("He said \"Hello!\"\n"); /* Prints: He said "Hello!" */

    /* BACKSLASH ESCAPE SEQUENCE:
       Since backslash starts escape sequences, we need \\ for literal backslash */
    printf("Path: C:\\Users\\me\n");/* Prints: Path: C:\Users\me */

    /* ALERT/BELL ESCAPE SEQUENCE:
       \a produces an audible beep (if system supports it) */
    printf("\aBeep!\n");            /* Makes beep sound then prints "Beep!" */

    /* Program completed successfully */
    return 0;
}
➕ Operators

All Operators in C

C has a rich set of operators for arithmetic, comparison, logic, bit manipulation, and more.

Arithmetic, Relational & Logical
Core operators for calculations and decisions
operators_demo.c
/* =============================================
   Program : Complete C Operators Demonstration
   Purpose : Showcase all major operator categories in C
   Categories: Arithmetic, Relational, Logical, Assignment, Increment/Decrement
   Input   : None (uses hardcoded values)
   Output  : Results of various operator operations
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() function */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATIONS:
       a, b, c: integer variables for operator demonstrations
       a=10, b=3 provide good examples for various operations */
    int a=10, b=3, c;

    /* ============================================
       ARITHMETIC OPERATORS (+, -, *, /, %)
       Perform mathematical calculations
       ============================================ */

    printf("a+b=%d\n", a+b);   /* 13 — addition operator */
    printf("a-b=%d\n", a-b);   /* 7  — subtraction operator */
    printf("a*b=%d\n", a*b);   /* 30 — multiplication operator */
    printf("a/b=%d\n", a/b);   /* 3  — integer division (truncates decimal part) */
    printf("a%%b=%d\n", a%b);  /* 1  — modulo operator (remainder after division) */

    /* ============================================
       RELATIONAL OPERATORS (>, <, ==, !=, >=, <=)
       Compare values and return boolean result (1=true, 0=false)
       ============================================ */

    printf("a>b:  %d\n", a>b);   /* 1 = true (10 > 3) */
    printf("a<b:  %d\n", a<b);   /* 0 = false (10 < 3) */
    printf("a==b: %d\n", a==b);  /* 0 — equal? No (10 != 3) */
    printf("a!=b: %d\n", a!=b);  /* 1 — not equal? Yes (10 != 3) */
    printf("a>=b: %d\n", a>=b);  /* 1 — greater or equal? Yes (10 >= 3) */
    printf("a<=b: %d\n", a<=b);  /* 0 — less or equal? No (10 <= 3) */

    /* ============================================
       LOGICAL OPERATORS (&&, ||, !)
       Combine or negate boolean conditions
       && (AND): true only if BOTH operands are true
       || (OR):  true if at least ONE operand is true
       ! (NOT): flips true to false and vice versa
       ============================================ */

    printf("a>5 && b<5: %d\n", a>5 && b<5);  /* 1 (true AND true = true) */
    printf("a<5 || b<5: %d\n", a<5 || b<5);  /* 1 (false OR true = true) */
    printf("!(a>5): %d\n",       !(a>5));        /* 0 (NOT true = false) */

    /* ============================================
       ASSIGNMENT OPERATORS (=, +=, -=, *=, /=, %=)
       Modify variable values using shorthand notation
       These are equivalent to: variable = variable op value
       ============================================ */

    c = 20;          /* Simple assignment: c becomes 20 */
    c += 5;  /* c = c + 5 = 25 (addition assignment) */
    c -= 3;  /* c = c - 3 = 22 (subtraction assignment) */
    c *= 2;  /* c = c * 2 = 44 (multiplication assignment) */
    c /= 4;  /* c = c / 4 = 11 (division assignment) */
    c %= 4;  /* c = c % 4 = 3  (modulo assignment) */
    printf("c after ops: %d\n", c);  /* 3 (final result after all operations) */

    /* ============================================
       INCREMENT/DECREMENT OPERATORS (++, --)
       Increase or decrease variable by 1
       Pre-increment (++x): increment first, then use value
       Post-increment (x++): use value first, then increment
       Same applies to decrement operators
       ============================================ */

    int x = 5;  /* New variable for increment/decrement demo */

    printf("x++: %d\n", x++);  /* Post-increment: prints 5, then x becomes 6 */
    printf("++x: %d\n", ++x);  /* Pre-increment: x becomes 7, then prints 7 */
    printf("x--: %d\n", x--);  /* Post-decrement: prints 7, then x becomes 6 */
    printf("--x: %d\n", --x);  /* Pre-decrement: x becomes 5, then prints 5 */

    /* Program completed successfully */
    return 0;
}
⚙️
Bitwise & Ternary Operators
Bit manipulation and conditional shorthand
OpNameExample (a=6=0110, b=3=0011)Result
&AND6 & 3 = 0110 & 00110010 = 2
|OR6 | 3 = 0110 | 00110111 = 7
^XOR6 ^ 3 = 0110 ^ 00110101 = 5
~NOT~6 = ~01101001 = -7
<<Left Shift6 << 1 = multiply by 212
>>Right Shift6 >> 1 = divide by 23
bitwise_ternary.c
#include <stdio.h>
int main() {
    int a=6, b=3;  /* a=0110, b=0011 in binary */

    /* Bitwise AND: both bits must be 1
       0110 & 0011 = 0010 = 2 */
    printf("AND: %d\n", a&b);   /* 2 */
    /* Bitwise OR: either bit = 1 → result bit = 1
       0110 | 0011 = 0111 = 7 */
    printf("OR:  %d\n", a|b);   /* 7 */
    /* Left shift = multiply by 2 per shift position */
    printf("SHL: %d\n", a<<1);  /* 12 (6×2) */
    /* Right shift = integer divide by 2 per position */
    printf("SHR: %d\n", a>>1);  /* 3  (6÷2) */

    /* TERNARY OPERATOR: condition ? value_if_true : value_if_false
       Most compact form of if-else
       (a > b) is true, so max = a */
    int max = (a>b) ? a : b;
    printf("Max: %d\n", max);  /* 6 */

    /* Nested ternary for grade (use sparingly — can be hard to read) */
    int marks = 75;
    char g = (marks>=90) ? 'A':
              (marks>=80) ? 'B':
              (marks>=70) ? 'C': 'F';
    printf("Grade: %c\n", g);   /* C */

    /* Practical bitwise: check if number is even/odd
       n & 1 → if last bit is 1 = odd, 0 = even */
    printf("6 is %s\n", (a&1)?"Odd":"Even");  /* Even */

    return 0;
}
Precedence (High→Low): () [] → ~ ! ++ -- → * / % → + - → << >> → < > <= >= → == != → & → ^ → | → && → || → ?: → = += -= → ,
🔀 Control Statements

Decision Making — if, else, switch

🔀
if / if-else / else-if / nested
Conditional execution paths
if_statements.c
/* =============================================
   Program : Complete Conditional Statements Guide
   Purpose : Demonstrate if, if-else, else-if, and nested if constructs
   Input   : None (uses hardcoded values)
   Output  : Results of various conditional executions
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATION:
       marks: student score (75 out of 100)
       age, hasID: variables for nested if demonstration */
    int marks = 75;
    int age=20, hasID=1;

    /* ============================================
       SIMPLE IF STATEMENT
       Syntax: if(condition) { statements; }
       Executes body ONLY if condition evaluates to true (non-zero)
       No else clause = does nothing if condition is false
       ============================================ */

    if(marks >= 50)
        printf("Passed!\n");  /* Executes because 75 >= 50 is true */

    /* ============================================
       IF-ELSE STATEMENT
       Syntax: if(condition) { true_statements; } else { false_statements; }
       Exactly ONE branch always executes - either if or else
       ============================================ */

    if(marks >= 50)
        printf("Pass\n");
    else
        printf("Fail\n");  /* This would execute if marks < 50 */

    /* ============================================
       ELSE-IF LADDER (MULTI-WAY BRANCHING)
       Syntax: if(cond1) {...} else if(cond2) {...} else if(cond3) {...} else {...}
       Tests conditions in sequence from top to bottom
       ONLY the FIRST true condition executes - rest are skipped
       Final else catches all remaining cases (optional)
       ============================================ */

    if     (marks >= 90) printf("Grade: A\n");
    else if(marks >= 80) printf("Grade: B\n");
    else if(marks >= 70) printf("Grade: C\n"); /* ← Executes (75 >= 70) */
    else if(marks >= 60) printf("Grade: D\n");
    else                 printf("Grade: F\n");

    /* ============================================
       NESTED IF STATEMENTS
       An if statement inside another if statement
       Both outer AND inner conditions must be true to reach deepest code
       Useful for multi-level decision making
       ============================================ */

    if(age >= 18) {         /* OUTER CONDITION: Check age eligibility */
        if(hasID == 1) {    /* INNER CONDITION: Check ID requirement */
            printf("Entry allowed\n");
        } else {
            printf("Bring ID card\n");
        }
    } else {
        printf("Too young\n");
    }

    /* Program completed successfully */
    return 0;
}
🔦
switch-case
Multi-way branching on a single value
Use switch when: comparing the SAME variable/expression against multiple constant values. Cleaner than long if-else chains. Works with int and char only (not float or string).
switch_case.c
/* =============================================
   Program : Switch-Case Statement Demonstration
   Purpose : Show multi-way branching based on a single value
   Use when: Comparing the SAME variable against multiple constant values
   Works with: int, char (not float or string)
   Alternative to: Long if-else-if chains
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

int main() {  /* Program entry point */

    /* VARIABLE DECLARATIONS:
       day: integer representing day of week (1=Monday, 7=Sunday)
       op: character for calculator operation
       x, y: operands for calculator */
    int day = 3;
    char op='+'; int x=10, y=5;

    /* ============================================
       SWITCH STATEMENT SYNTAX AND FLOW
       switch(expression) {
           case constant1: statements; break;
           case constant2: statements; break;
           ...
           default: statements;  // optional
       }

       Flow: Expression evaluated once, then jumps to matching case
       Execution continues until break or end of switch
       ============================================ */

    /* SWITCH EXAMPLE 1: Day of week
       day=3, so execution jumps to case 3 */
    switch(day) {
        case 1: printf("Monday\n");    break; /* break exits switch immediately */
        case 2: printf("Tuesday\n");   break;
        case 3: printf("Wednesday\n"); break; /* ← This executes */
        case 4: printf("Thursday\n");  break;
        case 5: printf("Friday\n");    break;
        /* FALL-THROUGH: Multiple cases can share same code block */
        case 6:
        case 7: printf("Weekend!\n");  break;
        default: printf("Invalid!\n");  /* Runs if no case matches */
    }

    /* ============================================
       SWITCH EXAMPLE 2: Simple Calculator
       Demonstrates switch with char data type
       op='+', so case '+' executes: 10 + 5 = 15
       ============================================ */

    switch(op) {
        case '+': printf("%d\n",x+y); break;  /* Addition: 10 + 5 = 15 */
        case '-': printf("%d\n",x-y); break;  /* Subtraction: 10 - 5 = 5 */
        case '*': printf("%d\n",x*y); break;  /* Multiplication: 10 * 5 = 50 */
        case '/': printf("%d\n",x/y); break;  /* Division: 10 / 5 = 2 */
        default:  printf("Unknown\n");      /* Invalid operator */
    }

    /* Program completed successfully */
    return 0;
}
🔀 Control Statements

Loops — for, while, do-while

🔁
All Three Loop Types
When to use which loop
all_loops.c
/* =============================================
   Program : Complete Loop Control Structures
   Purpose : Demonstrate for, while, and do-while loops
   Use when: Repeating code multiple times
   Key concepts: Initialization, condition, update, body
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

int main() {  /* Program entry point */

    /* ============================================
       FOR LOOP: Best when you know exact number of iterations
       Syntax: for(initialization; condition; update) { body; }
       Flow: 1. Initialize, 2. Check condition, 3. Execute body, 4. Update, repeat
       ============================================ */

    printf("for:      ");
    for(int i=1; i<=5; i++) {  /* i starts at 1, loops while i<=5, increments i */
        printf("%d ", i);       /* Body: print current value of i */
    } printf("\n");                   /* Output: 1 2 3 4 5 */

    /* ============================================
       WHILE LOOP: Best when number of iterations is unknown
       Syntax: while(condition) { body; update; }
       Flow: 1. Check condition, 2. If true execute body, 3. Repeat
       Condition checked BEFORE each iteration
       ============================================ */

    printf("while:    ");
    int j=1;                    /* Initialize outside loop */
    while(j<=5) {                /* Check condition first */
        printf("%d ", j);         /* Body: print current value */
        j++;                          /* Update: increment j */
    } printf("\n");                   /* Output: 1 2 3 4 5 */

    /* ============================================
       DO-WHILE LOOP: Executes body AT LEAST once
       Syntax: do { body; update; } while(condition);
       Flow: 1. Execute body, 2. Check condition, 3. If true repeat
       Condition checked AFTER each iteration
       ============================================ */

    printf("do-while: ");
    int k=1;                    /* Initialize */
    do {
        printf("%d ", k);         /* Body: always executes first */
        k++;                          /* Update */
    } while(k<=5);             /* Check condition after */
    printf("\n");                   /* Output: 1 2 3 4 5 */

    /* ============================================
       NESTED LOOPS: Loop inside another loop
       Outer loop controls rows, inner loop controls columns
       Total iterations = outer_iterations * inner_iterations
       ============================================ */

    printf("Multiplication Table (3×3):\n");
    for(int r=1; r<=3; r++) {     /* Outer loop: rows (1,2,3) */
        for(int c=1; c<=3; c++) {   /* Inner loop: columns (1,2,3) */
            printf("%3d", r*c);     /* Print product with 3-char field width */
        }
        printf("\n");                /* New line after each row */
    }

    /* Program completed successfully */
    return 0;
}
🦘
Jump Statements
break, continue, goto, return
jump_statements.c
/* =============================================
   Program : Jump Statements in C
   Purpose : Demonstrate break, continue, goto, and return
   Use when: Need to alter normal control flow in loops/functions
   Key concepts: Loop control, function exit, unconditional jumps
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

int main() {  /* Program entry point */

    /* ============================================
       BREAK STATEMENT: Immediately exits the nearest loop or switch
       Execution resumes at the statement AFTER the loop/switch
       Useful for: Early exit from loops when condition is met
       ============================================ */

    printf("break:    ");
    for(int i=1; i<=10; i++) {  /* Loop from 1 to 10 */
        if(i==5) break;            /* Exit loop when i reaches 5 */
        printf("%d ", i);          /* Prints: 1 2 3 4 */
    } printf("\n");                       /* Loop exits here after break */

    /* ============================================
       CONTINUE STATEMENT: Skips the REST of current iteration
       Goes immediately to the loop's update/condition check
       Useful for: Skipping certain iterations based on conditions
       ============================================ */

    printf("continue: ");
    for(int i=1; i<=8; i++) {  /* Loop from 1 to 8 */
        if(i%2==0) continue;     /* Skip even numbers */
        printf("%d ", i);          /* Prints: 1 3 5 7 */
    } printf("\n");                       /* Even numbers are skipped */

    /* ============================================
       GOTO STATEMENT: Unconditionally jumps to a labeled statement
       AVOID in general code — makes logic hard to follow and debug
       One legitimate use: Error handling with cleanup code
       ============================================ */

    int n = -1;                          /* Negative input for demonstration */
    if(n < 0) goto error_label;      /* Jump to error handling */
    printf("This line is skipped\n");   /* Never executed */

    error_label:                           /* Label: identifier followed by colon */
        printf("Error: negative input!\n"); /* Error message */

    /* ============================================
       RETURN STATEMENT: Exits the current function immediately
       For main(): return 0 = success, non-zero = error code
       Can return a value that the caller receives
       ============================================ */

    return 0;  /* Exit main() with success code */
}
📦 Functions

Functions & Recursion

🧩
Function Basics
Declaration, definition, call, types
3 Parts: Declaration (prototype) — tells compiler function exists. Definition — actual implementation. Call — executing the function from somewhere.
functions_complete.c
/* =============================================
   Program : Complete Function Guide in C
   Purpose : Demonstrate function declaration, definition, and calling
   Key concepts: Prototypes, parameters, return values, void functions
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

/* ============================================
   FUNCTION DECLARATIONS (Prototypes)
   Must appear BEFORE they are called
   Tells compiler: "this function exists — trust me"
   Syntax: return_type function_name(parameter_types);
   ============================================ */

int   add(int a, int b);              /* Returns int, takes two ints */
float average(int arr[], int n);        /* Returns float, takes array and size */
void  greet(char name[]);             /* Returns nothing (void), takes string */
int   square(int n);                  /* Returns int, takes one int */

int main() {  /* Program entry point */

    /* ============================================
       FUNCTION CALLS — values passed as arguments
       Arguments are COPIED to function parameters
       ============================================ */

    printf("5 + 3 = %d\n", add(5,3));         /* Calls add function, prints: 8 */
    printf("4^2 = %d\n",  square(4));        /* Calls square function, prints: 16 */
    greet("Alice");                             /* Calls greet function */

    int nums[] = {10,20,30,40};             /* Array of 4 integers */
    printf("Avg: %.1f\n", average(nums,4));     /* Calls average function, prints: 25.0 */

    return 0;  /* Exit main with success */
}

/* ============================================
   FUNCTION DEFINITIONS — actual implementation code
   Parameters 'a' and 'b' are LOCAL copies of arguments
   Changes to parameters here do NOT affect caller's variables
   ============================================ */

int add(int a, int b) {
    return a + b;  /* Return result to caller */
}

/* One-liner function — still valid C syntax */
int square(int n) { return n * n; }  /* Return n squared */

/* ============================================
   ARRAY PARAMETER: arr[] automatically becomes a pointer
   n is passed separately since arrays don't know their size
   ============================================ */

float average(int arr[], int n) {
    int sum = 0;                              /* Initialize sum to zero */
    for(int i=0; i<n; i++) sum += arr[i];   /* Add each element to sum */
    return (float)sum / n;                  /* Cast to float for decimal division */
}

/* ============================================
   VOID FUNCTION — performs work but returns nothing
   No return statement needed, or use bare "return;"
   ============================================ */

void greet(char name[]) {
    printf("Hello, %s!\n", name);         /* Print greeting message */
    /* No return statement needed for void functions */
}
🔄
Recursion & Call by Value/Reference
Function calling itself + pointer parameters
Recursion rules: Must have a BASE CASE (stops recursion). Must progress toward base case each call. Stack builds up then unwinds.
recursion_callbyref.c
/* =============================================
   Program : Recursion and Parameter Passing in C
   Purpose : Demonstrate recursive functions and call by value/reference
   Key concepts: Base cases, recursive calls, pointers, memory addresses
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

/* ============================================
   RECURSION: A function that calls itself
   Must have a BASE CASE to stop infinite recursion
   Each call progresses toward the base case
   Call stack builds up then unwinds with return values
   ============================================ */

/* FACTORIAL RECURSION: factorial(5) = 5 × 4 × 3 × 2 × 1 = 120
   Call stack: factorial(5) → factorial(4) → factorial(3) → factorial(2) → factorial(1) → factorial(0)
   Returns: 1 ← 1 ← 2 ← 6 ← 24 ← 120 */

int factorial(int n) {
    if(n <= 1) return 1;                     /* BASE CASE: factorial(0) = factorial(1) = 1 */
    return n * factorial(n-1);                /* RECURSIVE CALL: multiply by smaller factorial */
}

/* FIBONACCI RECURSION: fib(n) = fib(n-1) + fib(n-2)
   Sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55...
   Base cases: fib(0) = 0, fib(1) = 1 */

int fib(int n) {
    if(n<=1) return n;                      /* BASE CASES: fib(0)=0, fib(1)=1 */
    return fib(n-1) + fib(n-2);          /* TWO recursive calls */
}

/* ============================================
   CALL BY VALUE — Default parameter passing in C
   Function receives a COPY of the argument
   Changes to parameter inside function do NOT affect original variable
   ============================================ */

void doubleVal(int x) {
    x *= 2;                                       /* Only modifies the LOCAL copy */
    printf("Inside doubleVal: %d\n", x);     /* Prints doubled value */
}

/* ============================================
   CALL BY REFERENCE — Using pointers
   Function receives the MEMORY ADDRESS of the argument
   Changes through pointer DIRECTLY affect the original variable
   Use & (address-of) operator when calling, * (dereference) inside function
   ============================================ */

void doubleRef(int *x) {
    *x *= 2;                                  /* *x dereferences pointer = changes original value */
    printf("Inside doubleRef: %d\n", *x);  /* Prints doubled original value */
}

int main() {  /* Program entry point */

    /* RECURSION DEMONSTRATION */
    printf("5! = %d\n", factorial(5));             /* 120 */
    printf("fib(8) = %d\n", fib(8));           /* 21 */

    /* CALL BY VALUE DEMONSTRATION */
    int a=10;                                      /* Original value: 10 */
    doubleVal(a);                                 /* Pass by value */
    printf("After doubleVal: %d\n", a);        /* Still 10! Original unchanged */

    /* CALL BY REFERENCE DEMONSTRATION */
    int b=10;                                      /* Original value: 10 */
    doubleRef(&b);                              /* Pass ADDRESS of b using & operator */
    printf("After doubleRef: %d\n", b);       /* Now 20! Original was modified */

    return 0;  /* Exit with success */
}
📚 Arrays

Arrays — 1D, 2D & Functions

📏
1D & 2D Arrays
Fixed-size collections of same-type data
Array: contiguous memory block holding same-type elements. Index starts at 0. arr[0] is first, arr[n-1] is last.
arrays_complete.c
/* =============================================
   Program : Complete Arrays Guide in C
   Purpose : Demonstrate 1D and 2D arrays with operations
   Key concepts: Declaration, initialization, indexing, traversal
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

int main() {  /* Program entry point */

    /* ============================================
       1D ARRAY — Linear sequence of elements
       Declaration: type name[size] = {values};
       Index starts at 0, ends at size-1
       ============================================ */

    int marks[5] = {85,92,78,95,88};  /* Array of 5 integers */

    /* ACCESS ELEMENTS: Use index [0..n-1] */
    printf("First: %d\n", marks[0]);           /* 85 - first element */
    printf("Last:  %d\n", marks[4]);           /* 88 - last element */

    /* TRAVERSE WITH LOOP: Process all elements */
    int sum=0;                                      /* Initialize sum to zero */
    for(int i=0; i<5; i++) sum+=marks[i];       /* Add each element to sum */
    printf("Average: %.1f\n", (float)sum/5);   /* Cast to float for decimal division */

    /* FIND MAXIMUM VALUE: Linear search algorithm */
    int max=marks[0];                              /* Start with first element */
    for(int i=1; i<5; i++)                     /* Check remaining elements */
        if(marks[i]>max) max=marks[i];           /* Update max if larger found */
    printf("Max: %d\n", max);                   /* 95 */

    /* ============================================
       2D ARRAY — Table/matrix of elements
       Declaration: type name[rows][cols] = {{row0}, {row1}, ...};
       Stored in row-major order: matrix[row][col]
       ============================================ */

    int mat[3][3] = {                              /* 3x3 matrix */
        {1,2,3},                                  /* Row 0 */
        {4,5,6},                                  /* Row 1 */
        {7,8,9}                                   /* Row 2 */
    };

    /* PRINT 2D ARRAY: Nested loops for rows and columns */
    printf("Matrix:\n");
    for(int r=0; r<3; r++) {                     /* Outer loop: rows */
        for(int c=0; c<3; c++)                 /* Inner loop: columns */
            printf("%3d", mat[r][c]);                /* Print element with 3-char width */
        printf("\n");                                /* New line after each row */
    }

    /* MATRIX TRANSPOSE: Swap mat[i][j] with mat[j][i] */
    printf("Transpose:\n");
    for(int r=0; r<3; r++) {                     /* Outer loop: rows */
        for(int c=0; c<3; c++)                 /* Inner loop: columns */
            printf("%3d", mat[c][r]);            /* Note: c,r swapped for transpose */
        printf("\n");                                /* New line after each row */
    }

    return 0;  /* Exit with success */
}
📦
Arrays with Functions
Passing and processing arrays in functions
array_functions.c
/* =============================================
   Program : Arrays with Functions in C
   Purpose : Demonstrate passing arrays to functions and processing them
   Key concepts: Array parameters, pointer decay, in-place modifications
   ============================================= */

#include <stdio.h>  /* Standard I/O library for printf() */

/* ============================================
   ARRAY PARAMETERS: Arrays are passed as pointers automatically
   Syntax: return_type function_name(type arr[], int size)
   Changes to array elements WILL affect the caller's original array
   ============================================ */

/* FIND MAXIMUM VALUE: Linear search through array */
int findMax(int arr[], int n) {                    /* arr[] decays to int* pointer */
    int max=arr[0];                                  /* Start with first element */
    for(int i=1; i<n; i++)                         /* Check remaining elements */
        if(arr[i]>max) max=arr[i];               /* Update max if larger found */
    return max;                                       /* Return maximum value */
}

/* REVERSE ARRAY IN-PLACE: Two-pointer technique */
void reverse(int arr[], int n) {                   /* void = no return value */
    int lo=0, hi=n-1;                            /* Initialize pointers at ends */
    while(lo<hi) {                                 /* While pointers haven't crossed */
        int tmp=arr[lo]; arr[lo]=arr[hi]; arr[hi]=tmp; /* Swap elements */
        lo++; hi--;                                  /* Move pointers toward center */
    }
}

/* LINEAR SEARCH: Find index of target value */
int search(int arr[], int n, int target) {         /* Returns index or -1 if not found */
    for(int i=0; i<n; i++)                     /* Check each element */
        if(arr[i]==target) return i;                  /* Return index if found */
    return -1;                                          /* -1 = not found convention */
}

int main() {  /* Program entry point */

    int nums[]={3,7,1,9,4,6}, sz=6;           /* Array and its size */

    /* CALL FUNCTIONS WITH ARRAY */
    printf("Max: %d\n", findMax(nums,sz));              /* 9 - maximum value */

    int idx=search(nums,sz,9);                      /* Search for value 9 */
    printf("9 found at index: %d\n", idx);           /* 3 - index of 9 */

    reverse(nums,sz);                              /* Reverse array in-place */
    printf("Reversed: ");
    for(int i=0; i<sz; i++) printf("%d ",nums[i]); /* Print reversed array: 6 4 9 1 7 3 */

    return 0;  /* Exit with success */
}
🔤 Strings

Strings & String Functions

💬
String Basics & Functions
char arrays terminated by \0
String = char array ending with null '\0'. "Hello" stores: H e l l o \0 (6 bytes). Always declare with enough space for \0!
strings_complete.c
/* =============================================
   Program : Complete String Functions Guide in C
   Purpose : Demonstrate string operations and functions from <string.h>
   Key concepts: Null-terminated arrays, string functions, character processing
   ============================================= */

#include <stdio.h>   /* Standard I/O library for printf(), fgets() */
#include <string.h>  /* String functions: strlen, strcpy, strcat, strcmp, etc. */
#include <ctype.h>   /* Character functions: toupper, tolower, isdigit, etc. */

int main() {  /* Program entry point */

    /* ============================================
       STRING DECLARATIONS: Arrays of characters ending with '\0'
       "Hello" stores: H e l l o \0 (6 bytes total)
       Always declare with enough space for the null terminator!
       ============================================ */

    char s1[20] = "Hello";         /* Fixed size, initialized */
    char s2[] = "World";           /* Size auto-calculated = 6 */
    char s3[50];                     /* Empty — holds user input */

    /* ============================================
       STRING INPUT METHODS
       scanf("%s") — reads until whitespace (single word only)
       fgets() — reads full line including spaces (safer, recommended)
       ============================================ */

    printf("Enter your name: ");
    fgets(s3, sizeof(s3), stdin);      /* Reads up to 49 chars + \n */

    /* ============================================
       STRING FUNCTIONS from <string.h>
       All functions work with null-terminated strings
       ============================================ */

    /* strlen — Count characters (NOT counting \0) */
    printf("Length of '%s': %zu\n", s1, strlen(s1));  /* 5 characters */

    /* strcpy — Copy source string INTO destination
       Destination must be large enough to hold source + \0 */
    char dest[20];                          /* Destination buffer */
    strcpy(dest, s1);                    /* dest now = "Hello" */

    /* strcat — Append source TO END of destination
       Destination must have enough space for combined strings */
    strcat(s1, " World");               /* s1 = "Hello World" */
    printf("%s\n", s1);                 /* Print concatenated result */

    /* strcmp — Compare two strings LEXICOGRAPHICALLY
       Returns: 0 if equal, <0 if s1<s2, >0 if s1>s2 */
    int r=strcmp("apple","apple");       /* Compare identical strings */
    printf("strcmp equal: %d\n", r);     /* 0 = equal */

    /* strchr — Find first occurrence of character in string
       Returns pointer to that position, or NULL if not found */
    char *p=strchr("Hello",'l');         /* Find first 'l' */
    printf("Found 'l' at: %s\n", p);    /* "llo" (pointer to 'l') */

    /* strstr — Find first occurrence of substring */
    char *q=strstr("Hello World","World"); /* Find "World" */
    printf("Substring: %s\n", q);      /* "World" */

    /* strtok — Split string by delimiters (tokenize)
       First call: pass the string. Subsequent calls: pass NULL */
    char csv[] = "Alice,Bob,Charlie";         /* Comma-separated values */
    char *tok=strtok(csv,",");               /* First token: "Alice" */
    while(tok!=NULL) {                      /* While tokens remain */
        printf("Token: %s\n", tok);       /* Print current token */
        tok=strtok(NULL,",");            /* Next token */
    }

    /* ============================================
       CHARACTER PROCESSING from <ctype.h>
       toupper/tolower — convert single char case
       To convert whole string, loop through each character
       ============================================ */

    char word[]="hello";                     /* String to convert */
    for(int i=0; word[i]; i++)             /* Loop until null terminator */
        word[i]=toupper(word[i]);           /* Convert each char to uppercase */
    printf("Uppercase: %s\n", word);    /* "HELLO" */

    return 0;  /* Exit with success */
}
📚
String Functions Reference
All key <string.h> functions
FunctionPurposeReturns
strlen(s)Length of stringsize_t
strcpy(d,s)Copy s into dd pointer
strncpy(d,s,n)Copy at most n charsd pointer
strcat(d,s)Append s to dd pointer
strncat(d,s,n)Append at most n charsd pointer
strcmp(a,b)Compare two stringsint
strncmp(a,b,n)Compare first n charsint
strchr(s,c)Find char c in schar*
strstr(s,t)Find substring t in schar*
strtok(s,d)Split s by delimiters dchar*
sprintf(b,f,...)printf into string bufferint
sscanf(s,f,...)scanf from stringint
atoi(s)String → integerint
atof(s)String → doubledouble
strupr(s)Convert to uppercasechar*
strlwr(s)Convert to lowercasechar*
strrev(s)Reverse a stringchar*
🧱 Pointers

Pointers — C's Most Powerful Feature

👆
Pointer Basics & Arithmetic
Variables that store memory addresses
Pointer = a variable that stores the memory address of another variable. Every byte in RAM has a unique address (like a house number). Pointers let you directly access memory locations.
10
0x1000
int var
0x1000
0x2000
int *ptr
pointers_complete.c
#include <stdio.h>
int main() {

    int var = 10;          /* regular variable stored somewhere */
    int *ptr;              /* pointer: * means "pointer to int" */

    /* & = address-of operator: gives the ADDRESS of variable */
    ptr = &var;            /* ptr now HOLDS the address of var */

    printf("var   = %d\n",  var);   /* 10 (the value) */
    printf("&var  = %p\n",  &var);  /* 0x...  (address) */
    printf("ptr   = %p\n",  ptr);   /* same address as &var */

    /* * = dereference operator: "go to that address and get value" */
    printf("*ptr  = %d\n", *ptr);   /* 10 = value at address */

    /* Change value THROUGH the pointer */
    *ptr = 99;   /* This changes var! Both ptr and &var point there */
    printf("var after *ptr=99: %d\n", var);  /* 99 */

    /* POINTER ARITHMETIC — moving through memory
       ptr + 1 moves forward by sizeof(int) = 4 bytes */
    int arr[]={10,20,30,40};
    int *p=arr;   /* p points to arr[0] */

    printf("%d\n", *p);       /* 10 = arr[0] */
    printf("%d\n", *(p+1));  /* 20 = arr[1] (moved 4 bytes) */
    printf("%d\n", *(p+2));  /* 30 = arr[2] */
    p++;  /* now p points to arr[1] */
    printf("%d\n", *p);       /* 20 */

    /* DOUBLE POINTER — pointer to a pointer (**pp)
       pp → ptr → var
       pp holds address of ptr, ptr holds address of var */
    int x=42;
    int  *ptr1=&x;       /* ptr1 points to x */
    int **ptr2=&ptr1;    /* ptr2 points to ptr1 */
    printf("x via **ptr2: %d\n", **ptr2);  /* 42 */

    /* NULL pointer — pointer that points to nothing
       ALWAYS initialize pointers! Uninitialized = DANGER */
    int *np=NULL;
    if(np==NULL) printf("Null pointer is safe!\n");

    return 0;
}
🔗
Pointer with Arrays & Functions
Function pointers, pointer-array equivalence
pointer_advanced.c
#include <stdio.h>

/* Swap two integers using pointers — classic pointer function
   Without pointers, original values would NOT be swapped */
void swap(int *a, int *b) {
    int tmp=*a;  /* save value at a's address */
    *a=*b;       /* write b's value to a's address */
    *b=tmp;      /* write saved value to b's address */
}

/* Functions for function pointer example */
int add(int x, int y) { return x+y; }
int mul(int x, int y) { return x*y; }

int main() {

    /* Array name IS a pointer to first element
       arr, &arr[0], and p all hold same address */
    int arr[]={5,10,15};
    int *p=arr;
    /* These three are EQUIVALENT ways to access arr[1]: */
    printf("%d %d %d\n", arr[1], *(p+1), p[1]);  /* all print 10 */

    /* Using pointer to iterate over array */
    for(int *q=arr; q<arr+3; q++)
        printf("%d ", *q);  /* 5 10 15 */
    printf("\n");

    /* Swap using pointers */
    int x=100, y=200;
    swap(&x,&y);  /* pass ADDRESSES — & required */
    printf("After swap: x=%d y=%d\n", x, y);  /* x=200 y=100 */

    /* FUNCTION POINTER — stores address of a function
       Declaration: return_type (*fp_name)(param_types)
       Enables runtime selection of which function to call */
    int (*fp)(int,int);  /* fp can point to any int(int,int) func */

    fp=add;  /* point to add function */
    printf("add via fp: %d\n", fp(3,4));  /* 7 */

    fp=mul;  /* now point to mul function */
    printf("mul via fp: %d\n", fp(3,4));  /* 12 */

    /* Pointer to string */
    char *str="Hello";  /* str points to string literal */
    while(*str) printf("%c", *str++);  /* print char by char */
    printf("\n");

    return 0;
}
🏗️ User Defined Types

Structure, Union, Enum & typedef

🏛️
Structure
Group different data types under one name
struct groups related variables of DIFFERENT types. Each member gets its OWN separate memory. Size = sum of all members (+ padding).
structure.c
#include <stdio.h>
#include <string.h>

/* Define a structure blueprint for Student
   This does NOT allocate memory — just defines the template */
struct Student {
    char  name[50];   /* 50 bytes for name string */
    int   roll;        /* 4 bytes for roll number */
    float marks;       /* 4 bytes for marks */
    char  grade;       /* 1 byte for grade character */
};  /* semicolon required after struct definition! */

/* typedef creates an ALIAS — write "Student" instead of "struct Student" */
typedef struct Student Student;

int main() {
    /* Create struct variable and initialize at once */
    Student s1 = {"Alice", 101, 92.5f, 'A'};

    /* Access members using DOT operator ( . ) */
    printf("Name:  %s\n",  s1.name);
    printf("Roll:  %d\n",  s1.roll);
    printf("Marks: %.1f\n",s1.marks);
    printf("Grade: %c\n",  s1.grade);

    /* Modify struct members after creation */
    s1.marks = 95.0f;
    strcpy(s1.name, "Bob");  /* use strcpy for string members */

    /* ARRAY OF STRUCTS — store multiple records */
    Student cls[3] = {
        {"Alice",1,90,'A'},
        {"Bob",  2,75,'B'},
        {"Carol",3,60,'C'}
    };
    for(int i=0; i<3; i++)
        printf("%s: %.0f\n", cls[i].name, cls[i].marks);

    /* POINTER TO STRUCT — use ARROW operator ( -> )
       Instead of (*ptr).member, use ptr->member */
    Student *sp = &cls[0];
    printf("Via ptr: %s\n", sp->name);   /* -> is shorthand for (*sp).name */
    sp++;  /* move pointer to next struct in array */
    printf("Next:    %s\n", sp->name);

    /* NESTED STRUCTS — struct inside struct */
    struct Date { int day, month, year; };
    struct Employee {
        char       name[40];
        float      salary;
        struct Date doj;   /* Date of Joining nested inside */
    };
    struct Employee emp = {"Dave", 50000, {15,6,2020}};
    printf("Joined: %d/%d/%d\n", emp.doj.day, emp.doj.month, emp.doj.year);

    return 0;
}
🤝
Union, Enum & typedef
Shared memory, named constants, type aliases
union — all members SHARE the same memory. Size = size of LARGEST member. Only ONE member holds valid data at a time.
union_enum_typedef.c
#include <stdio.h>

/* UNION — members SHARE same memory location
   sizeof(Data) = 8 (largest member: double)
   Useful to save memory when only one value needed at a time */
union Data {
    int    i;    /* 4 bytes */
    float  f;    /* 4 bytes */
    double d;    /* 8 bytes → determines union size */
};

/* ENUM — enumeration of named integer constants
   Makes code readable: use "Mon" instead of "0" */
enum Day {
    Mon=1, Tue, Wed, Thu, Fri,  /* Mon=1, Tue=2, ... Fri=5 */
    Sat=10, Sun                  /* Sat=10, Sun=11 */
};

/* ENUM for status codes — very common pattern */
enum Status { PENDING=0, APPROVED=1, REJECTED=2 };

/* TYPEDEF — create shorter/cleaner alias for types */
typedef unsigned long long ull;   /* ull instead of ull */
typedef int bool;                  /* simulate bool */
#define true  1
#define false 0

int main() {
    /* Using union */
    union Data d;
    d.i = 42;                         /* store int */
    printf("d.i = %d\n", d.i);        /* 42 */

    d.f = 3.14f;                      /* OVERWRITES int — they share memory */
    printf("d.f = %.2f\n", d.f);      /* 3.14 */
    printf("d.i now = %d\n", d.i);    /* GARBAGE — int was overwritten */

    /* Using enum */
    enum Day today = Wed;
    printf("Wednesday = %d\n", today); /* 3 */
    printf("Saturday  = %d\n", Sat);   /* 10 */

    if(today == Wed)
        printf("Midweek!\n");

    /* Enum in switch — very clean pattern */
    enum Status s = APPROVED;
    switch(s) {
        case PENDING:  printf("Waiting\n");  break;
        case APPROVED: printf("Approved!\n"); break;
        case REJECTED: printf("Rejected.\n"); break;
    }

    /* typedef usage */
    ull big = 9999999999ULL;
    printf("Big: %llu\n", big);

    bool flag = true;
    printf("Flag: %d\n", flag);  /* 1 */

    return 0;
}
📂 File Handling

File Handling — Read, Write, Append

📂
File Basics & Text Files
fopen, fclose, fprintf, fscanf, fgets
ModeMeaningFile exists?
"r"Read onlyMust exist
"w"Write (create/truncate)Created if not
"a"Append to endCreated if not
"r+"Read + WriteMust exist
"w+"Write + Read (truncate)Created if not
"rb"Read binaryMust exist
"wb"Write binaryCreated if not
file_handling.c
#include <stdio.h>

int main() {
    /* FILE* is a pointer to the file structure
       fopen() returns NULL on failure — ALWAYS check! */
    FILE *fp;

    /* WRITE to text file */
    fp = fopen("data.txt", "w");
    if(fp == NULL) {
        printf("Error: cannot open file!\n");
        return 1;  /* exit with error code */
    }
    fprintf(fp, "Hello, File!\n");      /* like printf but to file */
    fprintf(fp, "Number: %d\n", 42);
    fprintf(fp, "Float:  %.2f\n", 3.14);
    fclose(fp);  /* ALWAYS close! Flushes buffer to disk */

    /* READ from text file — line by line using fgets */
    fp = fopen("data.txt", "r");
    if(fp == NULL) { printf("File not found!\n"); return 1; }

    char line[100];
    printf("File contents:\n");
    while(fgets(line, sizeof(line), fp) != NULL)
        printf("%s", line);  /* fgets includes \n already */
    fclose(fp);

    /* APPEND mode — adds to END without deleting existing */
    fp = fopen("data.txt", "a");
    fprintf(fp, "Appended line!\n");
    fclose(fp);

    /* READ character by character using fgetc */
    fp = fopen("data.txt", "r");
    int ch;
    while((ch = fgetc(fp)) != EOF) {  /* EOF = End Of File marker */
        putchar(ch);  /* print each character */
    }
    fclose(fp);

    /* fscanf — read formatted data from file */
    fp = fopen("data.txt", "r");
    char word[20]; int num;
    fscanf(fp, "%s %s %d", word, word, &num);  /* read word by word */
    fclose(fp);

    return 0;
}
💾
Binary Files — fread & fwrite
Store structs and raw binary data
binary_file.c
#include <stdio.h>

struct Record {
    int   id;
    char  name[30];
    float salary;
};

int main() {
    struct Record emp = {1, "Alice", 50000.0f};
    FILE *fp;

    /* fwrite — write raw binary bytes to file
       Syntax: fwrite(data_ptr, size_of_one_item, count, file)
       Faster than fprintf, stores exact bytes */
    fp = fopen("records.bin", "wb");
    fwrite(&emp, sizeof(struct Record), 1, fp);
    fclose(fp);

    /* fread — read binary data back
       Syntax: fread(dest_ptr, size_of_one_item, count, file)
       Returns number of items actually read */
    struct Record r2;
    fp = fopen("records.bin", "rb");
    int items = fread(&r2, sizeof(struct Record), 1, fp);
    fclose(fp);

    if(items==1)
        printf("ID:%d Name:%s Sal:%.0f\n", r2.id, r2.name, r2.salary);

    /* fseek — move file position pointer
       SEEK_SET = from start, SEEK_CUR = from current, SEEK_END = from end */
    fp = fopen("records.bin", "rb");
    fseek(fp, 0, SEEK_END);     /* jump to end of file */
    long sz = ftell(fp);         /* current position = file size */
    printf("File size: %ld bytes\n", sz);
    rewind(fp);                    /* go back to beginning */
    fclose(fp);

    /* remove() — delete a file */
    if(remove("records.bin") == 0)
        printf("File deleted!\n");

    /* rename() — rename a file */
    rename("data.txt", "output.txt");

    return 0;
}
🧮 Advanced

Dynamic Memory Allocation

Allocate memory at runtime from the heap using malloc, calloc, realloc, and free.

🧠
malloc, calloc, realloc, free
Heap memory management
FunctionPurposeInitializes?
malloc(size)Allocate size bytesNo (garbage)
calloc(n,size)Allocate n×size bytesYes (zeros)
realloc(ptr,size)Resize allocationNo
free(ptr)Release memory
dynamic_memory.c
#include <stdio.h>
#include <stdlib.h>  /* malloc, calloc, realloc, free */

int main() {
    int n=5;

    /* malloc — allocate n integers on the HEAP
       Returns void* (generic pointer) — must cast to correct type
       Does NOT initialize memory (contains garbage!) */
    int *a = (int*) malloc(n * sizeof(int));

    /* ALWAYS check if allocation succeeded! */
    if(a == NULL) {
        printf("malloc failed — not enough memory!\n");
        return 1;
    }
    /* Use it like a regular array */
    for(int i=0; i<n; i++) a[i] = (i+1)*10;
    for(int i=0; i<n; i++) printf("%d ", a[i]); /* 10 20 30 40 50 */
    printf("\n");

    /* calloc — allocate AND zero-initialize
       calloc(count, size_each) — safer than malloc */
    int *b = (int*) calloc(n, sizeof(int));
    if(b==NULL) { free(a); return 1; }
    for(int i=0; i<n; i++) printf("%d ", b[i]); /* 0 0 0 0 0 */
    printf("\n");

    /* realloc — resize existing allocation
       If new size is larger, old data is preserved
       May return a DIFFERENT pointer — reassign always! */
    int *c = (int*) realloc(a, 8 * sizeof(int));  /* grow to 8 ints */
    if(c==NULL) { free(a); free(b); return 1; }
    a = c;  /* update pointer — old 'a' may be invalid now */
    a[5]=60; a[6]=70; a[7]=80;  /* fill new slots */

    /* free — MUST free heap memory when done
       Not freeing = MEMORY LEAK (memory wasted forever)
       Never access memory after freeing! */
    free(a);  /* free first allocation */
    free(b);  /* free second allocation */
    a = NULL; b = NULL;  /* set to NULL after freeing — good habit */

    /* Dynamic array of structs */
    int cnt=3;
    struct { char name[20]; int age; } *people;
    people = malloc(cnt * sizeof(*people));
    if(people) {
        for(int i=0; i<cnt; i++)
            printf("Person %d age slot ready\n", i);
        free(people);
    }
    return 0;
}
⚠️
Memory Concepts Visualized
Stack vs Heap, memory leaks
Stack — automatic, fast, limited size. Local variables live here. Auto-freed when function returns.
Heap — manual, large, slow. malloc/calloc memory lives here. YOU must free it with free().
memory_zones.c
#include <stdio.h>
#include <stdlib.h>

/* Memory zones in a C program:
   ┌─────────────────┐
   │   Code Segment  │ ← compiled instructions
   ├─────────────────┤
   │  Data Segment   │ ← global & static vars
   ├─────────────────┤
   │      Heap       │ ← malloc/calloc (grows ↑)
   │        ↑        │
   │        ↓        │
   │      Stack      │ ← local vars (grows ↓)
   └─────────────────┘ */

int globalVar = 100;  /* Data Segment */

int main() {
    int local = 10;         /* STACK — auto freed at } */
    int *heap = malloc(4); /* HEAP  — must free manually */

    printf("Stack addr: %p\n", &local);
    printf("Heap  addr: %p\n",  heap);

    /* MEMORY LEAK — bad! heap never freed */
    /* heap = malloc(100);  ← if you forget free(heap) below */

    /* DANGLING POINTER — bad! access after free */
    free(heap);
    heap = NULL;  /* good practice — prevents dangling ptr */
    /* *heap = 5;  ← CRASH! Never use after free */

    return 0;
}
🧮 Advanced

Preprocessor Directives & Macros

#
All Preprocessor Directives
Processed before compilation begins
preprocessor.c
/* PREPROCESSOR DIRECTIVES — lines starting with #
   Processed BEFORE compilation by the preprocessor */

/* #include — insert header file content */
#include <stdio.h>    /* system header — search system path */
#include "myfile.h"   /* user header — search current directory first */

/* #define — create constants and macros */
#define PI       3.14159          /* simple constant */
#define MAX      100
#define SQ(x)   ((x)*(x))         /* function-like macro */
#define MAX2(a,b) ((a)>(b)?(a):(b)) /* max macro */
#define STR     "Hello Macro"    /* string constant */

/* #undef — remove a previously defined macro */
#undef MAX
#define MAX 200   /* redefine with new value */

/* #ifdef / #ifndef — conditional compilation
   Include code only if macro IS or IS NOT defined */
#define DEBUG   /* define DEBUG flag */

#ifdef DEBUG
    #define LOG(msg) printf("[DBG] %s\n", msg)
#else
    #define LOG(msg)   /* empty — no logging in release */
#endif

/* #if / #elif / #else — numeric condition check */
#define VERSION 2
#if VERSION == 1
    #define FEATURE "Basic"
#elif VERSION == 2
    #define FEATURE "Advanced"
#else
    #define FEATURE "Unknown"
#endif

/* #pragma — compiler-specific instructions */
#pragma once       /* include guard — prevent double inclusion */
#pragma warning(disable:4996)  /* suppress specific warnings */

/* Predefined macros — always available */
/* __FILE__ = "filename.c"    (current file name) */
/* __LINE__ = 42              (current line number) */
/* __DATE__ = "Jan 01 2024"   (compilation date) */
/* __TIME__ = "12:00:00"      (compilation time) */
/* __STDC__ = 1               (standard C?) */

int main() {
    printf("SQ(5) = %d\n", SQ(5));         /* 25 */
    printf("MAX2(3,7) = %d\n", MAX2(3,7)); /* 7 */
    LOG("Program started");                 /* [DBG] Program started */
    printf("Feature: %s\n", FEATURE);       /* Advanced */
    printf("File: %s Line: %d\n", __FILE__, __LINE__);
    return 0;
}
🖥️
Command Line Arguments
argc and argv — pass args to program
argc = argument count (always ≥ 1, program name counts). argv = argument vector (array of strings). argv[0] = program name.
cmdargs.c
#include <stdio.h>
#include <stdlib.h>  /* for atoi() */

/* argc = number of arguments (including program name)
   argv = array of argument strings
   Run as: ./program 10 20 30 */
int main(int argc, char *argv[]) {

    printf("Number of arguments: %d\n", argc);
    printf("Program name: %s\n", argv[0]);  /* always program name */

    /* Print all arguments */
    for(int i=1; i<argc; i++)
        printf("argv[%d] = %s\n", i, argv[i]);

    /* Convert string arg to integer using atoi() */
    if(argc >= 3) {
        int a=atoi(argv[1]), b=atoi(argv[2]);
        printf("%d + %d = %d\n", a, b, a+b);
    } else {
        printf("Usage: %s num1 num2\n", argv[0]);
    }
    return 0;
}
🧮 Advanced

Storage Classes & Bit Fields

💾
Storage Classes
auto, static, extern, register
auto
Default for local variables. Created on stack when block starts, destroyed when block ends.
static
Persists across function calls. Initialized once. Local=private to file, Global=file scope.
extern
Declare variable defined in ANOTHER file. Enables sharing across multiple .c files.
register
Hint to store in CPU register (fastest). Compiler may ignore. Cannot take address (&).
storage_classes.c
#include <stdio.h>

/* EXTERN — global variable shared across files
   Define it here, declare it in other files with 'extern int g;' */
int g = 100;  /* global — implicitly extern */

void countCalls() {
    /* STATIC local — survives between function calls
       Initialized ONCE to 0, then keeps its value */
    static int count = 0;
    count++;
    printf("Called %d time(s)\n", count);
}

void regularLocal() {
    /* AUTO local — destroyed and recreated each call
       Always starts fresh at 0 */
    auto int x = 0;  /* auto is the default, keyword rarely needed */
    x++;
    printf("x = %d\n", x);  /* always prints 1 */
}

int main() {
    /* static function — counts calls */
    countCalls();  /* Called 1 time(s) */
    countCalls();  /* Called 2 time(s) */
    countCalls();  /* Called 3 time(s) */

    regularLocal();  /* x = 1 */
    regularLocal();  /* x = 1 (always!) */

    /* REGISTER — hint for CPU register storage
       Best for loop counters accessed very frequently */
    register int i;
    int sum=0;
    for(i=0; i<1000000; i++) sum+=i;  /* i in register = faster */
    printf("Sum: %d\n", sum);

    /* static global in one file:
       In another .c file: extern int g; — to USE it
       In header .h: extern int g; — to DECLARE it */
    printf("Global g: %d\n", g);

    return 0;
}
🔩
Bit Fields & Error Handling
Compact structs + errno
bitfields_errors.c
#include <stdio.h>
#include <errno.h>   /* errno — global error number */
#include <string.h>  /* strerror() */
#include <math.h>    /* sqrt, log etc. */

/* BIT FIELDS — specify exact number of bits for each member
   Saves memory when you only need a few bits per field
   Total size here: 1+3+4 = 8 bits = 1 byte (vs 12 bytes normally) */
struct Flags {
    unsigned int active   : 1;  /* 1 bit  — 0 or 1 only */
    unsigned int priority : 3;  /* 3 bits — 0 to 7 */
    unsigned int type     : 4;  /* 4 bits — 0 to 15 */
};

int main() {

    /* Using bit fields */
    struct Flags f;
    f.active   = 1;   /* set active flag */
    f.priority = 5;   /* priority level 5 (0-7) */
    f.type     = 3;   /* type code 3 (0-15) */

    printf("active=%d priority=%d type=%d\n",
           f.active, f.priority, f.type);
    printf("Size of Flags struct: %zu bytes\n", sizeof(f));

    /* ERROR HANDLING — errno and perror()
       errno is a global integer set by failed system calls
       perror() prints errno as a human-readable message */
    FILE *fp = fopen("nonexistent.txt", "r");
    if(fp == NULL) {
        printf("errno = %d\n", errno);            /* 2 = ENOENT */
        perror("fopen failed");                    /* human message */
        printf("Error: %s\n", strerror(errno));   /* get string */
    }

    /* Math errors — check errno after math functions */
    errno = 0;  /* reset before calling */
    double result = sqrt(-1.0);  /* invalid: sqrt of negative */
    if(errno != 0)
        perror("sqrt error");
    else
        printf("sqrt(-1) = %f\n", result);

    /* EXIT codes — return meaningful values from main() */
    /* EXIT_SUCCESS (0) = success, EXIT_FAILURE (1) = error */
    return EXIT_SUCCESS;  /* same as return 0; */
}
💡 Practice Problems

Problems & Solutions

100+ C programming problems with complete solutions. Perfect for beginners and intermediate learners to practice and understand concepts.

🔢
Basic Arithmetic Problems
Simple calculations and operations
area_of_circle.c
#include <stdio.h>
#define PI 3.14159

int main() {
    float radius, area;
    printf("Enter radius: ");
    scanf("%f", &radius);
    area = PI * radius * radius;
    printf("Area = %.2f\n", area);
    return 0;
}
celsius_to_fahrenheit.c
#include <stdio.h>

int main() {
    float celsius, fahrenheit;
    printf("Enter temperature in Celsius: ");
    scanf("%f", &celsius);
    fahrenheit = (celsius * 9/5) + 32;
    printf("%.2f°C = %.2f°F\n", celsius, fahrenheit);
    return 0;
}
swap_two_numbers.c
#include <stdio.h>

int main() {
    int a, b, temp;
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
    printf("Before swap: a=%d, b=%d\n", a, b);
    temp = a;
    a = b;
    b = temp;
    printf("After swap: a=%d, b=%d\n", a, b);
    return 0;
}
🔍
Search & Find Problems
Linear search, binary search algorithms
linear_search.c
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int n = 5, key, i, found = 0;
    
    printf("Enter number to search: ");
    scanf("%d", &key);
    
    for(i = 0; i < n; i++) {
        if(arr[i] == key) {
            printf("Found at position %d\n", i + 1);
            found = 1;
            break;
        }
    }
    if(!found) printf("Not found\n");
    return 0;
}
binary_search.c
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int n = 5, key, low = 0, high = n - 1, mid;
    
    printf("Enter number to search: ");
    scanf("%d", &key);
    
    while(low <= high) {
        mid = (low + high) / 2;
        if(arr[mid] == key) {
            printf("Found at position %d\n", mid + 1);
            return 0;
        } else if(arr[mid] < key) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    printf("Not found\n");
    return 0;
}
find_max_min.c
#include <stdio.h>

int main() {
    int arr[] = {12, 45, 23, 67, 89, 34};
    int n = 6, i, max, min;
    
    max = min = arr[0];
    
    for(i = 1; i < n; i++) {
        if(arr[i] > max) max = arr[i];
        if(arr[i] < min) min = arr[i];
    }
    
    printf("Maximum: %d\nMinimum: %d\n", max, min);
    return 0;
}
📊
Array Operations
Sum, average, reverse, sort arrays
array_sum_average.c
#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int n = 5, i, sum = 0;
    float average;
    
    for(i = 0; i < n; i++) {
        sum += arr[i];
    }
    
    average = (float)sum / n;
    printf("Sum: %d\nAverage: %.2f\n", sum, average);
    return 0;
}
reverse_array.c
#include <stdio.h>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = 5, i, temp;
    
    printf("Original: ");
    for(i = 0; i < n; i++) printf("%d ", arr[i]);
    
    for(i = 0; i < n/2; i++) {
        temp = arr[i];
        arr[i] = arr[n-i-1];
        arr[n-i-1] = temp;
    }
    
    printf("\nReversed: ");
    for(i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    return 0;
}
sort_array.c
#include <stdio.h>

int main() {
    int arr[] = {64, 34, 25, 12, 22};
    int n = 5, i, j, temp;
    
    for(i = 0; i < n-1; i++) {
        for(j = 0; j < n-i-1; j++) {
            if(arr[j] > arr[j+1]) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    
    printf("Sorted array: ");
    for(i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    return 0;
}
🔤
String Problems
Length, reverse, palindrome, count characters
string_length.c
#include <stdio.h>

int main() {
    char str[100];
    int length = 0;
    
    printf("Enter a string: ");
    scanf("%s", str);
    
    while(str[length] != '\0') {
        length++;
    }
    
    printf("Length: %d\n", length);
    return 0;
}
reverse_string.c
#include <stdio.h>
#include <string.h>

int main() {
    char str[100], temp;
    int i, len;
    
    printf("Enter a string: ");
    scanf("%s", str);
    
    len = strlen(str);
    
    for(i = 0; i < len/2; i++) {
        temp = str[i];
        str[i] = str[len-i-1];
        str[len-i-1] = temp;
    }
    
    printf("Reversed: %s\n", str);
    return 0;
}
string_palindrome.c
#include <stdio.h>
#include <string.h>

int main() {
    char str[100];
    int i, len, isPalindrome = 1;
    
    printf("Enter a string: ");
    scanf("%s", str);
    
    len = strlen(str);
    
    for(i = 0; i < len/2; i++) {
        if(str[i] != str[len-i-1]) {
            isPalindrome = 0;
            break;
        }
    }
    
    if(isPalindrome)
        printf("%s is a palindrome\n", str);
    else
        printf("%s is not a palindrome\n", str);
    
    return 0;
}
🔢
Mathematical Problems
Prime numbers, GCD, LCM, factorial
check_prime.c
#include <stdio.h>

int main() {
    int n, i, isPrime = 1;
    
    printf("Enter a number: ");
    scanf("%d", &n);
    
    if(n <= 1) isPrime = 0;
    
    for(i = 2; i * i <= n; i++) {
        if(n % i == 0) {
            isPrime = 0;
            break;
        }
    }
    
    if(isPrime)
        printf("%d is prime\n", n);
    else
        printf("%d is not prime\n", n);
    
    return 0;
}
gcd_lcm.c
#include <stdio.h>

int main() {
    int a, b, x, y, gcd, lcm;
    
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
    
    x = a;
    y = b;
    
    while(y != 0) {
        int temp = y;
        y = x % y;
        x = temp;
    }
    
    gcd = x;
    lcm = (a * b) / gcd;
    
    printf("GCD: %d\nLCM: %d\n", gcd, lcm);
    return 0;
}
factorial_recursive.c
#include <stdio.h>

long long factorial(int n) {
    if(n == 0 || n == 1)
        return 1;
    else
        return n * factorial(n - 1);
}

int main() {
    int n;
    printf("Enter n: ");
    scanf("%d", &n);
    printf("%d! = %lld\n", n, factorial(n));
    return 0;
}
🔄
Pattern Printing
Stars, numbers, pyramids
star_pyramid.c
#include <stdio.h>

int main() {
    int n, i, j;
    printf("Enter n: ");
    scanf("%d", &n);
    
    for(i = 1; i <= n; i++) {
        for(j = 1; j <= n - i; j++) printf(" ");
        for(j = 1; j <= 2 * i - 1; j++) printf("*");
        printf("\n");
    }
    return 0;
}
number_pattern.c
#include <stdio.h>

int main() {
    int n, i, j;
    printf("Enter n: ");
    scanf("%d", &n);
    
    for(i = 1; i <= n; i++) {
        for(j = 1; j <= i; j++) {
            printf("%d ", j);
        }
        printf("\n");
    }
    return 0;
}
diamond_pattern.c
#include <stdio.h>

int main() {
    int n, i, j;
    printf("Enter n: ");
    scanf("%d", &n);
    
    // Upper half
    for(i = 1; i <= n; i++) {
        for(j = 1; j <= n - i; j++) printf(" ");
        for(j = 1; j <= 2 * i - 1; j++) printf("*");
        printf("\n");
    }
    
    // Lower half
    for(i = n - 1; i >= 1; i--) {
        for(j = 1; j <= n - i; j++) printf(" ");
        for(j = 1; j <= 2 * i - 1; j++) printf("*");
        printf("\n");
    }
    return 0;
}
📈
Matrix Operations
Addition, multiplication, transpose
matrix_addition.c
#include <stdio.h>

int main() {
    int a[2][2] = {{1,2},{3,4}};
    int b[2][2] = {{5,6},{7,8}};
    int c[2][2], i, j;
    
    for(i = 0; i < 2; i++) {
        for(j = 0; j < 2; j++) {
            c[i][j] = a[i][j] + b[i][j];
        }
    }
    
    printf("Result:\n");
    for(i = 0; i < 2; i++) {
        for(j = 0; j < 2; j++) {
            printf("%d ", c[i][j]);
        }
        printf("\n");
    }
    return 0;
}
matrix_transpose.c
#include <stdio.h>

int main() {
    int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
    int t[3][3], i, j;
    
    for(i = 0; i < 3; i++) {
        for(j = 0; j < 3; j++) {
            t[j][i] = a[i][j];
        }
    }
    
    printf("Transpose:\n");
    for(i = 0; i < 3; i++) {
        for(j = 0; j < 3; j++) {
            printf("%d ", t[i][j]);
        }
        printf("\n");
    }
    return 0;
}
matrix_multiplication.c
#include <stdio.h>

int main() {
    int a[2][2] = {{1,2},{3,4}};
    int b[2][2] = {{5,6},{7,8}};
    int c[2][2] = {0}, i, j, k;
    
    for(i = 0; i < 2; i++) {
        for(j = 0; j < 2; j++) {
            for(k = 0; k < 2; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }
    
    printf("Product:\n");
    for(i = 0; i < 2; i++) {
        for(j = 0; j < 2; j++) {
            printf("%d ", c[i][j]);
        }
        printf("\n");
    }
    return 0;
}
📊
File Operations
Read, write, copy files
write_to_file.c
#include <stdio.h>

int main() {
    FILE *fp;
    char text[100];
    
    fp = fopen("sample.txt", "w");
    if(fp == NULL) {
        printf("Error opening file\n");
        return 1;
    }
    
    printf("Enter text to write: ");
    fgets(text, 100, stdin);
    fprintf(fp, "%s", text);
    
    fclose(fp);
    printf("Text written to file\n");
    return 0;
}
read_from_file.c
#include <stdio.h>

int main() {
    FILE *fp;
    char ch;
    
    fp = fopen("sample.txt", "r");
    if(fp == NULL) {
        printf("File not found\n");
        return 1;
    }
    
    printf("File contents:\n");
    while((ch = fgetc(fp)) != EOF) {
        printf("%c", ch);
    }
    
    fclose(fp);
    return 0;
}
count_words_lines.c
#include <stdio.h>
#include <ctype.h>

int main() {
    FILE *fp;
    char ch;
    int words = 0, lines = 0, chars = 0, inWord = 0;
    
    fp = fopen("sample.txt", "r");
    if(fp == NULL) {
        printf("File not found\n");
        return 1;
    }
    
    while((ch = fgetc(fp)) != EOF) {
        chars++;
        if(ch == '\n') lines++;
        if(isspace(ch)) {
            inWord = 0;
        } else if(inWord == 0) {
            inWord = 1;
            words++;
        }
    }
    
    printf("Characters: %d\nWords: %d\nLines: %d\n", chars, words, lines);
    fclose(fp);
    return 0;
}
🏗️
Structure Problems
Student records, employee data
student_records.c
#include <stdio.h>
#include <string.h>

struct Student {
    char name[50];
    int roll;
    float marks;
};

int main() {
    struct Student s[3];
    int i;
    
    for(i = 0; i < 3; i++) {
        printf("Enter name, roll, marks for student %d: ", i+1);
        scanf("%s %d %f", s[i].name, &s[i].roll, &s[i].marks);
    }
    
    printf("\nStudent Records:\n");
    for(i = 0; i < 3; i++) {
        printf("Name: %s, Roll: %d, Marks: %.2f\n", 
               s[i].name, s[i].roll, s[i].marks);
    }
    return 0;
}
employee_database.c
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[50];
    int id;
    float salary;
    char department[20];
} Employee;

int main() {
    Employee emp;
    
    printf("Enter employee details:\n");
    printf("Name: ");
    scanf("%s", emp.name);
    printf("ID: ");
    scanf("%d", &emp.id);
    printf("Salary: ");
    scanf("%f", &emp.salary);
    printf("Department: ");
    scanf("%s", emp.department);
    
    printf("\nEmployee Information:\n");
    printf("Name: %s\nID: %d\nSalary: %.2f\nDepartment: %s\n",
           emp.name, emp.id, emp.salary, emp.department);
    
    return 0;
}
book_library.c
#include <stdio.h>
#include <string.h>

typedef struct {
    char title[100];
    char author[50];
    int year;
    float price;
} Book;

int main() {
    Book books[2] = {
        {"C Programming", "Dennis Ritchie", 1978, 29.99},
        {"Data Structures", "Robert Kruse", 1987, 39.99}
    };
    
    int i;
    printf("Library Books:\n");
    for(i = 0; i < 2; i++) {
        printf("Title: %s\nAuthor: %s\nYear: %d\nPrice: $%.2f\n\n",
               books[i].title, books[i].author, 
               books[i].year, books[i].price);
    }
    return 0;
}
🔄
Recursion Problems
Tower of Hanoi, Fibonacci, sum digits
fibonacci_recursive.c
#include <stdio.h>

int fibonacci(int n) {
    if(n == 0) return 0;
    if(n == 1) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}

int main() {
    int n, i;
    printf("Enter n: ");
    scanf("%d", &n);
    
    printf("Fibonacci series: ");
    for(i = 0; i < n; i++) {
        printf("%d ", fibonacci(i));
    }
    printf("\n");
    return 0;
}
sum_digits_recursive.c
#include <stdio.h>

int sumDigits(int n) {
    if(n == 0) return 0;
    return (n % 10) + sumDigits(n / 10);
}

int main() {
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);
    printf("Sum of digits: %d\n", sumDigits(num));
    return 0;
}
tower_of_hanoi.c
#include <stdio.h>

void towerOfHanoi(int n, char from, char to, char aux) {
    if(n == 1) {
        printf("Move disk 1 from %c to %c\n", from, to);
        return;
    }
    towerOfHanoi(n-1, from, aux, to);
    printf("Move disk %d from %c to %c\n", n, from, to);
    towerOfHanoi(n-1, aux, to, from);
}

int main() {
    int n;
    printf("Enter number of disks: ");
    scanf("%d", &n);
    printf("Solution:\n");
    towerOfHanoi(n, 'A', 'C', 'B');
    return 0;
}
🎯
Advanced Problems
Sorting algorithms, binary conversion
selection_sort.c
#include <stdio.h>

int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int n = 5, i, j, min_idx, temp;
    
    for(i = 0; i < n-1; i++) {
        min_idx = i;
        for(j = i+1; j < n; j++) {
            if(arr[j] < arr[min_idx]) {
                min_idx = j;
            }
        }
        temp = arr[min_idx];
        arr[min_idx] = arr[i];
        arr[i] = temp;
    }
    
    printf("Sorted array: ");
    for(i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    return 0;
}
decimal_to_binary.c
#include <stdio.h>

int main() {
    int decimal, binary[32], i = 0;
    
    printf("Enter decimal number: ");
    scanf("%d", &decimal);
    
    if(decimal == 0) {
        printf("Binary: 0\n");
        return 0;
    }
    
    while(decimal > 0) {
        binary[i] = decimal % 2;
        decimal = decimal / 2;
        i++;
    }
    
    printf("Binary: ");
    for(i = i-1; i >= 0; i--) {
        printf("%d", binary[i]);
    }
    printf("\n");
    return 0;
}
merge_two_arrays.c
#include <stdio.h>

int main() {
    int arr1[] = {1, 3, 5, 7};
    int arr2[] = {2, 4, 6, 8};
    int n1 = 4, n2 = 4, merged[8];
    int i = 0, j = 0, k = 0;
    
    while(i < n1 && j < n2) {
        if(arr1[i] < arr2[j]) {
            merged[k++] = arr1[i++];
        } else {
            merged[k++] = arr2[j++];
        }
    }
    
    while(i < n1) merged[k++] = arr1[i++];
    while(j < n2) merged[k++] = arr2[j++];
    
    printf("Merged array: ");
    for(i = 0; i < n1+n2; i++) printf("%d ", merged[i]);
    printf("\n");
    return 0;
}
🧪 Test Yourself

Full Course Quiz — 20 Questions

Test your understanding of all C programming topics. Select an answer to see instant feedback.

Question 1 of 20 Score: 0 / 20