โ† All units

๐Ÿงฑ Unit 1 ยท Basics of C Programming

What a computer is, how we solve problems, and the building blocks of every C program

1. Introduction: Computer Systems

A computer works like a kitchen. Vegetables come in (input), the cook chops and cooks them (process), the fridge keeps things for later (storage), and the food is served (output).

A computer is an electronic machine that takes data, works on it following instructions, stores it, and gives results. It's fast, accurate, never gets tired, and can remember a lot, but it can't think for itself. It only does what we tell it.

Block diagram of a computer

INPUT UNITkeyboard, mouse CPU (the brain) Control Unit (CU)the boss: gives orders ALUdoes maths + comparisons Main Memory (RAM)short-term memory OUTPUT UNITmonitor, printer Secondary Storage (HDD/SSD)
PartJobKitchen version
Input unitTakes data into the computerVegetables arriving
CPU: Control UnitControls and directs every other partHead chef giving orders
CPU: ALUArithmetic (+ - * /) and logic (>, <, ==)Cook chopping and mixing
Memory (RAM)Holds data while working; erased when power goes offKitchen table
Secondary storageKeeps data permanentlyFridge
Output unitShows resultsServing the food
Bit = one 0 or 1. Byte = 8 bits. 1 KB = 1024 bytes, 1 MB = 1024 KB, 1 GB = 1024 MB.

File: 01_computer_system_ipo.c

/*
 * Program 1: Computer System - Input, Process, Output, Storage
 * ------------------------------------------------------------
 * Real-life story: A computer works like a KITCHEN.
 *   INPUT   = vegetables come in      (keyboard, mouse)
 *   PROCESS = the cook chops & cooks  (CPU)
 *   STORAGE = the fridge keeps things (memory / RAM / hard disk)
 *   OUTPUT  = the food is served      (monitor, printer)
 *
 * This program acts out those 4 jobs to find the area of a room.
 */
#include <stdio.h>

int main() {
    /* INPUT: normally from the keyboard, here we just give the values */
    int length = 12;
    int width = 10;
    printf("INPUT   : length = %d feet, width = %d feet\n", length, width);

    /* PROCESS: the CPU (the computer's brain) does the maths */
    int area = length * width;
    printf("PROCESS : CPU calculates %d x %d\n", length, width);

    /* STORAGE: the answer is kept in memory inside the box called "area" */
    printf("STORAGE : answer is kept in memory (box 'area')\n");

    /* OUTPUT: show the answer on the monitor */
    printf("OUTPUT  : area of the room = %d square feet\n", area);

    return 0;
}

Output

INPUT   : length = 12 feet, width = 10 feet
PROCESS : CPU calculates 12 x 10
STORAGE : answer is kept in memory (box 'area')
OUTPUT  : area of the room = 120 square feet
Draw the block diagram (Input โ†’ CPU [CU, ALU, Memory] โ†’ Output, plus secondary storage) and explain each unit's job in one or two lines. Add the characteristics of a computer: speed, accuracy, diligence, storage, versatility.

2. Hardware and Software Concepts

Your body is hardware: you can touch it. Your thoughts and knowledge are software: you can't touch them, but they tell your body what to do.

๐Ÿ–ฅ๏ธ Hardware

The physical parts you can touch: keyboard, mouse, CPU, RAM, hard disk, monitor, printer.

๐Ÿ’ฟ Software

A set of programs (instructions) that tell the hardware what to do. You can't touch it.

Types of software

TypeWhat it doesExamples
System softwareRuns the computer itself and helps other programs runOperating system (Windows, macOS, Linux), compilers, device drivers
Application softwareDoes a job for the userMS Word, Chrome, games, calculator
Utility softwareKeeps the computer healthyAntivirus, disk cleaner, zip tools

Translators: a kind of system software

TranslatorConvertsHow
CompilerHigh-level โ†’ machine codeThe whole program at once, then runs it (C uses this)
InterpreterHigh-level โ†’ machine codeOne line at a time (Python, BASIC)
AssemblerAssembly โ†’ machine codeTurns short words like ADD, MOV into 0s and 1s
๐ŸŽฎ Sort it: hardware or software?

Hardware = physical parts; software = programs. Software has 2 main types: system (OS, compiler) and application (Word, browser). Know compiler vs interpreter: a compiler translates the whole program at once (faster to run), an interpreter goes line by line (easier to debug).

3. Problem Solving: Algorithm & Pseudo code

To make tea you follow steps: boil water โ†’ add tea powder โ†’ add milk and sugar โ†’ pour into a cup. Steps that are clear, in order, and finish at the end are an algorithm.

Steps to solve any problem

  1. Understand the problem (what goes in, what comes out?)
  2. Plan it: write the algorithm, pseudo code or flowchart
  3. Write the program (coding)
  4. Test and fix mistakes (debugging)
  5. Document it so others understand

Properties of a good algorithm

PropertyMeaning
InputTakes zero or more inputs
OutputGives at least one result
DefinitenessEach step is clear, with no confusion
FinitenessIt must stop after a limited number of steps
EffectivenessEach step is simple enough to actually do

Algorithm

Step-by-step instructions in plain English.

Step 1: Start
Step 2: Read a, b, c
Step 3: If a>b and a>c, largest = a
Step 4: Else if b>c, largest = b
Step 5: Else largest = c
Step 6: Print largest
Step 7: Stop

Pseudo code

"Fake code": half English, half program. No strict rules.

BEGIN
 READ a, b, c
 IF a>b AND a>c THEN
  largest โ† a
 ELSE IF b>c THEN
  largest โ† b
 ELSE largest โ† c
 PRINT largest
END
๐Ÿ‘ฃ Run the algorithm yourself
a b c

  

File: 02_algorithm_largest_of_three.c

/*
 * Program 2: Problem Solving - Algorithm -> Pseudo code -> C
 * ----------------------------------------------------------
 * Real-life story: Three friends measure their height.
 * Who is the tallest? Let's solve it step by step.
 *
 * ALGORITHM (steps in plain English):
 *   Step 1: Start
 *   Step 2: Read three numbers a, b, c
 *   Step 3: If a is bigger than b AND a is bigger than c, a is the largest
 *   Step 4: Else if b is bigger than c, b is the largest
 *   Step 5: Else c is the largest
 *   Step 6: Print the largest
 *   Step 7: Stop
 *
 * PSEUDO CODE (half English, half code):
 *   BEGIN
 *     READ a, b, c
 *     IF a > b AND a > c THEN largest = a
 *     ELSE IF b > c THEN largest = b
 *     ELSE largest = c
 *     PRINT largest
 *   END
 */
#include <stdio.h>

int main() {
    int a = 140, b = 152, c = 147;   /* heights in cm (Step 2) */
    int largest;

    if (a > b && a > c) {            /* Step 3 */
        largest = a;
    } else if (b > c) {              /* Step 4 */
        largest = b;
    } else {                         /* Step 5 */
        largest = c;
    }

    printf("Heights: %d, %d, %d\n", a, b, c);
    printf("Tallest friend is %d cm\n", largest);   /* Step 6 */
    return 0;                                       /* Step 7 */
}

Output

Heights: 140, 152, 147
Tallest friend is 152 cm
Define algorithm, give its 5 properties, then write an algorithm and pseudo code for a simple problem (largest of 3, sum of N numbers, even/odd). Pseudo code has no fixed syntax. It's for people, not computers.

4. Flowchart

A flowchart is like a map of the algorithm. Instead of words, you follow shapes and arrows with your finger.
ShapeMeaning
โฌญ Oval (terminal)Start / Stop
โ–ฑ ParallelogramInput / Output (Read, Print)
โ–ญ RectangleProcess (calculation)
โ—‡ DiamondDecision (Yes / No)
โ†’ Arrow (flow line)Direction of flow
โ—‹ Circle (connector)Joins parts of the chart
Start Read n n % 2 == 0 ? Print "Even" Print "Odd" Stop Yes No
๐Ÿฌ Follow the flowchart
Number of sweets:

  

File: 03_flowchart_even_odd.c

/*
 * Program 3: Flowchart example - Even or Odd
 * ------------------------------------------
 * Real-life story: You have some sweets. Can you share them
 * equally between 2 friends with nothing left over?
 * If yes, the number is EVEN. If 1 is left over, it is ODD.
 *
 * FLOWCHART (shapes):
 *   ( Start )                 <- oval   = start / stop
 *       |
 *   / Read n /                <- parallelogram = input / output
 *       |
 *   < n % 2 == 0 ? >          <- diamond = decision (yes / no)
 *     yes |     | no
 *   / "Even" /  / "Odd" /
 *        \     /
 *       ( Stop )
 */
#include <stdio.h>

int main() {
    int sweets[] = {8, 13, 20, 7};
    int i;

    for (i = 0; i < 4; i++) {
        int n = sweets[i];
        if (n % 2 == 0) {                        /* the diamond box */
            printf("%2d sweets -> EVEN (shared equally)\n", n);
        } else {
            printf("%2d sweets -> ODD  (1 sweet left over)\n", n);
        }
    }
    return 0;
}

Output

 8 sweets -> EVEN (shared equally)
13 sweets -> ODD  (1 sweet left over)
20 sweets -> EVEN (shared equally)
 7 sweets -> ODD  (1 sweet left over)
Draw the flowchart symbols table. Advantages: easy to understand, helps find mistakes, good for documentation. Disadvantages: hard to draw for big programs, and hard to change.

5. Computer Languages: Machine, Symbolic, High-level

You speak English. The computer only understands 0 and 1 (light OFF, light ON). We need a language both sides can use, plus a translator in the middle.
Machine languageSymbolic (Assembly) languageHigh-level language
Looks like10110000 00000010MOV AX, 2
ADD AX, 3
sum = 2 + 3;
Generation1st2nd3rd and later
TranslatorNone neededAssemblerCompiler / Interpreter
SpeedFastestFastA little slower
Easy to learn?Very hardHardEasy
Portable? (runs on other machines)NoNoYes
ExamplesBinary code8086 assemblyC, C++, Java, Python
C is sometimes called a middle-level language. It's easy to read like a high-level language, but it can also work close to the hardware (bits, memory addresses) like assembly.
๐Ÿ’ก See a number the way the machine does
Number (0โ€“255):

File: 04_languages_binary.c

/*
 * Program 4: Computer Languages - What the machine really sees
 * ------------------------------------------------------------
 * Real-life story: You speak English, but the computer only
 * understands 0 and 1 (light OFF and light ON).
 *
 *   High level  (C)        : sum = 2 + 3;      <- easy for us
 *   Assembly    (symbolic) : MOV AX, 2
 *                            ADD AX, 3         <- short words
 *   Machine     (binary)   : 10110000 00000010 <- only 0s and 1s
 *
 * A COMPILER translates C into machine language for us.
 * This program prints numbers the way the machine stores them: in binary.
 */
#include <stdio.h>

/* print the 8 bits (0/1 lights) of a small number */
void printBinary(int n) {
    int bit;
    for (bit = 7; bit >= 0; bit--) {
        printf("%d", (n >> bit) & 1);   /* look at one light at a time */
    }
}

int main() {
    int numbers[] = {2, 3, 5, 10, 255};
    int i;

    printf("We see  ->  Machine sees\n");
    for (i = 0; i < 5; i++) {
        printf("%5d   ->  ", numbers[i]);
        printBinary(numbers[i]);
        printf("\n");
    }

    int sum = 2 + 3;                    /* one easy line of high-level C */
    printf("\n2 + 3 = %d  (binary ", sum);
    printBinary(sum);
    printf(")\n");
    return 0;
}

Output

We see  ->  Machine sees
    2   ->  00000010
    3   ->  00000011
    5   ->  00000101
   10   ->  00001010
  255   ->  11111111

2 + 3 = 5  (binary 00000101)
Compare the 3 language types (table above). Machine language is binary and depends on the machine. Assembly uses mnemonics (short words like ADD, MOV) and needs an assembler. High-level is English-like and portable, and needs a compiler or interpreter.

6. Structure of a C Program

A C program is like a letter. It has a heading, an address, the main message and a signature, always in the same order.
#SectionWhat goes hereExample
1DocumentationComments: name, purpose, author/* Area of circle */
2LinkHeader files to include#include <stdio.h>
3DefinitionSymbolic constants#define PI 3.14
4Global declarationVariables/functions used everywhereint total;
5main() functionDeclaration part + executable part. Execution starts here.int main() { ... }
6Sub-programUser-defined functionsvoid sayBye() { ... }
Every statement ends with a semicolon ;, like a full stop in English. Curly braces { } group statements together, like a box.

File: 05_structure_of_c_program.c

/*
 * ===== 1. DOCUMENTATION SECTION =====
 * Program 5: Structure of a C program
 * Real-life story: A C program is like a LETTER.
 *   It has a heading, the address, the main message, and a signature.
 *   Every C program has the same parts in the same order.
 * Author: Learner   Date: today
 */

/* ===== 2. LINK SECTION: bring in ready-made tools ===== */
#include <stdio.h>

/* ===== 3. DEFINITION SECTION: give names to fixed values ===== */
#define SCHOOL "Sunshine School"

/* ===== 4. GLOBAL DECLARATION SECTION: things everyone can use ===== */
int totalStudents = 40;
void sayBye(void);              /* function prototype (a promise) */

/* ===== 5. MAIN FUNCTION SECTION: the program starts HERE ===== */
int main() {
    /* (a) declaration part */
    int present = 37;

    /* (b) executable part */
    printf("Welcome to %s\n", SCHOOL);
    printf("Present today: %d out of %d\n", present, totalStudents);
    sayBye();

    return 0;                   /* 0 means "everything went fine" */
}

/* ===== 6. SUB-PROGRAM SECTION: our own helper functions ===== */
void sayBye(void) {
    printf("Bye! See you tomorrow.\n");
}

Output

Welcome to Sunshine School
Present today: 37 out of 40
Bye! See you tomorrow.
List the 6 sections in order with one example each. Only main() is compulsory. Execution always begins at main().

7. Data Types

Boxes come in different sizes. A ring box (char) is tiny, a shoe box (int) is medium, a suitcase (double) is big. Pick the box that fits what you want to keep!

Kinds of data types

GroupTypes
Basic (primary)int, char, float, double, void
Derivedarray, pointer, function
User-definedstruct, union, enum, typedef

Basic types (typical 64-bit computer)

TypeSizeRangeFormatExample
char1 byte-128 to 127%c'A'
unsigned char1 byte0 to 255%c200
short int2 bytes-32,768 to 32,767%hd1000
int4 bytes-2,147,483,648 to 2,147,483,647%d25
unsigned int4 bytes0 to 4,294,967,295%u40000
long int4 or 8 bytesdepends on the computer%ld123456L
float4 bytesabout 6 correct digits%f3.14f
double8 bytesabout 15 correct digits%lf3.14159265
void-"nothing"-void main()
Sizes can change from computer to computer. Old 16-bit Turbo C has a 2-byte int (range -32768 to 32767). Many textbooks use that. Use sizeof to check your own machine.
๐Ÿ“ฆ Which box do I need?

File: 06_data_types_sizeof.c

/*
 * Program 6: Data Types and their sizes
 * -------------------------------------
 * Real-life story: Boxes come in different sizes.
 *   A ring box (char) is tiny, a shoe box (int) is medium,
 *   a suitcase (double) is big. Pick the box that fits your thing!
 *
 * sizeof tells how many BYTES a box uses. 1 byte = 8 bits.
 */
#include <stdio.h>
#include <limits.h>   /* gives INT_MAX, CHAR_MAX ... */
#include <float.h>    /* gives FLT_MAX, DBL_MAX ... */

int main() {
    char   grade  = 'A';
    int    age    = 10;
    float  height = 4.5f;
    double pi     = 3.14159265358979;

    printf("Type          Size   Example\n");
    printf("char          %zu B    %c\n",  sizeof(char), grade);
    printf("int           %zu B    %d\n",  sizeof(int), age);
    printf("float         %zu B    %.1f\n", sizeof(float), height);
    printf("double        %zu B    %.10f\n", sizeof(double), pi);
    printf("short int     %zu B\n", sizeof(short));
    printf("long int      %zu B\n", sizeof(long));
    printf("long long     %zu B\n", sizeof(long long));
    printf("long double   %zu B\n", sizeof(long double));

    printf("\nBiggest and smallest values:\n");
    printf("char  : %d to %d\n", CHAR_MIN, CHAR_MAX);
    printf("unsigned char : 0 to %d\n", UCHAR_MAX);
    printf("short : %d to %d\n", SHRT_MIN, SHRT_MAX);
    printf("int   : %d to %d\n", INT_MIN, INT_MAX);
    printf("unsigned int  : 0 to %u\n", UINT_MAX);
    printf("float : up to about %e (6 digits correct)\n", FLT_MAX);
    printf("double: up to about %e (15 digits correct)\n", DBL_MAX);
    return 0;
}

Output (on this Mac)

Type          Size   Example
char          1 B    A
int           4 B    10
float         4 B    4.5
double        8 B    3.1415926536
short int     2 B
long int      8 B
long long     8 B
long double   8 B

Biggest and smallest values:
char  : -128 to 127
unsigned char : 0 to 255
short : -32768 to 32767
int   : -2147483648 to 2147483647
unsigned int  : 0 to 4294967295
float : up to about 3.402823e+38 (6 digits correct)
double: up to about 1.797693e+308 (15 digits correct)
Classify data types (primary, derived, user-defined) and give the size, range and format specifier table. Signed holds negative and positive numbers; unsigned holds only positive ones, which doubles the positive range.

8. Format Specifiers

A school form has blanks: "Name: ____ Age: ____". In printf, %d, %c, %f and %s are those blanks, and each one accepts only its own kind of value.
๐Ÿงช printf playground
Value:

  

File: 07_format_specifiers.c

/*
 * Program 7: Format Specifiers - the blanks inside printf
 * -------------------------------------------------------
 * Real-life story: A form at school has blanks:
 *   "Name: ____  Age: ____  Marks: ____"
 * %d, %f, %c, %s are those blanks. Each blank accepts one type.
 */
#include <stdio.h>

int main() {
    char   name[] = "Ravi";
    char   section = 'B';
    int    age = 11;
    float  marks = 92.5f;
    double bigMoney = 123456.789;
    unsigned int steps = 4000000000u;
    long   stars = 1234567890L;

    printf("%%s  string        : %s\n", name);
    printf("%%c  character     : %c\n", section);
    printf("%%d  integer       : %d\n", age);
    printf("%%f  float         : %f\n", marks);
    printf("%%.1f 1 decimal    : %.1f\n", marks);
    printf("%%lf double        : %lf\n", bigMoney);
    printf("%%e  science style : %e\n", bigMoney);
    printf("%%u  unsigned      : %u\n", steps);
    printf("%%ld long          : %ld\n", stars);
    printf("%%o  octal of 11   : %o\n", age);
    printf("%%x  hex of 255    : %x\n", 255);
    printf("%%5d width 5       : [%5d]\n", age);
    printf("%%-5d left aligned : [%-5d]\n", age);
    printf("%%%%  percent sign  : 100%%\n");
    return 0;
}

Output

%s  string        : Ravi
%c  character     : B
%d  integer       : 11
%f  float         : 92.500000
%.1f 1 decimal    : 92.5
%lf double        : 123456.789000
%e  science style : 1.234568e+05
%u  unsigned      : 4000000000
%ld long          : 1234567890
%o  octal of 11   : 13
%x  hex of 255    : ff
%5d width 5       : [   11]
%-5d left aligned : [11   ]
%%  percent sign  : 100%
%d int, %f float, %lf double, %c char, %s string, %u unsigned, %ld long, %o octal, %x hex, %e exponent, %% prints a % sign. Width and precision look like this: %8.2f.

9. Constants

Your birthday never changes, and a week always has 7 days. Those are constants. Your age changes every year, so that's a variable.
Type of constantExamplesRule
Integer10, -45, 0No decimal point
Octal integer017 (=15)Starts with 0
Hexadecimal integer0x1F (=31)Starts with 0x
Real (floating)3.14, -0.5, 2.5e3Has a decimal point or an exponent
Character'A', '9', '\n'One character in single quotes
String"Hello", "A"In double quotes, ends with a hidden '\0'

Making a named constant

#define PI 3.14
Preprocessor swaps every PI with 3.14 before compiling. No =, no ;, no type.
const float PI = 3.14;
A real variable that is locked. It has a type, and the compiler stops you if you try to change it.

Escape sequences (backslash characters)

CodeMeaningCodeMeaning
\nNew line\tTab
\\Backslash\"Double quote
\'Single quote\0Null (end of string)
\aBeep (alert)\bBackspace

File: 08_constants.c

/*
 * Program 8: Constants - values that never change
 * -----------------------------------------------
 * Real-life story: Your birthday never changes. A week always has 7 days.
 * Such fixed values are CONSTANTS. Your age changes, so it's a VARIABLE.
 *
 * 3 ways to make constants:
 *   1. Literal          : write the value directly, like 7 or 'A'
 *   2. #define          : a name that is swapped before compiling
 *   3. const keyword    : a variable that is locked
 */
#include <stdio.h>

#define DAYS_IN_WEEK 7          /* way 2: #define (no = and no ;) */
#define PI 3.14159

int main() {
    const int birthYear = 2015; /* way 3: const - locked box */
    /* birthYear = 2020;   <- ERROR! You cannot change a const */

    printf("Integer constant      : %d\n", 100);        /* way 1: literals */
    printf("Real (float) constant : %.2f\n", 9.75);
    printf("Character constant    : %c\n", 'Z');
    printf("String constant       : %s\n", "Hello");
    printf("Octal constant 017    : %d\n", 017);       /* starts with 0  */
    printf("Hex constant 0x1F     : %d\n", 0x1F);      /* starts with 0x */
    printf("Escape \\t gives a tab:[\t]\n");

    printf("\nDays in 3 weeks       : %d\n", 3 * DAYS_IN_WEEK);
    printf("Area of circle r=2    : %.2f\n", PI * 2 * 2);
    printf("Born in               : %d\n", birthYear);
    return 0;
}

Output

Integer constant      : 100
Real (float) constant : 9.75
Character constant    : Z
String constant       : Hello
Octal constant 017    : 15
Hex constant 0x1F     : 31
Escape \t gives a tab:[	]

Days in 3 weeks       : 21
Area of circle r=2    : 12.57
Born in               : 2015
Constants are fixed values. There are 2 groups: numeric (integer, real) and character (single char, string). Know the 2 ways to name them (#define vs const) and the escape sequences.

10. Enumeration Constants (enum)

A traffic light has only 3 colours. Instead of remembering "0 means red, 1 means yellow, 2 means green", we give those numbers names.
enum Light { RED, YELLOW, GREEN };      // RED=0, YELLOW=1, GREEN=2
enum Day   { MON = 1, TUE, WED };       // MON=1, TUE=2, WED=3
enum Coin  { ONE = 1, FIVE = 5, TEN = 10 };
๐Ÿ”ข Build your own enum
Names (comma-separated):

File: 09_enum_constants.c

/*
 * Program 9: Enumeration Constants (enum)
 * ---------------------------------------
 * Real-life story: A traffic light has only 3 colours.
 * Instead of remembering "0 means red, 1 means yellow, 2 means green",
 * we give the numbers NAMES using enum.
 *
 * enum names get numbers automatically: 0, 1, 2 ...
 */
#include <stdio.h>

enum Light { RED, YELLOW, GREEN };            /* RED=0, YELLOW=1, GREEN=2 */
enum Day { MON = 1, TUE, WED, THU, FRI, SAT, SUN };  /* start from 1 */
enum Coin { ONE = 1, TWO = 2, FIVE = 5, TEN = 10 };  /* choose your own */

int main() {
    enum Light now = GREEN;

    printf("RED = %d, YELLOW = %d, GREEN = %d\n", RED, YELLOW, GREEN);

    if (now == GREEN) {
        printf("Light is GREEN -> Go!\n");
    }

    printf("WED is day number %d, SUN is day number %d\n", WED, SUN);
    printf("Coins: %d + %d + %d + %d = Rs %d\n", ONE, TWO, FIVE, TEN, ONE + TWO + FIVE + TEN);
    return 0;
}

Output

RED = 0, YELLOW = 1, GREEN = 2
Light is GREEN -> Go!
WED is day number 3, SUN is day number 7
Coins: 1 + 2 + 5 + 10 = Rs 18
An enum is a user-defined type made of named integer constants. Syntax: enum name { A, B, C };. Values start at 0 unless you set them.

11. Keywords

In a game, words like "jump" and "run" are special commands, so you can't name your pet "jump". C has 32 special words that you can't use as names.
โœ… Is this a valid variable name?

Rules for identifiers (names)

  1. Use only letters, digits and underscore _
  2. The first character must be a letter or _ (not a digit)
  3. No spaces and no special symbols like @, #, $
  4. It must not be a keyword
  5. Upper and lower case are different: Age and age are two separate names

File: 10_keywords.c

/*
 * Program 10: Keywords - C's reserved words
 * -----------------------------------------
 * Real-life story: In a game, some words are special commands
 * like "jump" or "run". You can't name your pet "jump"!
 * In C, 32 words are special. You can't use them as variable names.
 *
 *   int if = 5;      <- ERROR, "if" is a keyword
 *   int age = 5;     <- OK
 */
#include <stdio.h>

int main() {
    const char *keywords[32] = {
        "auto", "break", "case", "char", "const", "continue", "default", "do",
        "double", "else", "enum", "extern", "float", "for", "goto", "if",
        "int", "long", "register", "return", "short", "signed", "sizeof", "static",
        "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while"
    };
    int i;

    printf("The 32 keywords of C:\n");
    for (i = 0; i < 32; i++) {
        printf("%-10s", keywords[i]);
        if ((i + 1) % 4 == 0) {      /* new line after every 4 words */
            printf("\n");
        }
    }

    /* using a few keywords for real */
    unsigned int apples = 5;
    const float price = 2.5f;
    printf("\nUsing keywords: %u apples cost %.1f\n", apples, apples * price);
    return 0;
}

Output

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

Using keywords: 5 apples cost 12.5
Keywords are reserved words with a fixed meaning. ANSI C has 32 of them, all lowercase. A keyword can't be used as an identifier. Know the identifier rules too.

12. Operators

Operators are action words. + means "add", > means "is bigger?", and && means "both true?". The values they work on are called operands.
TypeOperatorsExample (a=10, b=3)
Arithmetic+ - * / %a % b = 1
Relational< > <= >= == !=a > b โ†’ 1
Logical&& || !(a>5 && b>5) โ†’ 0
Assignment= += -= *= /= %=a += 2 โ†’ 12
Increment/Decrement++ --a++ โ†’ 11
Bitwise& | ^ ~ << >>a & b = 2
Conditional (ternary)? :a>b ? a : b โ†’ 10
Specialsizeof, comma ,, & (address), * (pointer)sizeof(a) = 4
By number of operands
Unary (1): -a, ++a, !a
Binary (2): a + b
Ternary (3): a ? b : c
a++ vs ++a
b = a++; โ†’ b gets the OLD a, then a goes up
b = ++a; โ†’ a goes up FIRST, then b gets it
๐Ÿงฎ Operator calculator
a b

  
โž• a++ vs ++a step by step
a starts at

  

Arithmetic, relational, logical

File: 11_operators_arith_rel_logical.c

/*
 * Program 11: Arithmetic, Relational and Logical Operators
 * --------------------------------------------------------
 * Real-life story: Riya scored 45 in Maths and 38 in Science.
 *   Arithmetic -> do maths     (+ - * / %)
 *   Relational -> compare      (> < >= <= == !=)   answer is 1 (true) or 0 (false)
 *   Logical    -> join answers (&& AND, || OR, ! NOT)
 */
#include <stdio.h>

int main() {
    int maths = 45, science = 38;

    printf("--- Arithmetic ---\n");
    printf("total      = %d + %d = %d\n", maths, science, maths + science);
    printf("difference = %d - %d = %d\n", maths, science, maths - science);
    printf("double it  = %d * 2  = %d\n", maths, maths * 2);
    printf("half       = %d / 2  = %d\n", maths, maths / 2);
    printf("remainder  = %d %% 2  = %d\n", maths, maths % 2);

    printf("\n--- Relational (1 = true, 0 = false) ---\n");
    printf("maths >  science : %d\n", maths > science);
    printf("maths <  science : %d\n", maths < science);
    printf("maths >= 45      : %d\n", maths >= 45);
    printf("science <= 35    : %d\n", science <= 35);
    printf("maths == 45      : %d\n", maths == 45);
    printf("maths != science : %d\n", maths != science);

    printf("\n--- Logical ---\n");
    printf("pass both (>=40 && >=40) : %d\n", maths >= 40 && science >= 40);
    printf("pass any  (>=40 || >=40) : %d\n", maths >= 40 || science >= 40);
    printf("NOT passed science !(>=40): %d\n", !(science >= 40));
    return 0;
}

Output

--- Arithmetic ---
total      = 45 + 38 = 83
difference = 45 - 38 = 7
double it  = 45 * 2  = 90
half       = 45 / 2  = 22
remainder  = 45 % 2  = 1

--- Relational (1 = true, 0 = false) ---
maths >  science : 1
maths <  science : 0
maths >= 45      : 1
science <= 35    : 0
maths == 45      : 1
maths != science : 1

--- Logical ---
pass both (>=40 && >=40) : 0
pass any  (>=40 || >=40) : 1
NOT passed science !(>=40): 1

Assignment, increment, decrement

File: 12_operators_assign_incdec.c

/*
 * Program 12: Assignment and Increment / Decrement Operators
 * ----------------------------------------------------------
 * Real-life story: Your piggy bank has Rs 100.
 *   =   put money in a fresh box
 *   +=  add more money,   -= take some out
 *   *=  money doubles,    /= share it
 *   ++  add exactly 1,    -- take away exactly 1
 */
#include <stdio.h>

int main() {
    int money = 100;            /* = puts 100 in the box */
    printf("Start          : %d\n", money);

    money += 50;  printf("money += 50    : %d\n", money);   /* money = money + 50 */
    money -= 30;  printf("money -= 30    : %d\n", money);   /* money = money - 30 */
    money *= 2;   printf("money *= 2     : %d\n", money);   /* money = money * 2  */
    money /= 4;   printf("money /= 4     : %d\n", money);   /* money = money / 4  */
    money %= 7;   printf("money %%= 7     : %d\n", money);  /* money = money % 7  */

    printf("\n--- ++ and -- ---\n");
    int a = 5, b;

    b = a++;   /* POST: first give old value to b, THEN add 1 to a */
    printf("b = a++  ->  b = %d, a = %d\n", b, a);

    b = ++a;   /* PRE: first add 1 to a, THEN give it to b */
    printf("b = ++a  ->  b = %d, a = %d\n", b, a);

    b = a--;
    printf("b = a--  ->  b = %d, a = %d\n", b, a);

    b = --a;
    printf("b = --a  ->  b = %d, a = %d\n", b, a);
    return 0;
}

Output

Start          : 100
money += 50    : 150
money -= 30    : 120
money *= 2     : 240
money /= 4     : 60
money %= 7     : 4

--- ++ and -- ---
b = a++  ->  b = 5, a = 6
b = ++a  ->  b = 7, a = 7
b = a--  ->  b = 7, a = 6
b = --a  ->  b = 5, a = 5

Bitwise, conditional, sizeof, comma

aba & ba | ba ^ b
00000
01011
10011
11110

File: 13_operators_bitwise_special.c

/*
 * Program 13: Bitwise, Conditional, sizeof and Comma Operators
 * ------------------------------------------------------------
 * Real-life story: Think of 4 light switches in a row: 0 = OFF, 1 = ON.
 *   12 is 1100 (first two lights on)
 *   10 is 1010
 * Bitwise operators work on each switch one by one.
 *
 * Conditional ( ? : ) is a tiny if-else in one line:
 *   condition ? value_if_true : value_if_false
 */
#include <stdio.h>

int main() {
    int a = 12, b = 10;    /* 12 = 1100, 10 = 1010 */

    printf("--- Bitwise (a=12 is 1100, b=10 is 1010) ---\n");
    printf("a & b  (AND: both ON)    = %d  (1000)\n", a & b);
    printf("a | b  (OR: any ON)      = %d (1110)\n", a | b);
    printf("a ^ b  (XOR: different)  = %d  (0110)\n", a ^ b);
    printf("~a     (NOT: flip all)   = %d\n", ~a);
    printf("a << 1 (shift left = x2) = %d\n", a << 1);
    printf("a >> 2 (shift right = /4)= %d\n", a >> 2);

    printf("\n--- Conditional ? : ---\n");
    int age = 15;
    printf("Age %d -> %s\n", age, age >= 18 ? "can vote" : "too young to vote");
    int bigger = (a > b) ? a : b;
    printf("Bigger of %d and %d is %d\n", a, b, bigger);

    printf("\n--- sizeof ---\n");
    printf("sizeof(int) = %zu bytes, sizeof(a) = %zu bytes\n", sizeof(int), sizeof(a));

    printf("\n--- Comma ---\n");
    int x, y;
    x = (y = 3, y + 2);    /* do y = 3 first, then x gets the LAST value (y + 2) */
    printf("x = (y = 3, y + 2) -> x = %d, y = %d\n", x, y);
    return 0;
}

Output

--- Bitwise (a=12 is 1100, b=10 is 1010) ---
a & b  (AND: both ON)    = 8  (1000)
a | b  (OR: any ON)      = 14 (1110)
a ^ b  (XOR: different)  = 6  (0110)
~a     (NOT: flip all)   = -13
a << 1 (shift left = x2) = 24
a >> 2 (shift right = /4)= 3

--- Conditional ? : ---
Age 15 -> too young to vote
Bigger of 12 and 10 is 12

--- sizeof ---
sizeof(int) = 4 bytes, sizeof(a) = 4 bytes

--- Comma ---
x = (y = 3, y + 2) -> x = 5, y = 3
List the 8 types of operators with an example each. In C, relational and logical results are 1 (true) or 0 (false). && and || short-circuit: if the left side already decides the answer, the right side is never checked.

13. Precedence and Associativity

In the lunch queue, teachers go before students. That's precedence: who matters more. Among students, the one at the front goes first. That's associativity: left-to-right or right-to-left.
RankOperatorsAssociativity
1 (highest)() [] -> .Left โ†’ Right
2! ~ ++ -- + - (unary) * & sizeof (type)Right โ†’ Left
3* / %Left โ†’ Right
4+ -Left โ†’ Right
5<< >>Left โ†’ Right
6< <= > >=Left โ†’ Right
7== !=Left โ†’ Right
8&Left โ†’ Right
9^Left โ†’ Right
10|Left โ†’ Right
11&&Left โ†’ Right
12||Left โ†’ Right
13?:Right โ†’ Left
14= += -= *= /= %= ...Right โ†’ Left
15 (lowest),Left โ†’ Right
Easy way to remember the order: Unary โ†’ Arithmetic โ†’ Shift โ†’ Relational โ†’ Bitwise โ†’ Logical โ†’ Conditional โ†’ Assignment โ†’ Comma. When in doubt, add brackets ( ).
๐Ÿชœ Solve step by step

  

File: 14_precedence_associativity.c

/*
 * Program 14: Precedence and Associativity
 * ----------------------------------------
 * Real-life story: In a lunch queue, teachers go before students
 * (that's PRECEDENCE - who is more important).
 * Among students, the one standing first goes first
 * (that's ASSOCIATIVITY - left to right or right to left).
 *
 * Same in maths: * and / are done BEFORE + and -  (BODMAS)
 */
#include <stdio.h>

int main() {
    int r1 = 2 + 3 * 4;        /* * first: 2 + 12 = 14 */
    int r2 = (2 + 3) * 4;      /* brackets first: 5 * 4 = 20 */
    int r3 = 20 - 6 - 4;       /* left to right: (20-6)-4 = 10 */
    int r4 = 100 / 10 / 2;     /* left to right: (100/10)/2 = 5 */
    int r5 = 10 + 20 / 5 * 2 - 3 % 2;   /* /,*,% first left to right: 10 + 8 - 1 = 17 */
    int a, b, c;
    a = b = c = 7;             /* = goes RIGHT to LEFT: c=7, then b=c, then a=b */
    int r6 = 5 > 3 && 2 > 4;   /* > before &&: 1 && 0 = 0 */
    int r7 = !0 + 1;           /* ! (unary) first: 1 + 1 = 2 */

    printf("2 + 3 * 4             = %d\n", r1);
    printf("(2 + 3) * 4           = %d\n", r2);
    printf("20 - 6 - 4            = %d\n", r3);
    printf("100 / 10 / 2          = %d\n", r4);
    printf("10 + 20 / 5 * 2 - 3 %% 2 = %d\n", r5);
    printf("a = b = c = 7         -> a=%d b=%d c=%d\n", a, b, c);
    printf("5 > 3 && 2 > 4        = %d\n", r6);
    printf("!0 + 1                = %d\n", r7);
    return 0;
}

Output

2 + 3 * 4             = 14
(2 + 3) * 4           = 20
20 - 6 - 4            = 10
100 / 10 / 2          = 5
10 + 20 / 5 * 2 - 3 % 2 = 17
a = b = c = 7         -> a=7 b=7 c=7
5 > 3 && 2 > 4        = 0
!0 + 1                = 2
Precedence decides which operator goes first. Associativity decides the order when two operators have the same precedence. Unary, conditional and assignment operators go right to left; almost everything else goes left to right. Show an example worked out step by step.

๐Ÿ“ 2-mark questions (tap to see the answer)

What is a computer?An electronic device that accepts data (input), processes it according to instructions, stores it, and produces results (output).
Differentiate hardware and software.Hardware is the physical parts you can touch (CPU, keyboard). Software is a set of programs that tell the hardware what to do (OS, Word).
What is an algorithm? List its properties.A finite, ordered set of clear steps that solves a problem. Properties: input, output, definiteness, finiteness, effectiveness.
What is pseudo code?A way of writing program logic in simple English-like statements, without strict syntax. It's meant for people to read, not computers.
What is a flowchart? Name any 4 symbols.A diagram of an algorithm drawn with standard shapes. Oval: start/stop. Parallelogram: input/output. Rectangle: process. Diamond: decision.
Compare a compiler and an interpreter.A compiler translates the whole program at once and makes an executable. An interpreter translates and runs it line by line. C uses a compiler.
Why is C called a middle-level language?It has high-level features (easy syntax, functions) and also low-level features (pointers, bitwise operators, direct memory access).
What is an identifier? Give 2 rules.A name given to a variable or function. It must start with a letter or underscore, and it can't be a keyword.
What is a keyword? How many are there in C?A reserved word with a fixed meaning (like int or while). ANSI C has 32.
Difference between #define and const?#define is a text swap done by the preprocessor, with no type and no memory. const is a typed variable that can't be changed and is checked by the compiler.
What is an enum?A user-defined type made of named integer constants, like enum color {RED, GREEN};, where RED=0 and GREEN=1.
Difference between = and ==?= is assignment: it puts a value in a variable. == is a relational check: it asks whether two values are equal and gives 1 or 0.
What is the ternary operator?condition ? expr1 : expr2. If the condition is true it gives expr1, otherwise expr2. It's the only operator in C that takes 3 operands.
Define precedence and associativity.Precedence is the priority of an operator. Associativity is the direction of evaluation (left to right or right to left) when two operators have the same priority.
What does sizeof do?A compile-time operator that gives the size of a type or variable in bytes, like sizeof(int) = 4.

๐Ÿ† Mini quiz

๐ŸŽฏ Practice homework

  1. Write an algorithm, pseudo code and flowchart to find the sum and average of 3 numbers. Then write it in C.
  2. Write a program to swap two numbers using a third variable, and then without one (hint: a = a + b; b = a - b; a = a - b;).
  3. Use #define to convert Celsius to Fahrenheit: F = C * 9 / 5 + 32.
  4. Make an enum for months (JAN = 1 ...) and print the number for OCT.
  5. Predict, then check: int a = 5; int b = a++ + ++a;. Why is this a bad idea? (Hint: it's undefined behaviour, so don't change a variable twice in one statement.)
  6. Use ?: to print the larger of two numbers, then the largest of three.
  7. Use bitwise & 1 to check even/odd: n & 1 is 1 for odd numbers.