1
Basic Pointer Operations — Value, Address, Dereference
See & and * in action with real numbers
Basics
Declare three variables, create a pointer to each, and print the value, the address, and the dereferenced value. Shows clearly that
*p and the original variable give the same result, and that p and &variable give the same address.#include <stdio.h> int main() { int a = 10; float b = 3.14; char c = 'Z'; int *pa = &a; float *pb = &b; char *pc = &c; printf("--- Integer ---\n"); printf("Value : %d\n", a); printf("Address &a : %p\n", &a); printf("Pointer pa : %p\n", pa); printf("Deref *pa : %d\n", *pa); printf("\n--- Float ---\n"); printf("Value : %.2f\n", b); printf("Deref *pb : %.2f\n", *pb); printf("\n--- Char ---\n"); printf("Value : %c\n", c); printf("Deref *pc : %c\n", *pc); /* Change a through pointer */ *pa = 999; printf("\nAfter *pa=999: a = %d\n", a); return 0; }
--- Integer --- Value : 10 Address &a : 0x7ffc... (example) Pointer pa : 0x7ffc... (same) Deref *pa : 10 --- Float --- Value : 3.14 Deref *pb : 3.14 --- Char --- Value : Z Deref *pc : Z After *pa=999: a = 999
example 2
2
Swap Two Numbers Using Pointers
Why swap needs pointers — pass by reference
Pass by ref
The classic pointer example. Shows the wrong swap (value copy — doesn't work) side by side with the correct swap using
*a and *b. The wrong version compiles with no error but does nothing — a very common beginner trap.#include <stdio.h> /* WRONG — gets copies, originals unchanged */ void wrongSwap(int a, int b) { int t = a; a = b; b = t; } /* CORRECT — gets addresses, modifies originals */ void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } int main() { int x = 10, y = 25; printf("Before wrongSwap: x=%d y=%d\n", x, y); wrongSwap(x, y); printf("After wrongSwap: x=%d y=%d\n", x, y); /* unchanged! */ printf("\nBefore swap: x=%d y=%d\n", x, y); swap(&x, &y); /* pass addresses */ printf("After swap: x=%d y=%d\n", x, y); /* swapped! */ return 0; }
Before wrongSwap: x=10 y=25 After wrongSwap: x=10 y=25 ← unchanged! Before swap: x=10 y=25 After swap: x=25 y=10 ← swapped!
example 3
3
Traverse an Array Using a Pointer
Walk through array with p++ — pointer arithmetic
Array + pointer
Set a pointer to the first element of an array. Walk through it using
p++ — each increment moves the pointer to the next element. Compares the result with normal array indexing to prove they give identical output.#include <stdio.h> int main() { int arr[] = {5, 15, 25, 35, 45}; int n = 5, i; int *p = arr; /* point to first element */ printf("Using arr[i]: "); for (i = 0; i < n; i++) printf("%d ", arr[i]); printf("\nUsing *(p+i): "); for (i = 0; i < n; i++) printf("%d ", *(p + i)); printf("\nUsing p++: "); p = arr; /* reset */ for (i = 0; i < n; i++) { printf("%d ", *p); p++; /* advance pointer */ } printf("\n"); /* Sum using pointer */ int sum = 0; for (p = arr; p < arr + n; p++) sum += *p; printf("Sum = %d\n", sum); return 0; }
Using arr[i]: 5 15 25 35 45 Using *(p+i): 5 15 25 35 45 Using p++: 5 15 25 35 45 Sum = 125
for (p = arr; p < arr + n; p++) — this loop uses the pointer itself as the loop variable. Start at the first element, stop when past the last one. Very common C idiom.example 4
4
Reverse a String Using Two Pointers
Left pointer and right pointer move toward each other
Two pointers
Use two pointers — one starting at the beginning of the string, one at the end. Swap characters and move them toward the middle until they meet. This two-pointer technique is used widely in string and array problems.
#include <stdio.h> #include <string.h> int main() { char str[] = "Haridwar"; char *left = str; /* start of string */ char *right = str + strlen(str) - 1; /* end of string */ char temp; printf("Original : %s\n", str); while (left < right) { temp = *left; /* swap chars */ *left = *right; *right = temp; left++; /* move inward */ right--; } printf("Reversed : %s\n", str); /* Test palindrome using same technique */ char word[] = "madam"; char *l = word, *r = word + strlen(word) - 1; int ok = 1; while (l < r) { if (*l != *r) { ok=0;break; } l++;r--; } printf("\n\"%s\" is %s palindrome\n", word, ok ? "a" : "NOT a"); return 0; }
Original : Haridwar Reversed : rawritaH "madam" is a palindrome
example 5
5
Count Characters in a String — Pointer Walk
Walk a string with a pointer until '\0' — count vowels, consonants, digits
String pointer
Use a
char *p to walk through a string one character at a time. The loop condition is *p != '\0' — when the pointer reaches the null terminator, the string is done. Count vowels, consonants, digits, and spaces in one pass.#include <stdio.h> #include <ctype.h> int isVowel(char c) { c = tolower(c); return c=='a'||c=='e'||c=='i'||c=='o'||c=='u'; } int main() { char str[] = "Hello World 2024"; char *p = str; int vowels=0, cons=0, digits=0, spaces=0; printf("String: \"%s\"\n\n", str); while (*p != '\0') { /* walk until null terminator */ if (isspace(*p)) spaces++; else if (isdigit(*p)) digits++; else if (isVowel(*p)) vowels++; else if (isalpha(*p)) cons++; p++; /* move to next character */ } printf("Vowels : %d\n", vowels); printf("Consonants : %d\n", cons); printf("Digits : %d\n", digits); printf("Spaces : %d\n", spaces); return 0; }
String: "Hello World 2024" Vowels : 3 Consonants : 7 Digits : 4 Spaces : 2
example 6
6
Find Maximum in Array — Return Pointer
Function returns a pointer to the max element
Return pointer
A function that takes an array and returns a
int * — a pointer to the maximum element. The caller dereferences it to get the value. Shows that functions can return pointers, not just values.#include <stdio.h> /* Returns POINTER to the maximum element */ int *findMax(int *arr, int n) { int *maxPtr = arr; /* assume first is max */ for (int i = 1; i < n; i++) if (arr[i] > *maxPtr) maxPtr = &arr[i]; /* update to point at new max */ return maxPtr; } int *findMin(int *arr, int n) { int *minPtr = arr; for (int i = 1; i < n; i++) if (arr[i] < *minPtr) minPtr = &arr[i]; return minPtr; } int main() { int arr[] = {34, 7, 89, 12, 56, 23}; int n = 6; int *mx = findMax(arr, n); int *mn = findMin(arr, n); printf("Array: 34 7 89 12 56 23\n"); printf("Max = %d (at index %ld)\n", *mx, mx - arr); printf("Min = %d (at index %ld)\n", *mn, mn - arr); /* Can modify the max through returned pointer */ *mx = 0; printf("After zeroing max: "); for (int i=0;i<n;i++) printf("%d ",arr[i]); return 0; }
Array: 34 7 89 12 56 23 Max = 89 (at index 2) Min = 7 (at index 1) After zeroing max: 34 7 0 12 56 23
mx - arr gives the index of the maximum element. Subtracting two pointers to the same array gives the number of elements between them — pointer subtraction.
example 7
7
Sum and Average — Output via Pointer Parameters
Function fills multiple results through pointer parameters
Multiple outputs
A function that computes both the sum and average of an array and writes them back to the caller through two pointer parameters. C functions can only return one value — pointer parameters are the solution for returning multiple results.
#include <stdio.h> /* Fills *sum and *avg through pointer parameters */ void calcStats(int *arr, int n, int *sum, float *avg) { *sum = 0; for (int i = 0; i < n; i++) *sum += arr[i]; *avg = (float)*sum / n; } int main() { int marks[] = {85, 90, 72, 88, 95}; int total; float average; calcStats(marks, 5, &total, &average); printf("Marks : 85 90 72 88 95\n"); printf("Total : %d\n", total); printf("Average: %.1f\n", average); return 0; }
Marks : 85 90 72 88 95 Total : 430 Average: 86.0
example 8
8
Bubble Sort Using Pointer-Based Swap
Sort an array in place — swap() takes pointers
Sorting
Bubble sort using a separate
swap(int *a, int *b) function. The sort passes addresses of array elements directly to swap. Shows that pointer-based swap works seamlessly inside sorting algorithms — the same pattern used in real C sorting libraries.#include <stdio.h> void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } void bubbleSort(int *arr, int n) { for (int i = 0; i < n-1; i++) for (int j = 0; j < n-i-1; j++) if (arr[j] > arr[j+1]) swap(&arr[j], &arr[j+1]); /* address of elements */ } void print(int *a, int n) { for (int i=0;i<n;i++) printf("%d ",a[i]); printf("\n"); } int main() { int arr[] = {64, 25, 12, 92, 43}; printf("Before: "); print(arr, 5); bubbleSort(arr, 5); printf("After: "); print(arr, 5); return 0; }
Before: 64 25 12 92 43 After: 12 25 43 64 92
example 9
9
Pointer to Struct — The Arrow Operator
Access struct members through a pointer using ->
Struct pointer
When you have a pointer to a struct, use the arrow operator
-> instead of the dot operator to access members. p->name means "go to the struct p points to and access the name field" — it's shorthand for (*p).name.#include <stdio.h> #include <string.h> typedef struct { char name[20]; int roll; float marks; } Student; void display(Student *p) { /* receives pointer to struct */ printf("Name : %s\n", p->name); /* arrow operator! */ printf("Roll : %d\n", p->roll); printf("Marks : %.1f\n",p->marks); } int main() { Student s1 = {"Ananta", 101, 88.5}; Student *ptr = &s1; /* pointer to student */ printf("--- Using dot (direct): ---\n"); printf("s1.name = %s\n", s1.name); printf("\n--- Using arrow (pointer): ---\n"); printf("ptr->name = %s\n", ptr->name); printf("(*ptr).roll = %d (same as ptr->roll)\n", (*ptr).roll); printf("\n--- Through function: ---\n"); display(&s1); /* Modify through pointer */ ptr->marks = 95.0; printf("\nAfter ptr->marks=95: s1.marks = %.1f\n", s1.marks); return 0; }
--- Using dot (direct): --- s1.name = Ananta --- Using arrow (pointer): --- ptr->name = Ananta (*ptr).roll = 101 (same as ptr->roll) --- Through function: --- Name : Ananta Roll : 101 Marks : 88.5 After ptr->marks=95: s1.marks = 95.0
Rule:
s.member when you have the struct directly. p->member when you have a pointer to the struct. The arrow is just a shortcut for (*p).member.example 10
10
Quadratic Roots — Three Output Pointers
One function fills root1, root2, and a discriminant flag through pointers
Multiple outputs
Solves a quadratic equation ax² + bx + c = 0. The function takes a, b, c as inputs and fills the two roots and a status code through three pointers. Status 1 = two real roots, 0 = equal roots, -1 = no real roots. Perfect example of using multiple pointer outputs to return a complex result.
#include <stdio.h> #include <math.h> /* Fills r1, r2 and returns status: 1 = two real roots 0 = equal roots (one root) -1 = no real roots (complex) */ int quadratic(float a, float b, float c, float *r1, float *r2) { float disc = b*b - 4*a*c; if (disc > 0) { *r1 = (-b + (float)sqrt(disc)) / (2*a); *r2 = (-b - (float)sqrt(disc)) / (2*a); return 1; /* two real roots */ } else if (disc == 0) { *r1 = *r2 = -b / (2*a); return 0; /* equal roots */ } else { return -1; /* no real roots */ } } int main() { float r1, r2; int status; /* x^2 - 5x + 6 = 0 roots: 3 and 2 */ status = quadratic(1, -5, 6, &r1, &r2); printf("x^2 - 5x + 6 = 0\n"); if (status == 1) printf(" Roots: %.2f and %.2f\n\n", r1, r2); /* x^2 - 4x + 4 = 0 equal roots: 2 */ status = quadratic(1, -4, 4, &r1, &r2); printf("x^2 - 4x + 4 = 0\n"); if (status == 0) printf(" Equal root: %.2f\n\n", r1); /* x^2 + x + 1 = 0 no real roots */ status = quadratic(1, 1, 1, &r1, &r2); printf("x^2 + x + 1 = 0\n"); if (status == -1) printf(" No real roots\n"); return 0; }
x^2 - 5x + 6 = 0 Roots: 3.00 and 2.00 x^2 - 4x + 4 = 0 Equal root: 2.00 x^2 + x + 1 = 0 No real roots
checklist
- Ex 1 — &x gives address, *p gives value at address, changing *p changes x
- Ex 2 — Without pointers, swap gets copies. With &x and *a, it modifies the originals
- Ex 3 — arr[i] and *(arr+i) are the same. p++ moves to the next element
- Ex 4 — Two-pointer technique: left and right move inward — used for reverse and palindrome
- Ex 5 — while (*p != '\0') walks a string character by character
- Ex 6 — Functions can return int* — a pointer to an element. mx - arr gives the index
- Ex 7 — Pointer output parameters let one function fill multiple results
- Ex 8 — swap(&arr[j], &arr[j+1]) works because pointers point to the actual elements
- Ex 9 — p->member is shorthand for (*p).member — use arrow when you have a struct pointer
- Ex 10 — return value is the status code, pointer params carry the actual output data