Day 8: Pointers#
Overview#
Pointers are one of the most powerful and important features of C. A pointer is a variable that stores the memory address of another variable. Today we’ll demystify pointers and learn how to use them effectively.
What We’ll Learn Today#
- What are pointers and why they matter
- Address-of operator (&)
- Dereference operator (*)
- Declaring and using pointers
- Pointer arithmetic
- Pointers and arrays
- Passing by reference
Understanding Memory#
Every variable in C occupies memory at a specific address:
int x = 42;
// x is stored at some memory location, say 0x7fff5fbff8c
The Address-of Operator (&)#
Gets the memory address of a variable:
#include <stdio.h>
int main() {
int x = 42;
printf("Value of x: %d\n", x); // 42
printf("Address of x: %p\n", &x); // 0x7fff5fbff8c (varies)
return 0;
}Note: %p prints addresses in hexadecimal format.
What are Pointers?#
A pointer is a variable that stores a memory address:
int* ptr; // Declare a pointer to an int
The Dereference Operator (*)#
Accesses the value at the address the pointer points to:
int x = 42;
int* ptr = &x; // ptr now points to x
printf("Value at pointer: %d\n", *ptr); // 42
Complete Pointer Example#
#include <stdio.h>
int main() {
int x = 42; // Variable
int* ptr = &x; // Pointer to x
printf("x = %d\n", x); // 42
printf("Address of x: %p\n", &x); // 0x...
printf("ptr stores: %p\n", ptr); // 0x... (same as &x)
printf("Value at ptr: %d\n", *ptr); // 42
// Modify through pointer
*ptr = 100;
printf("x is now: %d\n", x); // 100
return 0;
}Output:
x = 42
Address of x: 0x7fff5fbff8c
ptr stores: 0x7fff5fbff8c
Value at ptr: 42
x is now: 100Pointer Syntax#
int x = 5;
int* ptr = &x; // Read: "ptr is a pointer to int, pointing to x"
// Access value: *ptr (dereference)
printf("%d\n", *ptr); // 5
// Access address: ptr
printf("%p\n", ptr); // 0x...
Common Confusion: * in Two Contexts#
// Declaration: * means "pointer to"
int* ptr; // ptr is a pointer to int
// Dereference: * means "value at"
int value = *ptr; // Get value at ptr
// Don't confuse these!
int* ptr1 = &x; // ptr1 points to x
int val = *ptr1; // val is the value x points to
Pointer Arithmetic#
Incrementing Pointers#
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = arr; // Point to first element
printf("First element: %d\n", *ptr); // 10
ptr++; // Move to next element
printf("Next element: %d\n", *ptr); // 20
ptr += 2; // Move 2 positions forward
printf("After +2: %d\n", *ptr); // 40
return 0;
}Important: When you increment a pointer, it moves by the size of the data type:
int* ptr++moves 4 bytes (size of int)char* ptr++moves 1 byte (size of char)
Pointer Subtraction#
int arr[] = {10, 20, 30, 40, 50};
int* ptr1 = &arr[0];
int* ptr2 = &arr[4];
int diff = ptr2 - ptr1; // 4 (four elements apart)
printf("%d\n", diff); // 4
Pointers and Arrays#
Arrays and pointers are closely related. The array name is a pointer to the first element:
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
printf("arr[0] = %d\n", arr[0]); // 10
printf("*arr = %d\n", *arr); // 10 (same thing)
printf("arr[2] = %d\n", arr[2]); // 30
printf("*(arr + 2) = %d\n", *(arr + 2)); // 30 (same thing)
return 0;
}Iterating with Pointers#
#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* ptr = arr;
// Print each element
for (int i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++;
}
printf("\n"); // Output: 10 20 30 40 50
return 0;
}Pointers to Different Data Types#
// Pointer to int
int x = 42;
int* ptr_int = &x;
// Pointer to float
float price = 19.99;
float* ptr_float = &price;
// Pointer to char
char grade = 'A';
char* ptr_char = &grade;
// Pointer to array
int arr[5] = {1, 2, 3, 4, 5};
int* ptr_arr = arr;Pass by Reference Using Pointers#
Recall that functions pass by value. Using pointers, we can modify the original variable:
Without Pointers (Pass by Value)#
void increment(int num) {
num++; // Only increments the copy
}
int x = 5;
increment(x);
printf("%d\n", x); // Still 5
With Pointers (Pass by Reference)#
void increment(int* num) {
(*num)++; // Increment the original
}
int x = 5;
increment(&x);
printf("%d\n", x); // Now 6
Practical Example: Swap Function#
#include <stdio.h>
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 10, y = 20;
printf("Before: x = %d, y = %d\n", x, y); // 10, 20
swap(&x, &y);
printf("After: x = %d, y = %d\n", x, y); // 20, 10
return 0;
}Null Pointers#
A pointer that doesn’t point to anything should be set to NULL:
#include <stdio.h>
int main() {
int* ptr = NULL; // Null pointer (not pointing to anything)
// Always check before using
if (ptr != NULL) {
printf("%d\n", *ptr);
} else {
printf("Pointer is NULL\n");
}
return 0;
}Common Pointer Errors#
Error 1: Using Uninitialized Pointer#
// ❌ Wrong - ptr points to garbage memory
int* ptr;
printf("%d\n", *ptr); // Crash!
// ✅ Correct
int x = 42;
int* ptr = &x;
printf("%d\n", *ptr);Error 2: Forgetting & When Getting Address#
int x = 42;
int* ptr;
ptr = x; // ❌ Wrong - assigns value, not address
ptr = &x; // ✅ Correct - assigns address
Error 3: Forgetting * When Using Value#
int x = 42;
int* ptr = &x;
printf("%d\n", ptr); // ❌ Wrong - prints address
printf("%d\n", *ptr); // ✅ Correct - prints value
Practical Example: Array Operations with Pointers#
#include <stdio.h>
void printArray(int* arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", *(arr + i));
}
printf("\n");
}
int findMax(int* arr, int size) {
int max = *arr;
for (int i = 1; i < size; i++) {
if (*(arr + i) > max) {
max = *(arr + i);
}
}
return max;
}
int main() {
int scores[] = {85, 92, 78, 95, 88};
int size = 5;
printf("Scores: ");
printArray(scores, size);
printf("Maximum: %d\n", findMax(scores, size));
return 0;
}Output:
Scores: 85 92 78 95 88
Maximum: 95Pointer Visualization#
Memory Layout:
┌─────────────────────────────┐
│ Address │ Variable │ Value │
├─────────────────────────────┤
│ 0x1000 │ x │ 42 │
│ 0x1004 │ ptr │ 0x1000│
└─────────────────────────────┘
int x = 42;
int* ptr = &x;
x stores value 42 at address 0x1000
ptr stores address 0x1000 (where x is)Practice Exercises#
Exercise 1: Pointer Basics#
Write a program that:
- Creates an integer variable
- Creates a pointer to it
- Prints both value and address
- Modifies through pointer
Exercise 2: Array with Pointers#
Write functions using pointers to:
- Print array elements
- Find sum of array
- Find average of array
Exercise 3: Multiple Variable Swap#
Write a program that:
- Takes 3 numbers
- Swaps them using pointers
- Displays before and after
Summary#
✅ Understood memory addresses
✅ Learned address-of (&) operator
✅ Learned dereference (*) operator
✅ Declared and used pointers
✅ Performed pointer arithmetic
✅ Worked with pointers and arrays
✅ Implemented pass by reference
✅ Avoided common pointer errors
Key Points to Remember#
&x= address of x*ptr= value at address ptr points toint* ptr = &xcreates pointer to int x- Pointer arithmetic moves by data type size
- Always initialize pointers (or set to NULL)
- Check for NULL before dereferencing
scanf("%d", &var)uses & to get address
Next Steps#
Tomorrow we’ll learn about structures and unions - how to group related data together!