Pointers in C provide direct access to memory addresses, making them essential for low-level programming and performance optimization. This article explores pointer fundamentals, usage patterns, and advanced techniques.
Pointer Fundamentals
A pointer is a variable that stores a memory address. To declare a pointer, use the syntax:
Type *pointerName;
Where Type specifies the data type the pointer references. For example, int *ptr; declares a pointer to an integer.
Addressing and Dereferencing
Every memory location has a unique address. When a variable is declared, the system allocates space and assigns it an address. The address operater & retrieves a variable's address, while the dereference operator * accesses the value at that adress.
Example:
int value = 10;
int *ptr = &value;
printf("Address: %p\n", ptr);
printf("Value: %d\n", *ptr);
Pointer Arithmetic
Pointer arithmetic allows navigation through arrays using mathematical operations. When a pointer points to an array element, operations like ptr + 1 move to the next element based on the size of the data type.
int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr;
printf("First element: %d\n", *ptr);
printf("Second element: %d\n", *(ptr + 1));
Arrays and Pointers
Arrays and pointers are closely related in C. An array name represents the address of its first element, and array indexing is equivalent to pointer arithmetic:
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // Same as &arr[0]
printf("Element 2: %d\n", *(ptr + 2)); // Equivalent to arr[2]
Function Parameters
Pointers can be passed to functions to modify variables directly:
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 5, y = 10;
swap(&x, &y);
printf("x = %d, y = %d\n", x, y);
return 0;
}
Multi-dimensional Arrays
Multi-dimensional arrays can also be accessed via pointers. For a 2D array int matrix[3][4], the expression matrix[i] yields a pointer to the i-th row:
int matrix[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int *row = matrix[1]; // Points to second row
printf("Element [1][2]: %d\n", *(row + 2));
String Handling
Strings in C are character arrays terminated by null characters. They can be handled using either character arrays or character pointers:
char str1[] = "Hello";
char *str2 = "World";
// Copy string using pointers
char *src = "Source";
char dest[10];
while ((*dest++ = *src++) != '\0');
Function Pointers
Function pointers store addresses of functions and enable dynamic function calls:
int add(int a, int b) { return a + b; }
int main() {
int (*operation)(int, int) = add;
int result = operation(3, 4);
printf("Result: %d\n", result);
return 0;
}
Pointer to Pointers
A pointer to a pointer holds the address of another pointer:
int value = 42;
int *ptr = &value;
int **doublePtr = &ptr;
printf("Value: %d\n", **doublePtr); // Accesses value through double indirection
Dynamic Memory Allocation
Memory allocation functions like malloc and free allow runtime memory management:
int *dynamicArray = (int*)malloc(5 * sizeof(int));
if (dynamicArray != NULL) {
for (int i = 0; i < 5; i++) {
dynamicArray[i] = i * 10;
}
free(dynamicArray);
}
Pointer concepts form the foundation of efficient C programming. Understanding these mechanisms enables developers to write more flexible and performant code.