Unit 3: Arrays and Pointers

Table of Contents

1. Arrays

An array is a fixed-size, sequential collection of elements of the same data type. Elements are stored in contiguous memory locations.

One-dimensional and Multi-dimensional Arrays

Passing Arrays to Functions

When you pass an array to a function, you are actually passing a pointer to its first element. The function can modify the original array.

// Both function prototypes are identical:
void printArray(int arr[], int size);
void printArray(int *arr, int size); 

void modify(int arr[]) {
    arr[0] = 100; // This changes the ORIGINAL array
}

int main() {
    int data[3] = {1, 2, 3};
    modify(data);
    printf("%d", data[0]); // Prints 100
    return 0;
}

Arrays and Strings

In C, a string is simply a one-dimensional array of char that is terminated by a special null character ('\0').

char name[] = "Hello"; // 6 bytes: 'H','e','l','l','o','\0'
char str[10]; // Can hold a string of up to 9 chars + null

2. Pointers: Introduction

A pointer is a variable whose value is the memory address of another variable.

Two key operators:

int x = 10;
int *ptr;  // 'ptr' is a pointer to an integer

ptr = &x; // 'ptr' now holds the address of 'x'

printf("%d\n", *ptr); // Prints 10 (the value at the address)
*ptr = 20;            // Changes the value of 'x' to 20
printf("%d\n", x);    // Prints 20

Pointer Declaration

The data type of the pointer must match the data type of the variable it points to.

int *i_ptr;     // Pointer to an int
char *c_ptr;    // Pointer to a char
float *f_ptr;   // Pointer to a float

Pointers and Function Arguments

To modify a variable from main() inside another function, you must pass a pointer to it. This is called "pass by reference."

// 'x_ptr' holds the address of 'num'
void increment(int *x_ptr) {
    (*x_ptr) = (*x_ptr) + 1; // Modifies the original 'num'
}

int main() {
    int num = 10;
    increment(&num); // Pass the address of 'num'
    printf("%d\n", num); // Prints 11
    return 0;
}

3. Pointers and Arrays

In C, pointers and arrays are very closely related. The name of an array "decays" to a pointer to its first element.

arr is equivalent to &arr[0]
arr[i] is equivalent to *(arr + i)
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // Same as int *ptr = &arr[0];

printf("%d\n", arr[2]); // Prints 30
printf("%d\n", *(arr + 2)); // Prints 30
printf("%d\n", ptr[2]); // Prints 30
printf("%d\n", *(ptr + 2)); // Prints 30

Address Arithmetic

When you add an integer n to a pointer ptr, the address is not incremented by n. It is incremented by n * sizeof(*ptr).

This is why ptr + 1 automatically points to the *next element* in an array, regardless of whether it's an int (4 bytes) or char (1 byte).

Character Pointers and Functions

A pointer to a char is often used to work with strings.

char *str = "Hello World"; // Points to a string literal
                          // This string is read-only!

// A common C function using char pointers
int str_length(char *s) {
    int len = 0;
    while (*s != '\0') {
        len++;
        s++; // Move pointer to next character
    }
    return len;
}

4. Advanced Pointers [cite: 224-225]

Pointer Arrays (Arrays of Pointers)

This is an array where each element is a pointer. This is often used to store a list of strings.

// 'names' is an array of 3 pointers to char
char *names[3] = {
    "Alice",
    "Bob",
    "Charlie"
};
printf("%s\n", names[1]); // Prints "Bob"

Pointers to Pointers

A "double pointer" stores the address of *another pointer*.

int x = 10;
int *p = &x;     // 'p' points to 'x'
int **pp = &p; // 'pp' points to 'p'

printf("%d\n", **pp); // Prints 10 (dereference twice)

This is used for functions that need to modify a pointer (e.g., in dynamic memory allocation) and for argv in main().

Pointers and Multi-dimensional Arrays

The name of a 2D array matrix decays to a pointer to its first *row*. This is a "pointer to an array," not a "pointer to a pointer."

int matrix[2][3] = {{1,2,3}, {4,5,6}};

// 'p' is a pointer to an array of 3 integers
int (*p)[3] = matrix; 

printf("%d\n", *(*(p + 1) + 2)); // Prints 6 (matrix[1][2])
int *p[3] (array of 3 pointers to int) is very different from int (*p)[3] (pointer to one array of 3 ints). This is a common exam question.

5. Special Topics

Command Line Arguments

C programs can receive arguments from the command line when executed (e.g., ./myprog file.txt). This is handled by main()'s parameters.

// argc: Argument Count (number of strings)
// argv: Argument Vector (array of strings)
int main(int argc, char *argv[]) {
    printf("You ran the program with %d arguments.\n", argc);

    // argv[0] is always the program's own name
    printf("Program name: %s\n", argv[0]); 

    if (argc > 1) {
        printf("First argument: %s\n", argv[1]);
    }
    return 0;
}

Pointers to Functions

Just as pointers can store addresses of variables, they can also store the address of a function. This allows you to treat functions as arguments to other functions.

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

// 'funcPtr' is a pointer to a function that
// takes two ints and returns an int
int (*funcPtr)(int, int);

// Assign the pointer
funcPtr = &add; // or just funcPtr = add;

// Call the function via the pointer
int result = funcPtr(10, 5); // result is 15

// Re-assign the pointer
funcPtr = &subtract;
result = funcPtr(10, 5); // result is 5

// --- Passing functions to other functions ---
int doOperation(int x, int y, int (*op)(int, int)) {
    return op(x, y);
}

int main() {
    int sum = doOperation(20, 10, &add);      // sum is 30
    int diff = doOperation(20, 10, &subtract); // diff is 10
    return 0;
}