โ† All units

๐Ÿฅš Unit 3 ยท Arrays & Strings

Egg trays, cinema seats, name badges, and how to sort and search them

1. Introduction: why do we need arrays?

You have marks for 5 subjects. Without arrays you need 5 boxes: m1, m2, m3, m4, m5. For 100 subjects you'd need 100 names. Too tiring!

An array is like an egg tray: one name, many slots in a row. Every slot holds the same type of thing (all int, or all char).

80marks[0]
75marks[1]
90marks[2]
60marks[3]
85marks[4]
C does not stop you from using marks[5] in a 5-slot array. It reads garbage or crashes. Always stay between 0 and size-1.
An array is a collection of elements of the same data type stored in contiguous memory locations under one name. Elements are accessed using an index starting from 0. Advantages: less variables, easy looping, random access. Disadvantage: fixed size.

File: 01_why_arrays.c

/*
 * Program 1: Why do we need ARRAYS?
 * ---------------------------------
 * Real-life story: You have marks for 5 subjects.
 * Without an array you need 5 separate boxes: m1, m2, m3, m4, m5.
 * With 100 subjects you would need 100 names. Too tiring!
 *
 * An ARRAY is like an egg tray: ONE name, many slots in a row.
 *   marks[0] marks[1] marks[2] marks[3] marks[4]
 */
#include <stdio.h>

int main() {
    /* The OLD way: five different variables */
    int m1 = 80, m2 = 75, m3 = 90, m4 = 60, m5 = 85;
    printf("Without array, total = %d\n", m1 + m2 + m3 + m4 + m5);

    /* The ARRAY way: one name, five slots */
    int marks[5] = {80, 75, 90, 60, 85};
    int total = 0;
    int i;

    for (i = 0; i < 5; i++) {      /* one loop visits every slot */
        total = total + marks[i];
    }
    printf("With array,    total = %d\n", total);

    printf("\nSlot numbers (index) start from 0:\n");
    for (i = 0; i < 5; i++) {
        printf("marks[%d] = %d\n", i, marks[i]);
    }

    return 0;
}

Output

Without array, total = 390
With array,    total = 390

Slot numbers (index) start from 0:
marks[0] = 80
marks[1] = 75
marks[2] = 90
marks[3] = 60
marks[4] = 85

2. Declaration and Initialization

Buying an egg tray. Declare = buy an empty tray. Initialize = put eggs in right away.

Syntax: data_type name[size];

StyleCodeWhat's inside
Declare onlyint a[5];Garbage (random) values
Full initializationint a[5] = {1,2,3,4,5};1 2 3 4 5
Partial initializationint a[5] = {1,2};1 2 0 0 0 (rest become 0)
Size-lessint a[] = {3,6,9};C counts: size = 3
All zerosint a[5] = {0};0 0 0 0 0
Char arraychar s[] = "CAT";'C' 'A' 'T' '\0' (size 4)
๐Ÿงช Try it: build an initializer
Size: Values (comma):
Number of elements = sizeof(a) / sizeof(a[0]). Total bytes divided by bytes of one slot.
Declaration reserves memory: int a[10];. Initialization gives values at declaration: int a[3] = {1,2,3};. If fewer values are given, the remaining elements become 0. If the size is left out, the compiler takes the number of values as the size.

File: 02_declare_initialize.c

/*
 * Program 2: Declaring and Initializing arrays
 * --------------------------------------------
 * Real-life story: Buying an egg tray.
 *   DECLARE    = buy an empty tray with 5 slots
 *   INITIALIZE = put eggs in the slots right away
 *
 *   int a[5];                  -> declare only (slots hold garbage!)
 *   int a[5] = {1,2,3,4,5};    -> full initialization
 *   int a[5] = {1,2};          -> partial: the rest become 0
 *   int a[]  = {1,2,3};        -> size-less: C counts for you (size 3)
 */
#include <stdio.h>

int main() {
    int i;

    int full[5] = {10, 20, 30, 40, 50};   /* every slot filled */
    int partial[5] = {7, 8};              /* only 2 given, others = 0 */
    int noSize[] = {3, 6, 9};             /* C decides size = 3 */
    int zeros[5] = {0};                   /* quick trick: all zeros */
    char letters[4] = {'C', 'A', 'T', '\0'}; /* array of characters */

    printf("full    : ");
    for (i = 0; i < 5; i++) printf("%d ", full[i]);

    printf("\npartial : ");
    for (i = 0; i < 5; i++) printf("%d ", partial[i]);

    int size = sizeof(noSize) / sizeof(noSize[0]);   /* total bytes / bytes of one slot */
    printf("\nnoSize  : ");
    for (i = 0; i < size; i++) printf("%d ", noSize[i]);
    printf("  (C made the size %d)", size);

    printf("\nzeros   : ");
    for (i = 0; i < 5; i++) printf("%d ", zeros[i]);

    printf("\nletters : %s\n", letters);

    /* Changing one slot later */
    full[2] = 99;
    printf("\nAfter full[2] = 99 -> full[2] is now %d\n", full[2]);

    printf("One int takes %zu bytes, so full[5] takes %zu bytes\n", sizeof(int), sizeof(full));

    return 0;
}

Output

full    : 10 20 30 40 50 
partial : 7 8 0 0 0 
noSize  : 3 6 9   (C made the size 3)
zeros   : 0 0 0 0 0 
letters : CAT

After full[2] = 99 -> full[2] is now 99
One int takes 4 bytes, so full[5] takes 20 bytes

3. One-dimensional array: read, print, sum, max

A cricket player's runs in 6 matches. Find total runs, average, best and worst score.

A 1D array is a single row. We always use one loop:

for (i = 0; i < n; i++)  scanf("%d", &a[i]);   // read
for (i = 0; i < n; i++)  printf("%d", a[i]);    // print

For the max: guess the first one is the biggest, then walk through. If someone is bigger, they become the new max.

๐Ÿ Try it: type your own scores

  
Programs on 1D arrays: reading n elements, printing, sum and average, largest and smallest, counting even/odd. The key idea: max = a[0]; for each i, if (a[i] > max) max = a[i];

File: 03_one_d_array.c (sample input: 45 12 78 33 90 5)

/*
 * Program 3: One-dimensional array - Read, Print, Sum, Max, Min
 * -------------------------------------------------------------
 * Real-life story: A cricket player's runs in 6 matches.
 * Let's find total runs, average, best score and worst score.
 *
 * Sample input: 6 numbers, e.g.  45 12 78 33 90 5
 */
#include <stdio.h>

int main() {
    int runs[6];
    int i, sum = 0;

    printf("Enter runs of 6 matches: ");
    for (i = 0; i < 6; i++) {
        scanf("%d", &runs[i]);       /* READ: fill each slot */
    }

    printf("\nMatch-wise runs:\n");
    for (i = 0; i < 6; i++) {
        printf("Match %d: %d\n", i + 1, runs[i]);   /* PRINT each slot */
    }

    int max = runs[0];   /* guess: first match is the best */
    int min = runs[0];   /* guess: first match is the worst */

    for (i = 0; i < 6; i++) {
        sum = sum + runs[i];               /* SUM */
        if (runs[i] > max) max = runs[i];  /* found a bigger score */
        if (runs[i] < min) min = runs[i];  /* found a smaller score */
    }

    printf("\nTotal runs   = %d\n", sum);
    printf("Average      = %.2f\n", (float)sum / 6);
    printf("Best score   = %d\n", max);
    printf("Worst score  = %d\n", min);

    return 0;
}

Output

Enter runs of 6 matches: 45 12 78 33 90 5
Match-wise runs:
Match 1: 45
Match 2: 12
Match 3: 78
Match 4: 33
Match 5: 90
Match 6: 5

Total runs   = 263
Average      = 43.83
Best score   = 90
Worst score  = 5

4. Two-dimensional arrays

Seats in a cinema hall. Each seat has a row and a column, like seat[1][2].

Syntax: data_type name[rows][columns];   int marks[3][4]; has 3 ร— 4 = 12 slots.

int m[2][3] = { {1, 2, 3},     // row 0
                {4, 5, 6} };   // row 1
๐ŸŽฌ Try it: click any seat
Rows: Cols:
Click a seat to see its row and column index.
Two loops: the outer loop picks a row, the inner loop walks across its columns. In memory, C stores row 0 first, then row 1 (row-major order).
A 2D array stores data in rows and columns (a matrix). Declaration int a[3][4];, access a[i][j], total elements = rows ร— columns. Stored in row-major order. Uses: matrices, tables, game boards.

File: 04_two_d_array.c

/*
 * Program 4: Two-dimensional arrays (rows and columns)
 * ----------------------------------------------------
 * Real-life story: Seats in a cinema hall.
 * Each seat has a ROW number and a COLUMN number, like seat[1][2].
 *
 *   int seats[3][4];  -> 3 rows, 4 columns = 12 seats
 *
 * We use TWO loops: the outer loop picks the row,
 * the inner loop walks across the columns.
 */
#include <stdio.h>

int main() {
    int marks[3][4] = {
        {80, 75, 90, 60},    /* row 0 : student 1 */
        {55, 65, 70, 95},    /* row 1 : student 2 */
        {88, 92, 79, 85}     /* row 2 : student 3 */
    };
    int r, c;

    printf("Marks table (3 students x 4 subjects):\n");
    for (r = 0; r < 3; r++) {
        for (c = 0; c < 4; c++) {
            printf("%4d", marks[r][c]);
        }
        printf("\n");
    }

    printf("\nmarks[1][3] means row 1, column 3 = %d\n", marks[1][3]);

    /* Total of each student (each row) */
    printf("\n");
    for (r = 0; r < 3; r++) {
        int total = 0;
        for (c = 0; c < 4; c++) {
            total = total + marks[r][c];
        }
        printf("Student %d total = %d\n", r + 1, total);
    }

    return 0;
}

Output

Marks table (3 students x 4 subjects):
  80  75  90  60
  55  65  70  95
  88  92  79  85

marks[1][3] means row 1, column 3 = 95

Student 1 total = 305
Student 2 total = 285
Student 3 total = 344

5. Matrix addition

Two toy shops each have a 2ร—3 shelf. Join both shops: each spot adds up with the same spot in the other shop.

Rule: both matrices must have the same size.   C[i][j] = A[i][j] + B[i][j]

| 1 2 3 |   | 6 5 4 |   | 7 7 7 |
| 4 5 6 | + | 3 2 1 | = | 7 7 7 |
Matrix addition is possible only when both matrices have the same order (m ร— n). Use two nested loops and add element by element. Subtraction works the same way with -.

File: 05_matrix_addition.c

/*
 * Program 5: Matrix Addition
 * --------------------------
 * Real-life story: Two shops each have a 2x3 shelf of toys.
 * We join both shops. Each shelf spot adds up: same row, same column.
 *
 *   C[i][j] = A[i][j] + B[i][j]
 */
#include <stdio.h>

int main() {
    int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
    int B[2][3] = {{6, 5, 4}, {3, 2, 1}};
    int C[2][3];
    int i, j;

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            C[i][j] = A[i][j] + B[i][j];   /* add matching spots */
        }
    }

    printf("A + B =\n");
    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            printf("%d+%d=%-3d ", A[i][j], B[i][j], C[i][j]);
        }
        printf("\n");
    }

    printf("\nResult matrix C:\n");
    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            printf("%4d", C[i][j]);
        }
        printf("\n");
    }
    return 0;
}

Output

A + B =
1+6=7   2+5=7   3+4=7   
4+3=7   5+2=7   6+1=7   

Result matrix C:
   7   7   7
   7   7   7

6. Matrix multiplication

A fruit shop. Matrix A says how many fruits each kid buys. Matrix B gives the price of each fruit on 2 days. A ร— B tells how much each kid pays each day.

Rule: columns of A = rows of B. If A is (2ร—3) and B is (3ร—2), the answer is (2ร—2).

To get C[i][j]: walk along row i of A and column j of B, multiply pairs, add them up.

C[0][0] = A[0][0]*B[0][0] + A[0][1]*B[1][0] + A[0][2]*B[2][0]
        =    1  *  10    +    2  *   5    +    3  *  20     = 80
That's why multiplication needs three loops: i (row of A), j (column of B), and k (walking along them).
Condition: number of columns of the first matrix must equal the number of rows of the second. Result order = rows of A ร— columns of B. Formula: C[i][j] = ฮฃ A[i][k] * B[k][j] for k = 0 to n-1. Uses three nested loops.

File: 06_matrix_multiplication.c

/*
 * Program 6: Matrix Multiplication
 * --------------------------------
 * Real-life story: A fruit shop.
 *   Matrix A = how many fruits each kid buys  (rows = kids, cols = fruits)
 *   Matrix B = price of each fruit on 2 days  (rows = fruits, cols = days)
 *   A x B    = how much each kid pays on each day
 *
 * Rule: columns of A must equal rows of B.
 *   C[i][j] = sum of A[i][k] * B[k][j]   (row of A "times" column of B)
 */
#include <stdio.h>

int main() {
    int A[2][3] = {{1, 2, 3},     /* kid 1 buys 1 apple, 2 bananas, 3 mangoes */
                   {4, 5, 6}};    /* kid 2 */
    int B[3][2] = {{10, 12},      /* apple price on day 1, day 2 */
                   {5, 6},        /* banana price */
                   {20, 15}};     /* mango price */
    int C[2][2];
    int i, j, k;

    for (i = 0; i < 2; i++) {             /* each row of A (kid) */
        for (j = 0; j < 2; j++) {         /* each column of B (day) */
            C[i][j] = 0;                  /* start the bill at 0 */
            for (k = 0; k < 3; k++) {     /* walk along the row and column */
                C[i][j] = C[i][j] + A[i][k] * B[k][j];
            }
        }
    }

    printf("A (2x3) x B (3x2) = C (2x2)\n\n");
    for (i = 0; i < 2; i++) {
        for (j = 0; j < 2; j++) {
            printf("Kid %d pays on day %d: Rs %d\n", i + 1, j + 1, C[i][j]);
        }
    }

    printf("\nMatrix C:\n");
    for (i = 0; i < 2; i++) {
        for (j = 0; j < 2; j++) printf("%5d", C[i][j]);
        printf("\n");
    }
    return 0;
}

Output

A (2x3) x B (3x2) = C (2x2)

Kid 1 pays on day 1: Rs 80
Kid 1 pays on day 2: Rs 69
Kid 2 pays on day 1: Rs 185
Kid 2 pays on day 2: Rs 168

Matrix C:
   80   69
  185  168

7. Transpose of a matrix

Turn your timetable on its side. Rows become columns, and columns become rows.
| 1 2 3 |   transpose   | 1 4 |
| 4 5 6 |   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ   | 2 5 |
                        | 3 6 |

Just swap the two indices: T[j][i] = A[i][j]. A (2ร—3) becomes (3ร—2).

Transpose of an m ร— n matrix is an n ร— m matrix obtained by interchanging rows and columns: T[j][i] = A[i][j].

File: 07_matrix_transpose.c

/*
 * Program 7: Transpose of a Matrix
 * --------------------------------
 * Real-life story: Turn your timetable on its side!
 * Rows become columns and columns become rows.
 *
 *   T[j][i] = A[i][j]
 */
#include <stdio.h>

int main() {
    int A[2][3] = {{1, 2, 3},
                   {4, 5, 6}};
    int T[3][2];
    int i, j;

    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) {
            T[j][i] = A[i][j];    /* swap row number and column number */
        }
    }

    printf("Original (2 rows x 3 cols):\n");
    for (i = 0; i < 2; i++) {
        for (j = 0; j < 3; j++) printf("%3d", A[i][j]);
        printf("\n");
    }

    printf("\nTranspose (3 rows x 2 cols):\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 2; j++) printf("%3d", T[i][j]);
        printf("\n");
    }
    return 0;
}

Output

Original (2 rows x 3 cols):
  1  2  3
  4  5  6

Transpose (3 rows x 2 cols):
  1  4
  2  5
  3  6

๐Ÿงต Strings: a quick intro

A string is a char array that ends with a hidden stop sign '\0' (the null character).

A[0]
P[1]
P[2]
L[3]
E[4]
\0[5]
JobManual way<string.h> way
Lengthcount until '\0'strlen(s)
Comparecheck letter by letterstrcmp(a, b)
Joingo to end of a, copy b after itstrcat(a, b)
Copycopy letter by letterstrcpy(dest, src)
๐Ÿ”ค Try all four string operations
String 1: String 2:

  

8. String length

Counting the letters on your name badge, finger by finger, until you hit the end.

Start count = 0. While s[count] != '\0', add 1. Or just call strlen(s).

strlen("APPLE") is 5, but sizeof of the array is 6, because it also counts the '\0' slot.
strlen() returns the number of characters before the null character. Defined in <string.h>. Without the library: while (s[i] != '\0') i++;

File: 08_string_length.c

/*
 * Program 8: String LENGTH
 * ------------------------
 * Real-life story: Counting the letters on your name badge.
 *
 * A string is a char array that ends with a hidden stop sign '\0'.
 *   "APPLE" -> A P P L E \0   (5 letters, 6 slots)
 *
 * Way 1: count with a loop until we hit '\0'
 * Way 2: use strlen() from <string.h>
 */
#include <stdio.h>
#include <string.h>

int main() {
    char word[] = "APPLE";
    int count = 0;

    /* Way 1: manual loop */
    while (word[count] != '\0') {
        count++;
    }
    printf("Manual count : \"%s\" has %d letters\n", word, count);

    /* Way 2: built-in function */
    printf("strlen()     : \"%s\" has %zu letters\n", word, strlen(word));

    /* sizeof counts the slots, including the '\0' */
    printf("sizeof()     : the array has %zu slots (includes '\\0')\n", sizeof(word));

    return 0;
}

Output

Manual count : "APPLE" has 5 letters
strlen()     : "APPLE" has 5 letters
sizeof()     : the array has 6 slots (includes '\0')

9. String compare

Checking if the password you typed matches the saved password.

Compare letter by letter, like a dictionary. Stop at the first different letter.

strcmp(a, b) returnsMeaning
0Both strings are the same
less than 0a comes before b in the dictionary
greater than 0a comes after b
Never write if (a == b) for strings. That compares their addresses, not their letters. Use strcmp(a, b) == 0.
strcmp(s1, s2) compares two strings character by character using ASCII values and returns 0 if equal, a negative value if s1 < s2, positive if s1 > s2.

File: 09_string_compare.c

/*
 * Program 9: String COMPARE
 * -------------------------
 * Real-life story: Checking if the password you typed matches the saved one.
 *
 * We compare letter by letter, like a dictionary.
 *   result = 0   -> both strings are SAME
 *   result < 0   -> first string comes BEFORE in dictionary
 *   result > 0   -> first string comes AFTER
 *
 * NOTE: never use == to compare strings in C. Use strcmp().
 */
#include <stdio.h>
#include <string.h>

/* Manual compare: returns difference at first mismatch */
int myCompare(char a[], char b[]) {
    int i = 0;
    while (a[i] != '\0' && a[i] == b[i]) {   /* move on while letters match */
        i++;
    }
    return a[i] - b[i];    /* 0 if same, else the difference of the first different letters */
}

int main() {
    char saved[] = "tiger";
    char typed1[] = "tiger";
    char typed2[] = "tigress";

    printf("Manual : compare(\"%s\", \"%s\") = %d\n", saved, typed1, myCompare(saved, typed1));
    printf("Manual : compare(\"%s\", \"%s\") = %d\n", saved, typed2, myCompare(saved, typed2));

    printf("strcmp : strcmp(\"%s\", \"%s\") = %d\n", saved, typed1, strcmp(saved, typed1));
    printf("strcmp : strcmp(\"apple\", \"banana\") is %s 0\n", strcmp("apple", "banana") < 0 ? "<" : ">");

    if (strcmp(saved, typed1) == 0) {
        printf("\nPassword \"%s\" -> Correct! Door opens.\n", typed1);
    }
    if (strcmp(saved, typed2) != 0) {
        printf("Password \"%s\" -> Wrong! Door stays shut.\n", typed2);
    }
    return 0;
}

Output

Manual : compare("tiger", "tiger") = 0
Manual : compare("tiger", "tigress") = -13
strcmp : strcmp("tiger", "tiger") = 0
strcmp : strcmp("apple", "banana") is < 0

Password "tiger" -> Correct! Door opens.
Password "tigress" -> Wrong! Door stays shut.

10. String concatenate (join)

Joining two train compartments: "Ice" + "Cream" โ†’ "IceCream".
1. walk to the '\0' of the first string
โ†’
2. copy each letter of the second there
โ†’
3. put a new '\0' at the end
The first array must be big enough for both! char a[20] = "Ice"; is fine; char a[] = "Ice"; has only 4 slots and will overflow.
strcat(s1, s2) appends s2 to the end of s1. s1 must have enough space. Result is stored in s1.

File: 10_string_concatenate.c

/*
 * Program 10: String CONCATENATE (join)
 * -------------------------------------
 * Real-life story: Joining two train compartments.
 *   "Ice" + "Cream" -> "IceCream"
 *
 * Make sure the first array is BIG enough to hold both!
 */
#include <stdio.h>
#include <string.h>

int main() {
    /* Way 1: manual loop */
    char first[20] = "Ice";
    char second[] = "Cream";
    int i = 0, j = 0;

    while (first[i] != '\0') {   /* go to the end of first */
        i++;
    }
    while (second[j] != '\0') {  /* copy each letter of second after it */
        first[i] = second[j];
        i++;
        j++;
    }
    first[i] = '\0';             /* put the stop sign at the new end */
    printf("Manual join : %s\n", first);

    /* Way 2: strcat() */
    char greet[30] = "Good ";
    strcat(greet, "Morning");
    printf("strcat()    : %s\n", greet);

    /* Building a full name */
    char fullName[40] = "Sabari";
    strcat(fullName, " ");
    strcat(fullName, "Nathan");
    printf("Full name   : %s\n", fullName);

    return 0;
}

Output

Manual join : IceCream
strcat()    : Good Morning
Full name   : Sabari Nathan

11. String copy

A photocopy machine: same words, new paper. Changing the copy doesn't change the original.

You cannot do dest = source; with arrays. Copy letter by letter (and add '\0'), or use strcpy(dest, source).

Remember the order: strcpy(where to, from where), like x = y.
strcpy(dest, src) copies src (including '\0') into dest. dest must be large enough.

File: 11_string_copy.c

/*
 * Program 11: String COPY
 * -----------------------
 * Real-life story: Photocopying your friend's homework (just for this example!).
 *
 * You CANNOT write  dest = source;  for arrays in C.
 * You copy letter by letter, or use strcpy(dest, source).
 */
#include <stdio.h>
#include <string.h>

int main() {
    char source[] = "Homework";
    char copy1[20];
    char copy2[20];
    int i = 0;

    /* Way 1: manual loop */
    while (source[i] != '\0') {
        copy1[i] = source[i];    /* copy one letter */
        i++;
    }
    copy1[i] = '\0';             /* don't forget the stop sign */
    printf("Manual copy : %s\n", copy1);

    /* Way 2: strcpy(destination, source) */
    strcpy(copy2, source);
    printf("strcpy()    : %s\n", copy2);

    /* Changing the copy does not change the original */
    copy2[0] = 'h';
    printf("\nChanged copy: %s\n", copy2);
    printf("Original    : %s (still safe)\n", source);

    return 0;
}

Output

Manual copy : Homework
strcpy()    : Homework

Changed copy: homework
Original    : Homework (still safe)

12. Selection sort

Kids lining up for a photo, shortest first. The teacher selects the shortest kid and puts them first. Then selects the shortest from the rest for second place, and so on.
  1. For position i, find the smallest from i to the end.
  2. Swap it with the element at i.
  3. Move to i + 1. Repeat until the second last position.
๐Ÿง Watch selection sort step by step
Numbers:

Orange = now checking ยท Blue border = smallest so far ยท Green = already sorted

Selection sort repeatedly selects the minimum element from the unsorted part and swaps it to the front. For n elements it makes n-1 passes. Time complexity O(nยฒ) in all cases. Simple, few swaps (at most n-1).

File: 12_selection_sort.c

/*
 * Program 12: SELECTION SORT
 * --------------------------
 * Real-life story: Kids standing in a line for a photo, shortest first.
 * The teacher looks at everyone, SELECTS the shortest kid and puts them first.
 * Then looks at the rest, selects the next shortest, puts them second... and so on.
 *
 * Steps for each position i:
 *   1. find the smallest from i to the end
 *   2. swap it with the element at i
 */
#include <stdio.h>

void printArray(int a[], int n) {
    int i;
    for (i = 0; i < n; i++) printf("%d ", a[i]);
    printf("\n");
}

int main() {
    int heights[] = {64, 25, 12, 22, 11};
    int n = 5;
    int i, j, minIndex, temp;

    printf("Before sorting : ");
    printArray(heights, n);

    for (i = 0; i < n - 1; i++) {
        minIndex = i;                          /* guess: smallest is at i */
        for (j = i + 1; j < n; j++) {
            if (heights[j] < heights[minIndex]) {
                minIndex = j;                  /* found someone shorter */
            }
        }
        /* swap the smallest into position i */
        temp = heights[i];
        heights[i] = heights[minIndex];
        heights[minIndex] = temp;

        printf("Pass %d (put %2d in place %d): ", i + 1, heights[i], i);
        printArray(heights, n);
    }

    printf("After sorting  : ");
    printArray(heights, n);
    return 0;
}

Output

Before sorting : 64 25 12 22 11 
Pass 1 (put 11 in place 0): 11 25 12 22 64 
Pass 2 (put 12 in place 1): 11 12 25 22 64 
Pass 3 (put 22 in place 2): 11 12 22 25 64 
Pass 4 (put 25 in place 3): 11 12 22 25 64 
After sorting  : 11 12 22 25 64

13. Linear search

Looking for your blue sock in a messy drawer. You pick up socks one by one from the start until you find it.

Check a[0], a[1], a[2]... If a[i] == key, found. If you reach the end, it's not there.

Linear (sequential) search compares the key with each element from the start. Best case O(1) (first element), worst case O(n). No need for a sorted array.

File: 13_linear_search.c

/*
 * Program 13: LINEAR SEARCH
 * -------------------------
 * Real-life story: Looking for your blue sock in a messy drawer.
 * You pick up socks ONE BY ONE from the start until you find it.
 *
 * Works on ANY array (sorted or not). Slow for big arrays.
 */
#include <stdio.h>

int main() {
    int drawer[] = {14, 7, 31, 9, 22, 5, 18};
    int n = 7;
    int key = 22;          /* the sock we want */
    int i, found = -1;

    for (i = 0; i < n; i++) {
        printf("Check position %d: %d", i, drawer[i]);
        if (drawer[i] == key) {
            printf("  <- FOUND!\n");
            found = i;
            break;         /* stop looking */
        }
        printf("  no\n");
    }

    if (found != -1) {
        printf("\n%d found at position %d after %d checks.\n", key, found, found + 1);
    } else {
        printf("\n%d is not in the drawer.\n", key);
    }
    return 0;
}

Output

Check position 0: 14  no
Check position 1: 7  no
Check position 2: 31  no
Check position 3: 9  no
Check position 4: 22  <- FOUND!

22 found at position 4 after 5 checks.

14. Binary search

Finding a word in a dictionary. Open the middle page. Is your word before or after? Throw away the wrong half. Repeat!
mid = (low + high) / 2
if a[mid] == key  โ†’ found
if a[mid] <  key  โ†’ low  = mid + 1   (look right)
if a[mid] >  key  โ†’ high = mid - 1   (look left)
stop when low > high โ†’ not found
Binary search works only on a sorted array.
๐Ÿ” Race: linear search vs binary search
Sorted array:
Find:

Linear

Binary

Linear searchBinary search
Needs sorted array?NoYes
How it worksOne by oneCut in half each time
Worst checks for 1000 items1000about 10
Time complexityO(n)O(log n)
Binary search works on a sorted array. It compares the key with the middle element and discards half of the array each step. Worst case O(log n). Variables: low, high, mid = (low + high) / 2.

File: 14_binary_search.c

/*
 * Program 14: BINARY SEARCH (iterative)
 * -------------------------------------
 * Real-life story: Finding a word in a dictionary.
 * You open the MIDDLE page. Is your word before or after?
 * Throw away the wrong half and repeat. Super fast!
 *
 * RULE: the array MUST be sorted first.
 */
#include <stdio.h>

int main() {
    int pages[] = {3, 8, 15, 21, 29, 36, 42, 57, 63, 71};
    int n = 10;
    int key = 57;
    int low = 0, high = n - 1, mid;
    int found = -1, steps = 0;

    while (low <= high) {
        mid = (low + high) / 2;            /* open the middle page */
        steps++;
        printf("Step %d: low=%d high=%d mid=%d -> pages[mid]=%d\n",
               steps, low, high, mid, pages[mid]);

        if (pages[mid] == key) {
            found = mid;                   /* got it! */
            break;
        } else if (pages[mid] < key) {
            low = mid + 1;                 /* word is in the RIGHT half */
        } else {
            high = mid - 1;                /* word is in the LEFT half */
        }
    }

    if (found != -1) {
        printf("\n%d found at position %d in only %d steps.\n", key, found, steps);
    } else {
        printf("\n%d not found.\n", key);
    }
    return 0;
}

Output

Step 1: low=0 high=9 mid=4 -> pages[mid]=29
Step 2: low=5 high=9 mid=7 -> pages[mid]=57

57 found at position 7 in only 2 steps.

๐Ÿ“ 2-mark questions & answers

1. Define an array.An array is a collection of elements of the same data type stored in contiguous memory locations, referred to by a single name and accessed using an index.
2. Why does array index start from 0?The index is the distance (offset) from the start of the array. The first element is at distance 0 from the base address, so a[i] is at base + i ร— size.
3. What happens with partial initialization?In int a[5] = {1, 2}; the first two elements get 1 and 2, and the remaining elements are set to 0.
4. How do you find the number of elements of an array?sizeof(a) / sizeof(a[0])
5. What is a 2D array? Give an example.An array of arrays arranged in rows and columns. int m[2][3] = {{1,2,3},{4,5,6}}; has 2 rows and 3 columns.
6. What is row-major order?Elements of a 2D array are stored row after row in memory: all of row 0, then all of row 1, and so on. C uses row-major order.
7. Condition for matrix multiplication?Number of columns of the first matrix must be equal to the number of rows of the second matrix.
8. What is a string? How is it terminated?A string is an array of characters terminated by the null character '\0'.
9. Difference between strlen() and sizeof()?strlen() counts characters before '\0'. sizeof gives the total memory of the array, including '\0' and unused slots.
10. What does strcmp() return?0 if both strings are equal, a negative value if the first is smaller, a positive value if the first is greater (based on ASCII values).
11. Write any four string functions.strlen(), strcpy(), strcat(), strcmp(). Also strrev() (non-standard), strupr(), strlwr(). Header: <string.h>.
12. Linear vs binary search?Linear search checks each element in order, works on unsorted data, O(n). Binary search needs sorted data, halves the search area each step, O(log n).
13. What is the time complexity of selection sort?O(nยฒ) in best, average and worst cases.

๐Ÿ† Mini quiz

๐ŸŽฏ Practice homework

  1. Read 10 numbers into an array and count how many are even and how many are odd.
  2. Print an array in reverse order.
  3. Find the sum of the main diagonal of a 3ร—3 matrix (a[0][0] + a[1][1] + a[2][2]).
  4. Check if a matrix is symmetric (equal to its own transpose).
  5. Write your own strrev: reverse a string using a loop.
  6. Count how many times the letter 'a' appears in "banana".
  7. Change selection sort to sort in descending order (biggest first).
  8. Sort an array with selection sort, then use binary search on it.