← C EnglishChapter 07 of 13

Pointers

## Learning Objectives - Understand pointer basics - Master pointer operations - Work with pointers and arrays - Learn pointer arithmetic ## What is a Pointer? A pointer is a variable that stores the memory address of another variable. ```c int x = 10; int *ptr = &x; // ptr holds address of x printf("%d\n", x); // Value of x: 10 printf("%p\n", ptr); // Address of x printf("%d\n", *ptr); // Value at address: 10 ``` ## Pointer Declaration ### Syntax ```c int *ptr; // Pointer to int char *cptr; // Pointer to char float *fptr; // Pointer to float double *dptr; // Pointer to double ``` ### Common Confusion ```c int *p1, p2; // p1 is pointer, p2 is int (not both!) int *p1, *p2; // Both are pointers ``` ## Address Operator (&) ```c int x = 10; int *ptr = &x; // &x gives address of x printf("Address of x: %p\n", &x); printf("ptr contains: %p\n", ptr); ``` ## Dereference Operator (*) ```c int x = 10; int *ptr = &x; printf("%d\n", *ptr); // 10 (value at address) *ptr = 20; // Modify value through pointer printf("%d\n", x); // 20 (x is now 20) ``` ## NULL Pointer ### Declaration ```c int *ptr = NULL; // Good practice - initialize to NULL ``` ### Check Before Use ```c int *ptr = NULL; if (ptr != NULL) { printf("%d\n", *ptr); } ``` ### Uninitialized vs NULL ```c int *p1; // Uninitialized - garbage value int *p2 = NULL; // NULL pointer - safe to check ``` ## Pointers and Arrays ### Array Name as Pointer ```c int arr[] = {1, 2, 3, 4, 5}; int *ptr = arr; // arr decays to pointer to first element printf("%d\n", *ptr); // 1 (first element) printf("%d\n", *(ptr + 1)); // 2 (second element) ``` ### Equivalence ```c arr[i] == *(arr + i) &arr[i] == arr + i ``` ### Array Index with Pointer ```c int arr[] = {10, 20, 30}; int *ptr = arr; printf("%d\n", ptr[0]); // 10 printf("%d\n", ptr[1]); // 20 ``` ## Pointer Arithmetic ### Increment/Decrement ```c int arr[] = {10, 20, 30}; int *ptr = arr; ptr++; // Move to next int printf("%d\n", *ptr); // 20 ptr--; // Move to previous int printf("%d\n", *ptr); // 10 ``` ### Addition/Subtraction ```c int arr[] = {10, 20, 30, 40, 50}; int *ptr = arr; printf("%d\n", *(ptr + 2)); // 30 printf("%d\n", *(ptr + 4)); // 50 ptr = &arr[4]; printf("%d\n", *(ptr - 2)); // 30 ``` ### Difference Between Pointers ```c int arr[] = {10, 20, 30, 40, 50}; int *p1 = &arr[0]; int *p2 = &arr[4]; ptrdiff_t diff = p2 - p1; // 4 ``` ## Pointers and Functions ### Pass by Reference ```c void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int main(void) { int x = 10, y = 20; swap(&x, &y); printf("%d %d\n", x, y); // 20 10 return 0; } ``` ### Array Parameter ```c int sum(int *arr, int size) { int total = 0; for (int i = 0; i < size; i++) { total += arr[i]; // or *(arr + i) } return total; } int main(void) { int nums[] = {1, 2, 3, 4, 5}; printf("%d\n", sum(nums, 5)); // 15 return 0; } ``` ## const with Pointers ### Pointer to const ```c const int x = 10; const int *ptr = &x; // *ptr = 20; // Error! Cannot modify through pointer ``` ### const Pointer ```c int x = 10; int y = 20; int *const ptr = &x; *ptr = 30; // OK - can modify value // ptr = &y; // Error! Cannot change where ptr points ``` ### const Pointer to const ```c const int x = 10; const int *const ptr = &x; // Cannot modify value or change address ``` ## Pointer to Pointer ```c int x = 10; int *p1 = &x; int **p2 = &p1; // Pointer to pointer printf("%d\n", **p2); // 10 ``` ### Use Case: Modify pointer in function ```c void allocate(int **ptr) { *ptr = malloc(sizeof(int)); **ptr = 42; } int main(void) { int *p = NULL; allocate(&p); printf("%d\n", *p); // 42 free(p); return 0; } ``` ## void Pointer ### Generic Pointer ```c void *ptr; // Can point to any type int x = 10; double y = 3.14; ptr = &x; // printf("%d\n", *ptr); // Error! Cannot dereference void* printf("%d\n", *(int*)ptr); // Cast to int* ptr = &y; printf("%f\n", *(double*)ptr); // Cast to double* ``` ### Use with malloc ```c void *malloc(size_t size); void *memcpy(void *dest, const void *src, size_t n); ``` ## Dynamic Memory (malloc/free) ```c #include int *ptr = (int*)malloc(sizeof(int)); if (ptr == NULL) { // Allocation failed return 1; } *ptr = 42; printf("%d\n", *ptr); free(ptr); // Release memory ptr = NULL; // Avoid dangling pointer ``` ## Pointers to Functions ```c int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } int main(void) { int (*operation)(int, int); operation = add; printf("%d\n", operation(5, 3)); // 8 operation = subtract; printf("%d\n", operation(5, 3)); // 2 return 0; } ``` ## Common Pitfalls ### Dangling Pointer ```c int *ptr = malloc(sizeof(int)); free(ptr); // ptr still points to freed memory - BAD! ptr = NULL; // Always set to NULL after free ``` ### Double Free ```c free(ptr); free(ptr); // Undefined behavior! ``` ### Memory Leak ```c int *ptr = malloc(sizeof(int)); ptr = malloc(sizeof(int)); // First allocation leaked free(ptr); ``` ### Uninitialized Pointer ```c int *ptr; // *ptr = 10; // Undefined! Points to garbage ptr = malloc(sizeof(int)); // Initialize first *ptr = 10; free(ptr); ``` ## Summary - Pointers store memory addresses - `*` declares pointer and dereferences - `&` gets address of a variable - NULL is safe; uninitialized is dangerous - Array name decays to pointer - Pointer arithmetic: `ptr + n`, `ptr - n` - Use `const` to prevent modification - `void*` can point to any type - Always `free()` dynamically allocated memory - Set pointers to NULL after freeing

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →