Pointers in C
Learn pointers using simple analogies and visual diagrams β no more confusion about * and &!
π€ What is a Pointer? (Simple Analogies)
π‘ Analogy 1: The Mailbox
Imagine a variable is like a mailbox at your house:
π Your House (Memory)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Mailbox #42 Mailbox #50 β
β ββββββββββββ ββββββββββββ β
β β π¬ #42 β β π¬ #50 β β
β β Value: β β Value: β β
β β 100 β β 0x002A β β This is a β
β β (int) β β (address)β POINTER! β
β ββββββββββββ ββββββββββββ β
β β β β
β β β β
β Regular Variable Pointer Variable β
β (stores a number) (stores an address) β
β β
β The pointer at #50 "points to" mailbox #42! β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Insight:
β’ A regular variable stores a VALUE (like 100)
β’ A pointer variable stores an ADDRESS (like 0x002A = #42)
πΊοΈ Analogy 2: The Treasure Map
A pointer is like a treasure map:
πΊοΈ Treasure Map Analogy
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Treasure Chest (Variable) Treasure Map β
β ββββββββββββββββ ββββββββββββββββ β
β β πππππ β β πΊοΈ MAP β β
β β β β β β
β β Location: β β "Go to the β β
β β Old Oak Tree β β Old Oak β β
β β β β Tree" β β
β β Contents: ββββββββββββββββββ β β
β β 500 Gold β Points to β Address: β β
β ββββββββββββββββ β "Old Oak" β β
β ββββββββββββββββ β
β β
β The map doesn't HAVE the treasure β it tells you β
β WHERE to find it! β
β β
β Similarly, a pointer doesn't HAVE the value β β
β it tells you WHERE the value is stored! β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π·οΈ Analogy 3: The Label on a Box
Think of memory like a storage unit facility:
π Storage Facility (Memory)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Unit A-12 Unit B-05 β
β ββββββββββββββ ββββββββββββββ β
β β π¦ Unit β β π¦ Unit β β
β β A-12 β β B-05 β β
β β β β β β
β β Contents: β β Contents: β β
β β "Bicycle" β β "See A-12" β β This is a β
β ββββββββββββββ ββββββββββββββ pointer! β
β β² β β
β β β β
β ββββββββββββββββββββββββ β
β β
β Unit B-05 contains directions to Unit A-12! β
β If you follow the directions, you find the bike. β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Summary: A pointer is a variable that stores a memory address instead of a regular value. It "points to" another location in memory where the actual data lives.
πΎ Visual Memory Diagrams
π How Memory Actually Looks
Let's see what happens when we create a variable and a pointer:
BEFORE: Creating Variables
Code: int num = 42;
Memory Layout:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Address Variable Value Type β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 0x1000 num 42 int β
β 0x1004 (empty) - - β
β 0x1008 (empty) - - β
β 0x100C (empty) - - β
β ... ... ... ... β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The computer assigns address 0x1000 to variable 'num'
It stores the value 42 at that location
AFTER: Creating a Pointer
Code: int *ptr = #
Memory Layout:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Address Variable Value Type/Notes β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 0x1000 num 42 int β
β β² β
β β β
β 0x1004 β ptr 0x1000 int* (pointer) β
β β β β
β β β β
β ββββββββββββββββ β
β ptr stores the address of num! β
β 0x1008 (empty) - - β
β 0x100C (empty) - - β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ptr is a pointer variable that lives at 0x1004
It stores the value 0x1000 (which is num's address)
We say "ptr points to num"
π Step-by-Step: Pointer Assignment
Step-by-Step: What happens with each line?
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Code: int num = 100; β
β β
β Memory: βββββββββββ β
β Address β Value β β
β 0x1000 β 100 β β num lives here β
β βββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Code: int *ptr = # β
β β
β Memory: βββββββββββ βββββββββββ β
β Address β Value β β Value β β
β 0x1000 β 100 ββββββ 0x1000 β β
β β num β β ptr β β
β βββββββββββ βββββββββββ β
β β β
β ptr stores num's address β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Code: *ptr = 200; β Dereferencing! β
β β
β What happens: β
β 1. *ptr means "go to the address stored in ptr" β
β 2. ptr has 0x1000, so go to address 0x1000 β
β 3. Change the value at 0x1000 to 200 β
β β
β Memory: βββββββββββ βββββββββββ β
β Address β Value β β Value β β
β 0x1000 β 200 ββββββ 0x1000 β β
β β num β β ptr β β
β βββββββββββ βββββββββββ β
β β
β Now num = 200! We changed it through the pointer! β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π― Understanding * and & Operators
π The & (Address-of) Operator
& means "get the address of" β it's like asking "where does this variable live?"
& (Address-of) Explained
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β int score = 95; β
β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β &score β "Where is score stored?" β β
β β β β
β β Answer: 0x1000 (or some address) β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β
β Think of it like: β
β "What's the address of score's house?" β
β "Where in memory does score live?" β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Example:
int num = 42;
printf("%p", &num); // Prints something like 0x7ffe1234
β The * (Dereference) Operator
* means "go to the address" or "get the value at" β it's like following a treasure map!
* (Dereference) Explained
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β int num = 42; β
β int *ptr = # // ptr = address of num β
β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β *ptr β "Go to the address in ptr" β β
β β β β
β β ptr has &num (address 0x1000) β β
β β *ptr means: Go to 0x1000 and get value β β
β β Answer: 42 β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β
β Think of it like: β
β "Follow the map to find the treasure!" β
β "Go to that address and tell me what's there" β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Example:
int num = 42;
int *ptr = #
printf("%d", *ptr); // Prints 42 (the value at that address)
π΅ Common Confusion: * in Declaration vs * in Usage
This trips everyone up! The same symbol * does different things:
CRITICAL DISTINCTION: * in different contexts
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Context 1: DECLARATION (Creating a pointer) β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β
β int *ptr; β
β β β
β This * says "ptr is a POINTER to int" β
β β
β β This creates a new pointer variable β
β β It's part of the TYPE declaration β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Context 2: USAGE (Dereferencing a pointer) β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β
β *ptr = 100; β
β β β
β This * says "go to address stored in ptr" β
β β
β β This ACCESS/CHANGES the value being pointed to β
β β It's an OPERATION on an existing pointer β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Side-by-Side Comparison: β
β β
β int *p = &x; β * in declaration β
β // β β
β // "p is a pointer to int" β
β β
β *p = 50; β * in usage β
β //β β
β // "Go to the address in p and put 50 there" β
β β
β int y = *p; β * in usage β
β // β β
β // "Go to the address in p and get the value" β
β β
β Memory Aid: β
β β’ Declaration * = "This is a pointer" π β
β β’ Usage * = "Follow the pointer" πΆ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Your First Pointer Example
π Step-by-Step Execution Trace
Watch how memory changes with each line:
Code Trace: first_pointer.c
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Line 1: int num = 10; β
β β
β Memory: β
β βββββββββββββββββββ β
β β Address: 0x1000 β β
β β num = 10 β β
β βββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Line 2: int *ptr = # β
β β
β Memory: β
β βββββββββββββββββββ βββββββββββββββββββ β
β β Address: 0x1000 β β Address: 0x1004 β β
β β num = 10 ββββββ ptr = 0x1000 β β
β βββββββββββββββββββ βββββββββββββββββββ β
β β β
β ptr "points to" num β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Line 3: printf("%d", *ptr); β
β β
β Output: 10 β
β Why? *ptr means "go to 0x1000, get value" β 10 β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Line 4: *ptr = 20; β
β β
β Memory: β
β βββββββββββββββββββ βββββββββββββββββββ β
β β Address: 0x1000 β β Address: 0x1004 β β
β β num = 20 βββββββββββββ ptr = 0x1000 β β
β βββββββββββββββββββ βββββββββββββββββββ β
β We changed num THROUGH the pointer! β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Line 5: printf("%d", num); β
β β
β Output: 20 β
β Even though we didn't touch num directly! β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#include <stdio.h>
int main() {
// Step 1: Create a regular variable
int num = 10;
printf("1. num = %d\n", num); // Output: 10
// Step 2: Create a pointer that points to num
int *ptr = #
printf("2. &num = %p\n", (void*)&num); // Address of num
printf("3. ptr = %p\n", (void*)ptr); // Same address!
// Step 3: Access value through pointer (dereferencing)
printf("4. *ptr = %d\n", *ptr); // Output: 10
// Step 4: Change value through pointer
*ptr = 20;
printf("5. After *ptr = 20:\n");
printf(" num = %d\n", num); // Output: 20
printf(" *ptr = %d\n", *ptr); // Output: 20
// Step 5: Change num directly
num = 30;
printf("6. After num = 30:\n");
printf(" num = %d\n", num); // Output: 30
printf(" *ptr = %d\n", *ptr); // Output: 30
return 0;
}
β Pointer Arithmetic Visualized
π Why ptr + 1 Doesn't Just Add 1
Pointer arithmetic is smart β it knows the size of what it points to!
Pointer Arithmetic Explained
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Array: int arr[5] = {10, 20, 30, 40, 50}; β
β β
β Memory Layout (int = 4 bytes): β
β βββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ¬ββββββββββ β
β βarr[0] βarr[1] βarr[2] βarr[3] βarr[4] β β
β β 10 β 20 β 30 β 40 β 50 β β
β β β β β β β β
β β 0x1000 β 0x1004 β 0x1008 β 0x100C β 0x1010 β β
β ββββββ¬βββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ΄ββββββββββ β
β β β
β ββ ptr = &arr[0] = 0x1000 β
β β
β Now let's do pointer arithmetic: β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β Expression β Calculation β Result ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β
β β ptr β 0x1000 β Points to arr[0] ββ
β β ptr + 1 β 0x1000 + 4 β Points to arr[1] ββ
β β ptr + 2 β 0x1000 + 8 β Points to arr[2] ββ
β β ptr + 3 β 0x1000 + 12 β Points to arr[3] ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Key Insight: ptr + 1 adds sizeof(int) = 4 bytes! β
β β
β Why? Because ptr knows it's an "int*" pointer! β
β It automatically multiplies by sizeof(int) β
β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β What you write β What actually happens ββ
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β
β β ptr + 1 β ptr + (1 Γ sizeof(int)) ββ
β β β ptr + (1 Γ 4) = ptr + 4 ββ
β β ββ
β β ptr + 3 β ptr + (3 Γ sizeof(int)) ββ
β β β ptr + (3 Γ 4) = ptr + 12 ββ
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β This is why *(ptr + 1) gives you arr[1], not garbage! β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Visual Array Traversal
Array Traversal with Pointer Arithmetic
int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr points to arr[0]
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Initial State: β
β βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ β
β β 10 β 20 β 30 β 40 β 50 β β
β ββββ¬βββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ β
β β β
β ptr β
β β
β Iteration 1: printf("%d", *ptr); β Prints 10 β
β ptr++; β
β βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ β
β β 10 β 20 β 30 β 40 β 50 β β
β βββββββ·βββ¬βββ΄ββββββ΄ββββββ΄ββββββ β
β β β
β ptr β
β β
β Iteration 2: printf("%d", *ptr); β Prints 20 β
β ptr++; β
β βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ β
β β 10 β 20 β 30 β 40 β 50 β β
β βββββββ΄ββββββ·βββ¬βββ΄ββββββ΄ββββββ β
β β β
β ptr β
β β
β And so on... β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr; // Points to first element
int n = 5;
printf("Array elements using pointer arithmetic:\n");
for (int i = 0; i < n; i++) {
printf("*(ptr + %d) = %d\n", i, *(ptr + i));
}
printf("\nUsing ptr++ to move through array:\n");
ptr = arr; // Reset to beginning
for (int i = 0; i < n; i++) {
printf("*ptr = %d, ptr = %p\n", *ptr, (void*)ptr);
ptr++; // Move to next element
}
// Arrays and pointers are closely related!
printf("\nArray[i] is the same as *(array + i):\n");
for (int i = 0; i < n; i++) {
printf("arr[%d] = %d, *(arr + %d) = %d\n",
i, arr[i], i, *(arr + i));
}
return 0;
}
π Pointer to Pointer (Double Pointer)
π‘ The "Address of an Address"
A pointer to a pointer is like a map to a map!
Pointer to Pointer Visual
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β int num = 42; β
β int *ptr = # // ptr points to num β
β int **pptr = &ptr; // pptr points to ptr β
β β
β Memory Diagram: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Address 0x1000: num = 42 β β
β β β β β
β β β β β
β β Address 0x1004: ptr = 0x1000 βββββ β β
β β β β β β
β β β β β β
β β Address 0x1008: pptr = 0x1004 βββ β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Accessing Values: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Expression β Meaning β Result β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β num β Direct value β 42 β β
β β *ptr β Follow ptr once β 42 β β
β β **pptr β Follow pptr twice β 42 β β
β β ptr β Address of num β 0x1000 β β
β β *pptr β Address of num β 0x1000 β β
β β pptr β Address of ptr β 0x1004 β β
β β &pptr β Address of pptr β 0x1008 β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#include <stdio.h>
int main() {
int num = 42;
int *ptr = # // Pointer to int
int **pptr = &ptr; // Pointer to pointer
printf("Value of num: %d\n", num);
printf("Value of *ptr: %d\n", *ptr);
printf("Value of **pptr: %d\n", **pptr);
printf("\nAddress of num: %p\n", (void*)&num);
printf("Value of ptr: %p\n", (void*)ptr);
printf("Value of *pptr: %p\n", (void*)*pptr);
printf("\nAddress of ptr: %p\n", (void*)&ptr);
printf("Value of pptr: %p\n", (void*)pptr);
// Modify through double pointer
**pptr = 100;
printf("\nAfter **pptr = 100, num = %d\n", num);
return 0;
}
π Arrays and Pointers Relationship
π‘ The Key Insight
In C, array names are essentially pointers to the first element!
Array Name as Pointer
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // Same as: int *ptr = &arr[0];
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Memory Layout: β
β βββββββ¬ββββββ¬ββββββ¬ββββββ¬ββββββ β
β β 10 β 20 β 30 β 40 β 50 β β
β ββββ¬βββ΄ββββββ΄ββββββ΄ββββββ΄ββββββ β
β β β
β ββ arr (the array name points here) β
β β β
β ββ ptr (our pointer also points here) β
β β
β Equivalence Table: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Array Notation β Pointer Notation β Value β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ€ β
β β arr[0] β *arr or *ptr β 10 β β
β β arr[1] β *(arr+1) or *(ptr+1)β 20 β β
β β arr[2] β *(arr+2) or *(ptr+2)β 30 β β
β β arr[i] β *(arr+i) or *(ptr+i)β ... β β
β β &arr[0] β arr or ptr β address β β
β β &arr[i] β arr+i or ptr+i β address β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Important Differences: β
β β’ arr is a CONSTANT pointer (can't do arr++) β
β β’ ptr is a VARIABLE pointer (can do ptr++) β
β β’ sizeof(arr) gives total array size β
β β’ sizeof(ptr) gives pointer size (4 or 8 bytes) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β οΈ Common Pointer Mistakes
| Mistake | Problem | Correct Code | Visual |
|---|---|---|---|
| Uninitialized Pointer | Pointer points to random memory | int *p = NULL;// orint *p = &x; |
ptr β ??? (Dangerous!) |
| NULL Pointer Dereference | Trying to access NULL pointer | if (p != NULL) *p = 10; |
ptr β NULL Check first! |
| Dangling Pointer | Pointing to freed memory | free(ptr);ptr = NULL; |
ptr β [FREED] Set to NULL! |
| Memory Leak | Allocated memory not freed | int *p = malloc(...);// use p...free(p); |
malloc β use β free Don't forget! |
| Confusing * and & | Using wrong operator | // Get address: &x// Get value: *p |
& = "where" * = "what's there" |
| Pointer Type Mismatch | Wrong pointer type | int *ip;char *cp;// Don't mix! |
int* vs char* Different sizes! |
π¨ Uninitialized Pointer Danger
β DANGEROUS: Uninitialized Pointer
int *ptr; // ptr contains GARBAGE address!
*ptr = 10; // Writing to random memory!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Memory: β
β β
β ptr = ??? (could be 0xABCDEF00 or anything) β
β β β
β βΌ β
β [RANDOM MEMORY] β Writing here! β
β β
β This could: β
β β’ Crash your program (Segmentation Fault) β
β β’ Corrupt other data silently β
β β’ Work "sometimes" (worst bug!) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
SAFE: Initialize Your Pointers!
int *ptr = NULL; // Now ptr = 0, a safe value
// OR
int x = 10;
int *ptr = &x; // Points to valid memory
πΎ Dynamic Memory with Pointers
π malloc() and free() Basics
Dynamic Memory Allocation
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Step 1: Allocate memory β
β β
β int *arr = malloc(5 * sizeof(int)); β
β β
β Memory: β
β βββββββββββββββββββββββββββ β
β β Heap: 5 integers β β
β β [?][?][?][?][?] β β
β ββββ¬βββββββββββββββββββββββ β
β β β
β ββ arr stores this address β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Step 2: Use the memory β
β β
β for (int i = 0; i < 5; i++) β
β arr[i] = i + 1; // or *(arr + i) = i + 1; β
β β
β Memory: β
β βββββββββββββββββββββββββββ β
β β Heap: β β
β β [1][2][3][4][5] β β
β ββββ¬βββββββββββββββββββββββ β
β β β
β ββ arr still points here β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Step 3: Free the memory β
β β
β free(arr); β
β arr = NULL; // Good practice! β
β β
β Memory: β
β βββββββββββββββββββββββββββ β
β β Heap: [FREED] β β
β βββββββββββββββββββββββββββ β
β β
β arr = NULL; // Now safe to check: if (arr != NULL) β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
// Allocate memory for n integers
int *arr = (int*)malloc(n * sizeof(int));
// Always check if allocation succeeded!
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Initialize the array
for (int i = 0; i < n; i++) {
arr[i] = (i + 1) * 10; // 10, 20, 30, 40, 50
}
// Print values
printf("Array values: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// CRITICAL: Free the allocated memory
free(arr);
arr = NULL; // Prevent dangling pointer
printf("Memory freed successfully!\n");
return 0;
}
π― Quick Reference Summary
π Pointer Cheat Sheet
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β POINTER CHEAT SHEET β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β DECLARATION: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β int *ptr; // Pointer to int β β
β β char *cptr; // Pointer to char β β
β β float *fptr; // Pointer to float β β
β β void *vptr; // Generic pointer β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β OPERATORS: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β &variable // Get address of variable β β
β β *pointer // Get value at address β β
β β pointer->field // Access struct field β β
β β (*pointer).field // Same as above β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β COMMON PATTERNS: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β int x = 10; β β
β β int *p = &x; // p points to x β β
β β int y = *p; // y = 10 (dereference) β β
β β *p = 20; // x = 20 (modify through p) β β
β β p++; // Move to next int β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β DYNAMIC MEMORY: β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β malloc(n) // Allocate n bytes β β
β β calloc(n, size) // Allocate n items, init 0 β β
β β realloc(ptr, n) // Resize allocation β β
β β free(ptr) // Release memory β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β BEST PRACTICES: β
β β’ Always initialize pointers (to NULL or valid addr) β
β β’ Check for NULL before dereferencing β
β β’ Every malloc() needs a free() β
β β’ After free(), set pointer to NULL β
β β’ Don't return pointers to local variables β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π Practice Problems
Level 1: Beginner
- Swap Using Pointers: Write a function that swaps two integers using pointers.
- Array Sum: Calculate the sum of an array using pointer arithmetic instead of array indexing.
- Print Address: Create variables of different types and print their addresses. Notice how they're spaced.
Level 2: Intermediate
- Reverse Array: Reverse an array in place using two pointers (one at start, one at end).
- Dynamic Array: Create a program that allocates an array of size n, fills it with values, then resizes it.
- String Length: Implement strlen() using a pointer (count until '\0').
Level 3: Advanced
- Matrix with Pointers: Allocate a 2D array dynamically using pointer to pointer.
- Linked List Node: Create a simple linked list node structure and traverse it using pointers.
- Function Pointer: Use a function pointer to call different math operations.