Pointers in C Programming
Introduction to Pointers
Suppose a city has a house with an address for each house. You don’t get the house when you know the address, but you do get to know where to find it exactly. In C, pointers are used in the same way. A pointer does not hold a value, it holds the memory address of a variable.
Every variable you declare in C occupies a certain amount of RAM. That space has an address. It has a number, a way to tell you exactly where it is. A pointer is just a variable that contains one of those addresses.
int x = 10; // ‘x’ holds the value 10 int *ptr = &x; // ‘ptr’ holds the address of ‘x’
Why do pointers matter?
Without pointers, C would be far less powerful. They enable:
- Passing large data to functions (without copying)
- Run-time dynamic memory allocation
- Building data structures like linked lists, and trees
- Direct programming of hardware and device drivers

Fig 1: Variable and Pointer in Memory
Understanding Memory and Addresses
RAM is divided into millions of tiny cells that each store one byte of information and are given a unique address. C gives you two operators for dealing with addresses.
| Operator | Name / Meaning |
|---|---|
| & (Address-of) | Returns the memory address of a variable |
| * (Dereference) | Returns the value stored at an address |
int x = 10;
int *ptr = &x;
printf("%d\n", x); // Output: 10 (value of x)
printf("%p\n", &x); // Output: 0x7FFF04 (address of x)
printf("%d\n", *ptr); // Output: 10 (value at ptr's address)
*ptr means “look at the address in ptr and read the value at that address”. This is called dereferencing.

Fig 2: Memory Layout
Declaring and Initializing Pointers
The ‘*’ symbol is always present in pointer syntax and must match the data type it points to:
int *ip; // pointer to int float *fp; // pointer to float char *cp; // pointer to char int *ptr = NULL; // NULL pointer — safe default, points nowhere

Fig 3: NULL Pointer Representation
- A NULL pointer says: ‘I am not pointing at anything yet.’
- Dereferencing NULL causes a segmentation fault — safer than a wild address.
Pointer Arithmetic
The pointers are not normal integers. Adding 1 to a pointer does not necessarily increase its address by 1 byte; the pointer is increased by the size of the type it points to.
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr points to arr[0]
printf("%d\n", *ptr); // 10
ptr++; // moves forward sizeof(int) = 4 bytes
printf("%d\n", *ptr); // 20
| Data Type | Size (typical) | ptr++ moves by |
|---|---|---|
| char | 1 byte | 1 byte |
| int | 4 bytes | 4 bytes |
| double | 8 bytes | 8 bytes |

Fig 4: Pointer Traversing an Array
Pointers and Arrays
In C programming the name of an array is a pointer to the first element of the array. arr and &arr[0] are the same.
int arr[5] = {10, 20, 30, 40, 50};
// These two expressions are equivalent:
printf("%d\n", arr[2]); // 30
printf("%d\n", *(arr + 2)); // 30
| Access Style | Example / Meaning |
|---|---|
Index notation: arr[i] | Element at index i (compiler sugar) |
Pointer arithmetic: *(arr+i) | Same element, explicit pointer form |

Fig 5: Array Memory Representation
Pointers and Functions
By default C passes arguments by value, the function gets a copy. The changes inside the function do not affect the original. Pointers give you call by reference, allowing functions to modify the caller’s variables directly.
// Call by value — does NOT swap
void swap_wrong(int a, int b) {
int temp = a; a = b; b = temp; // swaps local copies only
}
// Call by reference — DOES swap
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Usage:
int x = 5, y = 10;
swap(&x, &y);
// x is now 10, y is now 5

Fig 6: Swap Function Step-by-Step
Pointers and Strings
In C, a string is an array of characters terminated with the null terminator ‘\0’. A char* pointer can walk it character by character.
char str[] = "Hello";
char *ptr = str;
while (*ptr != '\0') {
printf("%c ", *ptr); // Hello
ptr++;
}

Fig 7: String Stored in Memory
Double Pointers (Pointer to Pointer)
A double pointer holds the address of a pointer. This is written in ‘**’.
int x = 10;
int *p = &x; // p holds address of x
int **pp = &p; // pp holds address of p
printf("%d\n", x); // 10
printf("%d\n", *p); // 10
printf("%d\n", **pp); // 10

Fig 8: Double Pointer Memory Chain
Double pointers are very common in functions that want to change a pointer itself (e.g. malloc wrappers), and in 2D arrays and arrays of strings.
Function Pointers (Advanced)
Just as you can point to data, you can point to functions. A function pointer stores the address of a function and lets you call it indirectly — essential for callbacks, plugin architectures, and embedded systems.
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
// Declare a function pointer matching the signature
int (*funcPtr)(int, int);
funcPtr = add;
printf("%d\n", funcPtr(3, 4)); // 7
funcPtr = sub;
printf("%d\n", funcPtr(3, 4)); // -1

Fig. 9: Function Pointer Mechanism
Function pointers power callback functions in the C standard library (qsort, bsearch), interrupt service routines in embedded firmware, and virtual function tables in object-oriented C patterns.
Common Mistakes and Pitfalls

Fig. 10: Common Pointer Errors
| Mistake | Bad Code | Fix |
|---|---|---|
| Uninitialized pointer | int *p; *p = 5; | int *p = NULL;; then assign |
| Dangling pointer | free(ptr); *ptr = 5; | Set ptr = NULL after free |
| Memory leak | ptr = malloc(...); /* no free */ | Always call free(ptr) |
| NULL dereference | int *p = NULL; *p; | Check if (p != NULL) first |
| Wrong type pointer | int x; float *p = &x; | Match pointer type to variable |
Practical Applications of Pointers
Pointers are the backbone of systems programming. Here’s where they appear in the real world:
- Linked Lists & Trees: Each node contains a pointer to the next/child node, enabling dynamic, non-contiguous data structures.
- Operating Systems: The OS kernel uses pointers to manage process tables, file descriptors, and page tables.
- Embedded Systems: Microcontroller registers are accessed through fixed memory addresses — pointers let C code read and write hardware directly.
- Device Drivers: Drivers map hardware I/O ports to memory-mapped addresses, accessed entirely via pointers.
- VLSI & Hardware Interfacing: Memory-mapped I/O in SoC design uses pointer-like addressing to configure hardware blocks.
- Sorting & Searching: qsort() in the C standard library takes a function pointer for comparison, making it work with any data type.
Summary
| Concept | Key Point |
|---|---|
Address operator & | Gets the memory address of a variable |
Dereference operator * | Reads/writes the value at an address |
| Arrays & Pointers | arr[i] is equivalent to *(arr+i); array name = pointer to first element |
| Pointer Arithmetic | Advances by sizeof the pointed-to type, not by 1 byte |
| Function Pointers | Store and call functions dynamically; used in callbacks |
| Dynamic Memory | malloc/calloc on heap; always free when done |
| Double Pointers | Pointer to pointer; used in 2D arrays and modifying pointers in functions |
| Best Practices | Initialize all pointers; check for NULL; free every allocation; set ptr = NULL after free |
FAQs
What is a pointer in C programming?
A pointer is a special variable that stores the memory address of another variable instead of storing a direct value. Pointers enable efficient memory management and dynamic data structures in C.
int x = 10;
int *ptr = &x;
Here, ptr stores the address of x.
What does the '&' operator do in Pointer in C Programming?
The address-of operator (&) returns the memory address of a variable.
int x = 10;
printf(“%p”, &x);
What does the '*' operator mean in pointers?
The asterisk (*) is used for:
- Declaring a pointer.
- Dereferencing a pointer.
int *ptr;
printf(“%d”, *ptr);
What is dereferencing?
Dereferencing means accessing the value stored at the memory address held by a pointer.
int x = 10;int *ptr = &x;printf(“%d”, *ptr);
Output:
10
How do you declare a pointer?
Syntax:
data_type *pointer_name;
Example:
int *ptr;float *fptr;char *cptr;
What is a NULL pointer?
A NULL pointer points to no valid memory location.
int *ptr = NULL;
It is used to indicate that a pointer is currently not pointing anywhere.
What is a dangling pointer?
A dangling pointer points to memory that has already been freed.
int *ptr = malloc(sizeof(int));
free(ptr);
After free(), ptr becomes dangling.
How are pointers and arrays related?
The name of an array acts like a constant pointer to its first element.
int arr[5];
Equivalent:
arr == &arr[0]
What is pointer arithmetic in C?
Pointer arithmetic allows incrementing or decrementing pointers to move through memory locations.
ptr++;
The pointer moves by the size of its data type.
How does pointer arithmetic work with arrays?
Array elements are stored in contiguous memory locations. Incrementing a pointer moves it to the next array element.
int arr[5];
int *ptr = arr;
ptr++;
What is the relationship between arrays and pointers in C?
Answers:
The array name acts as a pointer to the first element of the array.
arr[i]
is equivalent to
*(arr+i)
Can a pointer point to another pointer?
Yes. Such a pointer is called a double pointer.
int **pp;
Double pointers are commonly used in dynamic memory management and function arguments.
What causes a segmentation fault in C?
A segmentation fault occurs when a program attempts to access invalid memory, such as dereferencing a NULL or dangling pointer.
Are pointers faster than array indexing?
Pointers can provide efficient memory access and are often used in performance-critical applications, although modern compilers optimize both approaches effectively.
How are pointers used with strings?
Strings in C are arrays of characters, and pointers can be used to access and manipulate them efficiently.
char *str = “Hello”;
