C Fundamentals

Arrays in C

Learn to store multiple values of the same type efficiently using arrays โ€” from simple lists to multi-dimensional tables.

๐Ÿค” What is an Array?

๐Ÿ’ก The "Boxes in a Row" Analogy

Imagine you need to store test scores for 5 students. You could create 5 separate variables:

int score1 = 85;
int score2 = 90;
int score3 = 78;
int score4 = 92;
int score5 = 88;

But what if you have 100 students? Or 1000? Creating individual variables is messy and hard to manage.

An array is like a row of numbered boxes where each box can hold one value, and all boxes are the same type:

    Visual: Array as Numbered Boxes
    
    Index:   [0]     [1]     [2]     [3]     [4]
            +---+   +---+   +---+   +---+   +---+
            | 85|   | 90|   | 78|   | 92|   | 88|
            +---+   +---+   +---+   +---+   +---+
            scores[0] scores[1] scores[2] scores[3] scores[4]
            
    All boxes are connected and share the same name "scores"
    We access each box using its index number (0, 1, 2, 3, 4)
                        

Key Points:

  • Array stores multiple values of the same data type
  • Each element has an index starting from 0 (not 1!)
  • Array size is fixed once created
  • Elements are stored in contiguous memory (next to each other)

๐Ÿ’พ How Arrays are Stored in Memory

๐Ÿ“Š Memory Layout Visualization

When you create int scores[5] = {85, 90, 78, 92, 88};, here's what happens in memory:

Memory Address (hex)    Variable      Value
    0x1000            scores[0]  โ†’    85
    0x1004            scores[1]  โ†’    90    โ† Each int takes 4 bytes
    0x1008            scores[2]  โ†’    78
    0x100C            scores[3]  โ†’    92
    0x1010            scores[4]  โ†’    88
    
    Base address = &scores[0] = 0x1000
    
    The array name "scores" actually points to the first element!
                        

๐Ÿงฎ Address Calculation

To find the address of scores[i]:

Address of scores[i] = Base Address + (i ร— size of each element)

Example: Where is scores[3]?
Address = 0x1000 + (3 ร— 4) = 0x1000 + 12 = 0x100C โœ“

๐Ÿ“‹ One-Dimensional Arrays

โœ๏ธ Declaration and Initialization

Method 1: Declare first, assign later
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  int scores[5];  // 5 integers         โ”‚
โ”‚  scores[0] = 85;  // Assign to box 0   โ”‚
โ”‚  scores[1] = 90;  // Assign to box 1   โ”‚
โ”‚  scores[2] = 78;                       โ”‚
โ”‚  scores[3] = 92;                       โ”‚
โ”‚  scores[4] = 88;                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Method 2: Declare and initialize together
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  int scores[5] = {85, 90, 78, 92, 88}; โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Method 3: Partial initialization (rest become 0)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  int scores[5] = {85, 90};              โ”‚
โ”‚  Result: {85, 90, 0, 0, 0}             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Method 4: Let compiler count (size inferred)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  int scores[] = {85, 90, 78, 92, 88};  โ”‚
โ”‚  Compiler automatically sets size = 5  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        

โš ๏ธ Important: Index Starts at 0!

๐Ÿ“Š Step-by-Step: How Indexing Works

Array: int scores[5] = {85, 90, 78, 92, 88};

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Position:  1st    2nd    3rd    4th    5th   โ† Human  โ”‚
โ”‚  Index:      0      1      2      3      4    โ† C     โ”‚
โ”‚  Value:     85     90     78     92     88            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

To access elements:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  scores[0] gives you 85  โ† First item   โ”‚
โ”‚  scores[1] gives you 90  โ† Second item โ”‚
โ”‚  scores[4] gives you 88  โ† Fifth item  โ”‚
โ”‚  scores[5] โ†’ ERROR!      โ† OUT OF BOUNDSโ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿšจ CRITICAL: scores[5] does NOT exist!
   Valid indices are 0, 1, 2, 3, and 4 only
                        
basic_array.c
#include <stdio.h>

int main() {
    // Declare and initialize
    int scores[5] = {85, 90, 78, 92, 88};
    
    // Access individual elements
    printf("First student score: %d\n", scores[0]);   // 85
    printf("Third student score: %d\n", scores[2]);   // 78
    printf("Last student score: %d\n", scores[4]);    // 88
    
    // Modify an element
    scores[1] = 95;  // Changed 90 to 95
    printf("Updated second score: %d\n", scores[1]);
    
    // Calculate array size automatically
    int n = sizeof(scores) / sizeof(scores[0]);
    printf("Array size: %d elements\n", n);
    
    return 0;
}

๐Ÿ”„ Looping Through Arrays

๐Ÿ“Š Traversal Process

Step-by-step: Printing all elements

Array: [85, 90, 78, 92, 88]
Size: 5

Iteration | i | scores[i] | Action
----------+---+-----------+------------------
    1     | 0 |    85     | Print scores[0]
    2     | 1 |    90     | Print scores[1]
    3     | 2 |    78     | Print scores[2]
    4     | 3 |    92     | Print scores[3]
    5     | 4 |    88     | Print scores[4]
    6     | 5 |   STOP    | i < 5 is false
    
Output: 85 90 78 92 88
                        
array_traversal.c
#include <stdio.h>

int main() {
    int scores[] = {85, 90, 78, 92, 88};
    int n = sizeof(scores) / sizeof(scores[0]);
    
    // Forward traversal
    printf("All scores: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", scores[i]);
    }
    printf("\n");
    
    // Backward traversal
    printf("Reverse: ");
    for (int i = n - 1; i >= 0; i--) {
        printf("%d ", scores[i]);
    }
    printf("\n");
    
    // Calculate sum and average
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += scores[i];  // Add each element to sum
    }
    float average = (float)sum / n;
    printf("Sum: %d, Average: %.2f\n", sum, average);
    
    return 0;
}

๐Ÿ› ๏ธ Common Array Operations

๐Ÿ“Š Operation Examples

1. FIND MAXIMUM
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Start: max = first element (85)      โ”‚
   โ”‚  Compare with 90 โ†’ 90 is bigger       โ”‚
   โ”‚  Compare with 78 โ†’ 90 still biggest   โ”‚
   โ”‚  Compare with 92 โ†’ 92 is bigger!      โ”‚
   โ”‚  Compare with 88 โ†’ 92 still biggest   โ”‚
   โ”‚  Result: 92                           โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2. LINEAR SEARCH (Find 78)
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Check index 0: 85 โ‰  78 โ†’ continue    โ”‚
   โ”‚  Check index 1: 90 โ‰  78 โ†’ continue    โ”‚
   โ”‚  Check index 2: 78 = 78 โ†’ FOUND!      โ”‚
   โ”‚  Return index 2                       โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3. REVERSE ARRAY
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  Original: [85, 90, 78, 92, 88]        โ”‚
   โ”‚  Swap 0โ†”4: [88, 90, 78, 92, 85]        โ”‚
   โ”‚  Swap 1โ†”3: [88, 92, 78, 90, 85]        โ”‚
   โ”‚  Stop: middle reached                   โ”‚
   โ”‚  Result: [88, 92, 78, 90, 85]          โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        
array_operations.c
#include 

// Find maximum element
int findMax(int arr[], int size) {
    int max = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > max)
            max = arr[i];
    }
    return max;
}

// Linear search
int linearSearch(int arr[], int size, int key) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == key)
            return i;  // Return index where found
    }
    return -1;  // Not found
}

// Reverse array in-place
void reverseArray(int arr[], int size) {
    for (int i = 0; i < size / 2; i++) {
        int temp = arr[i];
        arr[i] = arr[size - 1 - i];
        arr[size - 1 - i] = temp;
    }
}

// Print array
void printArray(int arr[], int size) {
    printf("[ ");
    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);
    printf("]\n");
}

int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printf("Original: ");
    printArray(arr, size);
    
    printf("Maximum: %d\n", findMax(arr, size));
    
    int pos = linearSearch(arr, size, 22);
    if (pos != -1)
        printf("Found 22 at index %d\n", pos);
    else
        printf("22 not found\n");
    
    reverseArray(arr, size);
    printf("Reversed: ");
    printArray(arr, size);
    
    return 0;
}

๐Ÿ“Š Two-Dimensional Arrays (2D Arrays)

๐Ÿ’ก The "Spreadsheet" Analogy

A 2D array is like a spreadsheet or table with rows and columns:

Visual: 2D Array as a Grid

        Column 0   Column 1   Column 2
          โ†“          โ†“          โ†“
Row 0 โ†’ +----------+----------+----------+
        |  matrix  |  matrix  |  matrix  |
        |   [0][0] |   [0][1] |   [0][2] |
        |    (1)   |    (2)   |    (3)   |
        +----------+----------+----------+
Row 1 โ†’ |  matrix  |  matrix  |  matrix  |
        |   [1][0] |   [1][1] |   [1][2] |
        |    (4)   |    (5)   |    (6)   |
        +----------+----------+----------+
Row 2 โ†’ |  matrix  |  matrix  |  matrix  |
        |   [2][0] |   [2][1] |   [2][2] |
        |    (7)   |    (8)   |    (9)   |
        +----------+----------+----------+

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

๐ŸŽ“ Real-World Examples

  • Seating Chart: Rows = rows of seats, Columns = seat numbers
  • Game Board: Chess board, Tic-tac-toe, Sudoku
  • Pixel Image: Rows = height, Columns = width
  • Student Grades: Rows = students, Columns = subjects

๐Ÿ“Š Memory Storage of 2D Arrays

2D arrays are stored in row-major order (row by row) in memory:

Logical View (3ร—3 matrix):
    1  2  3
    4  5  6
    7  8  9

Memory Layout (Row-Major Order):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Address โ”‚ Value โ”‚ Element                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 0x1000  โ”‚   1   โ”‚ matrix[0][0]  โ† Row 0 starts here       โ”‚
โ”‚ 0x1004  โ”‚   2   โ”‚ matrix[0][1]                             โ”‚
โ”‚ 0x1008  โ”‚   3   โ”‚ matrix[0][2]  โ† Row 0 ends here          โ”‚
โ”‚ 0x100C  โ”‚   4   โ”‚ matrix[1][0]  โ† Row 1 starts here       โ”‚
โ”‚ 0x1010  โ”‚   5   โ”‚ matrix[1][1]                             โ”‚
โ”‚ 0x1014  โ”‚   6   โ”‚ matrix[1][2]  โ† Row 1 ends here          โ”‚
โ”‚ 0x1018  โ”‚   7   โ”‚ matrix[2][0]  โ† Row 2 starts here       โ”‚
โ”‚ 0x101C  โ”‚   8   โ”‚ matrix[2][1]                             โ”‚
โ”‚ 0x1020  โ”‚   9   โ”‚ matrix[2][2]  โ† Row 2 ends here          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Formula to find address of matrix[i][j]:
Address = Base + (i ร— columns + j) ร— size_of_element

Example: Where is matrix[1][2]?
Address = 0x1000 + (1 ร— 3 + 2) ร— 4 = 0x1000 + 20 = 0x1014 โœ“
                        
2d_array_basics.c
#include <stdio.h>

int main() {
    // Declaration and initialization
    int matrix[3][3] = {
        {1, 2, 3},    // Row 0
        {4, 5, 6},    // Row 1
        {7, 8, 9}     // Row 2
    };
    
    // Access elements
    printf("Element at row 1, col 2: %d\n", matrix[1][2]);  // 6
    printf("Element at row 0, col 0: %d\n", matrix[0][0]);  // 1
    
    // Modify element
    matrix[1][1] = 50;
    printf("Updated middle element: %d\n", matrix[1][1]);
    
    // Traverse 2D array
    printf("\nMatrix:\n");
    for (int i = 0; i < 3; i++) {        // For each row
        for (int j = 0; j < 3; j++) {    // For each column
            printf("%d ", matrix[i][j]);
        }
        printf("\n");  // New line after each row
    }
    
    return 0;
}

๐Ÿงฎ Matrix Operations

๐Ÿ“Š Matrix Addition Step-by-Step

Matrix A:          Matrix B:          Result A + B:
โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”
โ”‚ 1 โ”‚ 2 โ”‚ 3 โ”‚     โ”‚ 9 โ”‚ 8 โ”‚ 7 โ”‚     โ”‚10 โ”‚10 โ”‚10 โ”‚
โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค  +  โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค  =  โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค
โ”‚ 4 โ”‚ 5 โ”‚ 6 โ”‚     โ”‚ 6 โ”‚ 5 โ”‚ 4 โ”‚     โ”‚10 โ”‚10 โ”‚10 โ”‚
โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค     โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค     โ”œโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ค
โ”‚ 7 โ”‚ 8 โ”‚ 9 โ”‚     โ”‚ 3 โ”‚ 2 โ”‚ 1 โ”‚     โ”‚10 โ”‚10 โ”‚10 โ”‚
โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”˜

Calculation:
result[i][j] = A[i][j] + B[i][j]

result[0][0] = A[0][0] + B[0][0] = 1 + 9 = 10
result[0][1] = A[0][1] + B[0][1] = 2 + 8 = 10
result[0][2] = A[0][2] + B[0][2] = 3 + 7 = 10
...and so on for all elements
                        
matrix_operations.c
#include 
#define ROWS 3
#define COLS 3

// Add two matrices
void addMatrices(int a[ROWS][COLS], int b[ROWS][COLS], int result[ROWS][COLS]) {
    for (int i = 0; i < ROWS; i++)
        for (int j = 0; j < COLS; j++)
            result[i][j] = a[i][j] + b[i][j];
}

// Transpose matrix (rows become columns)
void transpose(int matrix[ROWS][COLS], int trans[COLS][ROWS]) {
    for (int i = 0; i < ROWS; i++)
        for (int j = 0; j < COLS; j++)
            trans[j][i] = matrix[i][j];  // Swap row and column
}

// Print matrix
void printMatrix(int matrix[ROWS][COLS]) {
    for (int i = 0; i < ROWS; i++) {
        for (int j = 0; j < COLS; j++)
            printf("%d ", matrix[i][j]);
        printf("\n");
    }
}

int main() {
    int a[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int b[ROWS][COLS] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
    int result[ROWS][COLS];
    
    printf("Matrix A:\n");
    printMatrix(a);
    
    printf("\nMatrix B:\n");
    printMatrix(b);
    
    addMatrices(a, b, result);
    printf("\nA + B:\n");
    printMatrix(result);
    
    return 0;
}

๐Ÿ”— Arrays and Pointers Relationship

๐Ÿ’ก The Key Insight

In C, arrays and pointers are closely related. The array name is actually a pointer to the first element!

Array: int arr[5] = {10, 20, 30, 40, 50};

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  The array name "arr" is equivalent to &arr[0]               โ”‚
โ”‚                                                               โ”‚
โ”‚  Memory Layout:                                              โ”‚
โ”‚  Address     Value    Expression    Result                   โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€               โ”‚
โ”‚  0x1000  โ†’   10      arr[0]         10                      โ”‚
โ”‚  0x1004  โ†’   20      arr[1]         20                      โ”‚
โ”‚  0x1008  โ†’   30      arr[2]         30                      โ”‚
โ”‚  0x100C  โ†’   40      arr[3]         40                      โ”‚
โ”‚  0x1010  โ†’   50      arr[4]         50                      โ”‚
โ”‚                โ†‘                                              โ”‚
โ”‚              arr points here (address 0x1000)                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Equivalent Ways to Access Elements:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Array Notation โ”‚ Pointer Notation โ”‚  Value  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚     arr[0]      โ”‚      *arr       โ”‚    10   โ”‚
โ”‚     arr[1]      โ”‚    *(arr + 1)   โ”‚    20   โ”‚
โ”‚     arr[2]      โ”‚    *(arr + 2)   โ”‚    30   โ”‚
โ”‚     arr[i]      โ”‚    *(arr + i)   โ”‚    ...  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why does *(arr + 1) work?
โ€ข arr is address 0x1000
โ€ข arr + 1 adds sizeof(int) = 4 bytes
โ€ข So arr + 1 = 0x1004 (address of arr[1])
โ€ข *(arr + 1) dereferences to get value 20
                        
array_pointer.c
#include 

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;  // ptr points to first element
    
    // Both give the same address
    printf("arr = %p\n", (void*)arr);
    printf("\u0026arr[0] = %p\n", (void*)&arr[0]);
    printf("ptr = %p\n", (void*)ptr);
    
    // Different ways to access elements
    printf("\nElement at index 2:\n");
    printf("Using array: arr[2] = %d\n", arr[2]);
    printf("Using pointer: *(arr + 2) = %d\n", *(arr + 2));
    printf("Using ptr: ptr[2] = %d\n", ptr[2]);
    printf("Using ptr: *(ptr + 2) = %d\n", *(ptr + 2));
    
    // Pointer arithmetic
    printf("\nPointer arithmetic:\n");
    printf("*ptr = %d\n", *ptr);        // 10
    ptr++;                              // Move to next element
    printf("*ptr after ptr++ = %d\n", *ptr);  // 20
    
    return 0;
}

๐Ÿ“ค Passing Arrays to Functions

๐Ÿ’ก How It Works

When you pass an array to a function, you're actually passing a pointer to the first element. This means:

  • The function can modify the original array (pass by reference)
  • You must also pass the array size (the function can't determine it)
Passing Arrays to Functions:

1. ONE-DIMENSIONAL ARRAY
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  void modify(int arr[], int size) {    โ”‚
   โ”‚      // arr is a pointer to first elem โ”‚
   โ”‚      arr[0] = 100;  // Modifies originalโ”‚
   โ”‚  }                                     โ”‚
   โ”‚                                        โ”‚
   โ”‚  // Call:                              โ”‚
   โ”‚  int nums[5] = {1, 2, 3, 4, 5};        โ”‚
   โ”‚  modify(nums, 5);  // Pass name + size โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

2. TWO-DIMENSIONAL ARRAY
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚  // Column size MUST be specified!       โ”‚
   โ”‚  void print2D(int arr[][3], int rows) {โ”‚
   โ”‚      for (int i = 0; i < rows; i++)    โ”‚
   โ”‚          for (int j = 0; j < 3; j++)    โ”‚
   โ”‚              printf("%d ", arr[i][j]); โ”‚
   โ”‚  }                                     โ”‚
   โ”‚                                        โ”‚
   โ”‚  // Call:                              โ”‚
   โ”‚  int matrix[2][3] = {{1,2,3},{4,5,6}}; โ”‚
   โ”‚  print2D(matrix, 2);                   โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        
pass_arrays.c
#include 

// Pass 1D array - size needed
void doubleValues(int arr[], int size) {
    printf("Doubling values...\n");
    for (int i = 0; i < size; i++)
        arr[i] *= 2;  // Modifies original array!
}

// Pass 2D array - column size required
void print2D(int arr[][3], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 3; j++)
            printf("%d ", arr[i][j]);
        printf("\n");
    }
}

// Using pointers
void printWithPointer(int *arr, int size) {
    for (int i = 0; i < size; i++)
        printf("%d ", *(arr + i));
    printf("\n");
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printf("Before: ");
    printWithPointer(arr, size);
    
    doubleValues(arr, size);
    
    printf("After:  ");
    printWithPointer(arr, size);
    
    // 2D array
    int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
    printf("\n2D Array:\n");
    print2D(matrix, 2);
    
    return 0;
}

โš ๏ธ Common Mistakes and How to Avoid Them

MistakeWrong CodeCorrect Code
Off-by-one error
Using index 5 in array of size 5
int arr[5];
arr[5] = 10;
int arr[5];
arr[4] = 10;
// Valid: 0-4
Array out of bounds
Loop goes too far
for(i=0; i<=5; i++)
arr[i] = 0;
for(i=0; i<5; i++)
arr[i] = 0;
Confusing size with last index // Accessing last element
arr[size]
// Last element is at
arr[size-1]
Not passing size to function void func(int arr[]) {
// Can't find size!
}
void func(int arr[], int n) {
// Use n for size
}
Forgetting 2D array needs column size void func(int arr[][]) void func(int arr[][COLS])
Array assignment
Arrays can't be assigned
int a[3] = {1,2,3};
int b[3];
b = a; // ERROR!
// Copy element by element
for(i=0; i<3; i++)
b[i] = a[i];

๐Ÿ“ Practice Problems

Level 1: Beginner

  1. Sum and Average: Write a program to read 10 numbers into an array and calculate their sum and average.
  2. Find Maximum: Find the largest number in an array of 20 integers.
  3. Count Even/Odd: Count how many even and odd numbers are in an array.

Level 2: Intermediate

  1. Reverse Array: Reverse an array without using a second array.
  2. Linear Search: Implement a search that returns all indices where the element appears.
  3. Matrix Diagonal Sum: Calculate the sum of diagonal elements in a square matrix.

Level 3: Advanced

  1. Matrix Multiplication: Multiply two matrices (must check dimensions are compatible).
  2. Transpose In-Place: Transpose a square matrix without using extra space.
  3. Rotate Matrix: Rotate a matrix 90 degrees clockwise.