Pointer In C Programming Examples | Double Pointer & Use
A pointer is also a variable that stores the memory address of another variable. The pointer variable itself also contains the address of memory. Pointers cannot store direct values; they only store memory addresses of where values are located.
This is useful for various reasons, such as dynamic memory allocation, arrays, and functions. As we know compiler assigns a unique address to each variable in a program.
Pointer Declaration and Initialization: Code Example
Here’s a very simple example of pointer declaration and initialization in C
#include <stdio.h> int main() { int a = 20; int *ptr; // pointer declaration ptr = &a; // pointer initialization printf("Address of a: %p\n", &a); // Output: a's address printf("Address of *ptr: %p\n", &(*ptr)); // Output: a's address printf("Value of ptr: %p\n", ptr); // Output: a's address printf("Value of a: %d\n", a); // Output: 20 (value of a) printf("Value of *ptr: %d\n", *ptr); // Output: 20 (value at a's address) printf("Value of *&a: %d\n", *(&a)); // Output: 20 (same as above) printf("Address of ptr: %p\n", &ptr); // Output: ptr's address return 0; }
Output:
Address of a: 000000000061FE1C Address of *ptr: 000000000061FE1C Value of ptr: 000000000061FE1C Value of a: 20 Value of *ptr: 20 Value of *&a: 20 Address of ptr: 000000000061FE10
Explanation: &var gives the address of var. *ptr giving you the value stored at that address.
Important:
Dereferencing a pointer means accessing the value stored at the memory address the pointer holds. dereferencing a pointer is done using the * operator. |
Double Pointer (Pointer to Pointer)
In C, a pointer-to-pointer (or “double pointer”) allows us to store the address of another pointer. Here’s a simple example diagram
According to above diagram, var is an integer variable set to 20. ptr1 is a pointer variable that holds the address of var. ptr2 is a pointer-to-pointer variable that holds the address of ptr1.
Double Pointer Code Example
#include <stdio.h> int main() { int var = 20; int *ptr1 = &var; // Pointer to var int **ptr2 = &ptr1; // Pointer to ptr1 printf("Value pointed to by ptr: %d\n", *ptr1); // Prints 20 printf("Value pointed to by pptr: %d\n", **ptr2); // Prints 20 return 0; }
Output:
Value pointed to by ptr: 20 Value pointed to by pptr: 20
Use of Pointer
Pointers are very powerful and useful in programming, especially in languages like C and C++. Here are some key uses of pointers:
1. Dynamic Memory Allocation
Pointers are essential for managing memory dynamically. Functions like malloc
, calloc
, and free
use pointers to allocate and deallocate memory.
Example:
int *ptr = (int*) malloc(sizeof(int) * 5); // Allocates memory for 5 integers
2. Efficient Array and String Handling
Pointers provide direct access to array elements and can optimize string manipulation, as arrays are essentially pointers to the first element.
Example:
int arr[] = {41, 25, 33, 41, 50};
int *ptr = arr; // Pointer to the first element of the array
printf("%d \n", *(ptr)); // Dereferencing pointer (output 41)
printf("%d\n", *(ptr + 2)); // Access the third element: 33
// Accessing and printing each element using pointer
for (int i = 0; i < 5; i++) {
printf("%d ", *(ptr + i)); // Dereferencing pointer to access elements
}
printf("\n"); // Output: 41, 25, 33, 41, 50
return 0;
}
3. Function Arguments (Passing by Reference)
Pointers allow passing by reference, enabling functions to modify the original data, which is efficient in terms of memory and performance.
Example:
void updateValue(int *ptr) {
*ptr = 20; // Dereference and modify the original value
}
int main() {
int number = 10;
updateValue(&number); // Pass the address of 'number'
printf("%d", number); // Prints 20
return 0;
}
4. Building Data Structures (Linked Lists, Trees, Graphs)
Pointers are crucial for building complex data structures like linked lists, trees, and graphs, where each element points to others.
Example (Linked List):
struct Node {
int data;
struct Node *next; // Pointer to the next node
};
5. Accessing Hardware and Memory Directly
In low-level programming (e.g., embedded systems), pointers can access hardware memory directly, useful for controlling hardware registers.
Example:
int *port = (int *) 0x4000; // Pointer to a memory-mapped register
*port = 1; // Set the register value to 1
6. Pointer Arithmetic
Pointers allow arithmetic operations (like incrementing or decrementing) to traverse arrays or other memory blocks efficiently.
Example:
int arr[] = {1, 2, 3, 4};
int *ptr = arr;
printf("%d\n", *(ptr + 1));
// Prints 2, accessing the second element
7. Pointers to Functions
Function pointers allow you to store addresses of functions, enabling callback mechanisms and flexible programming patterns.
Example:
void printMessage() {
printf("Hello, world!\n");
}
int main() {
void (*funcPtr)() = printMessage; // Pointer to 'printMessage'
funcPtr(); // Calls 'printMessage' via the pointer
return 0;
}