Pointer
Last Updated: Jan 2026
A pointers are simply variables that hold memory locations instead of raw data values.It gives you direct control over memory, enabling high-performance data manipulation, dynamic memory management, and clean function architectures.
When you declare a variable in C, the compiler reserves a specific chunk of memory bytes to store its value.
int x = 42;
- Value: 42
- Size: Typically 4 bytes (for an int)
- Address: A hexadecimal number like 0x7ffd535f2a1c indicating where x resides in RAM.
Pointer Size Across Systems
A pointer's memory size depends solely on your system architecture, not the data type it points to. All addresses on a given system require the same number of bits to represent:
printf("%zu bytes\n", sizeof(int*)); // 8 bytes (on 64-bit system)
printf("%zu bytes\n", sizeof(char*)); // 8 bytes
printf("%zu bytes\n", sizeof(double*)); // 8 bytes
Address-of Operator (&)
To find where a variable lives in memory, use the address-of operator (&). Printing an address in C requires the %p format specifier.
int age = 25;
printf("Value: %d\n", age); // Output: 25
printf("Address: %p\n", &age); // Output Look Like : 0x7ff7b1234a98
Pointer Declaration, Initialization, & Dereferencing (*)
- Declaration: Tell the compiler what data type the pointer points to using an asterisk (*).
- Initialization: Store an address using &.
- Dereferencing: Use the * operator on an existing pointer to read or modify the value stored at that address.
Example:
#include <stdio.h>
int main() {
int num = 100;
int *ptr; // 1. Declaration: ptr holds the address of an int
ptr = # // 2. Initialization: ptr now stores num's address
printf("Address stored in ptr: %p\n", ptr); // Prints num's address
printf("Value via dereference: %d\n", *ptr); // Prints 100
*ptr = 200; // 3. Modifying num directly through its pointer
printf("New num value: %d\n", num); // Prints 200
return 0;
}
NOTE: Never dereference an uninitialized or "wild" pointer (e.g., int *p; *p = 10;). Doing so attempts to write to a random location in memory, triggering a segmentation fault (crash) or memory corruption. Always initialize pointers to an address or NULL.
Pointer to Pointer (Multiple Indirection)
A pointer to a pointer is a variable that stores the address of another pointer.
int val = 500;
int *ptr1 = &val; // Stores address of val
int **ptr2 = &ptr1; // Stores address of ptr1 (Double Pointer)
printf("Value: %d\n", val); // 500
printf("Via ptr1: %d\n", *ptr1); // 500
printf("Via ptr2: %d\n", **ptr2); // 500
+---------------+ +---------------+ +---------------+
| ptr2 | --> | ptr1 | --> | val |
| (&ptr1 addr) | | (&val addr) | | (500) |
+---------------+ +---------------+ +---------------+
Common applications include dynamically allocating 2D arrays (int **grid) or modifying pointer arguments inside functions.
const Qualifier with Pointers
Combining const with pointers can be confusing. Read declarations right-to-left to understand what is constant:
int x = 10, y = 20;
// 1. Pointer to Constant Data (Data cannot be changed through ptr)
const int *ptr1 = &x;
// *ptr1 = 15; Error: Assignment of read-only location
ptr1 = &y; // Allowed: Pointer can move to another address
// 2. Constant Pointer (Address stored in ptr cannot change)
int *const ptr2 = &x;
*ptr2 = 15; // Allowed: Value can be modified
// ptr2 = &y; Error: Assignment of read-only variable
// 3. Constant Pointer to Constant Data (Neither address nor value can change)
const int *const ptr3 = &x;
// *ptr3 = 15; Error
// ptr3 = &y; Error
typedef Pointer
You can use typedef to abstract pointer types, though it should be used judiciously to avoid hiding pointer semantics from readers.
#include <stdio.h>
typedef int* IntPtr; // 'IntPtr' is now an alias for 'int*'
int main(void) {
int val = 50;
IntPtr p = &val; // Equivalent to: int *p = &val;
printf("Value: %d\n", *p);
// Be careful with multiple declarations on one line:
IntPtr a, b; // Both 'a' and 'b' are 'int*' pointers!
// Compare to standard syntax: int* a, b; (where 'a' is int* but 'b' is int)
return 0;
}
