Pointers in C

A pointer is a variable that stores the memory address of another variable. Instead of holding a value like 10 or 3.14, a pointer holds the location (address) in memory where a value is stored.

Understanding pointers is one of the most important skills in C programming. They enable dynamic memory allocation, efficient array and string handling, and passing variables by reference to functions.

Memory Address Concept

Every variable in a C program is stored at a specific location in the computer's memory. Each location has a unique address — a number that identifies it. Think of it like house addresses: a house holds a person (value), and the address tells exactly where that house is (memory address).


int age = 25;
// age is stored at some memory address, e.g., 1000
// Value at address 1000 = 25

Declaring a Pointer

Syntax


data_type *pointer_name;

The * symbol declares the variable as a pointer. The data type specifies what kind of variable the pointer points to.


int *ptr;       // pointer to an integer
float *fptr;    // pointer to a float
char *cptr;     // pointer to a character

Important Pointer Operators

OperatorNameDescription
&Address-of operatorReturns the memory address of a variable
*Dereference operatorAccesses the value stored at the pointer's address

Basic Pointer Example


#include <stdio.h>

int main()
{
    int age = 25;
    int *ptr;     // declare pointer

    ptr = &age;   // ptr now holds the address of age

    printf("Value of age         : %d\n", age);
    printf("Address of age (&age) : %p\n", &age);
    printf("Value of ptr (address): %p\n", ptr);
    printf("Value at ptr (*ptr)   : %d\n", *ptr);

    return 0;
}

Output (addresses will vary per system)


Value of age         : 25
Address of age (&age) : 0x7ffeabc1234
Value of ptr (address): 0x7ffeabc1234
Value at ptr (*ptr)   : 25

Visual Representation


Variable: age
Address:  1000
Value:    25

Pointer: ptr
Address:  2000
Value:    1000  ← (holds address of age)

*ptr → goes to address 1000 → finds value 25

Modifying a Variable Through a Pointer


#include <stdio.h>

int main()
{
    int num = 10;
    int *ptr = &num;

    printf("Before: %d\n", num);

    *ptr = 50;   // change value at the address ptr points to

    printf("After : %d\n", num);  // num is now 50

    return 0;
}

Output


Before: 10
After : 50

Pointer Arithmetic

Arithmetic operations can be performed on pointers. When a pointer is incremented, it moves to the next memory location for its data type. The size of the jump depends on the data type.

Data TypeSizeptr++ moves by
char1 byte1 byte
int4 bytes4 bytes
float4 bytes4 bytes
double8 bytes8 bytes

#include <stdio.h>

int main()
{
    int nums[3] = {10, 20, 30};
    int *ptr = nums;  // points to first element

    printf("Element 0: %d (at %p)\n", *ptr, ptr);
    ptr++;
    printf("Element 1: %d (at %p)\n", *ptr, ptr);
    ptr++;
    printf("Element 2: %d (at %p)\n", *ptr, ptr);

    return 0;
}

Output


Element 0: 10 (at 0x7ffe...00)
Element 1: 20 (at 0x7ffe...04)
Element 2: 30 (at 0x7ffe...08)

Notice each address increases by 4 (because int is 4 bytes).

Pointers and Arrays

In C, the name of an array is actually a pointer to its first element. This means arrays and pointers are closely related.


#include <stdio.h>

int main()
{
    int arr[4] = {5, 10, 15, 20};

    int *ptr = arr;  // arr is same as &arr[0]

    for (int i = 0; i < 4; i++)
    {
        printf("arr[%d] = %d\n", i, *(ptr + i));
    }

    return 0;
}

Output


arr[0] = 5
arr[1] = 10
arr[2] = 15
arr[3] = 20

Pointers and Functions — Pass by Reference

Passing a pointer to a function allows the function to modify the original variable.


#include <stdio.h>

void swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main()
{
    int x = 5, y = 10;

    printf("Before swap: x = %d, y = %d\n", x, y);
    swap(&x, &y);
    printf("After swap : x = %d, y = %d\n", x, y);

    return 0;
}

Output


Before swap: x = 5, y = 10
After swap : x = 10, y = 5

NULL Pointer

A pointer that does not point to any valid memory location is called a NULL pointer. It is good practice to initialize a pointer to NULL when no address is assigned yet.


#include <stdio.h>

int main()
{
    int *ptr = NULL;  // pointer initialized to NULL

    if (ptr == NULL)
        printf("Pointer is NULL — not pointing to any variable.\n");

    return 0;
}

Important: Always check if a pointer is NULL before dereferencing it. Dereferencing a NULL pointer crashes the program.

Pointer to Pointer (Double Pointer)

A pointer can also store the address of another pointer. This is called a pointer to pointer or double pointer.


#include <stdio.h>

int main()
{
    int value = 42;
    int *ptr = &value;    // ptr points to value
    int **dptr = &ptr;    // dptr points to ptr

    printf("value   = %d\n", value);
    printf("*ptr    = %d\n", *ptr);
    printf("**dptr  = %d\n", **dptr);

    return 0;
}

Output


value   = 42
*ptr    = 42
**dptr  = 42

Common Pointer Mistakes

MistakeDescriptionFix
Wild PointerUsing an uninitialized pointerAlways initialize: int *ptr = NULL;
NULL DereferenceAccessing value via NULL pointerCheck if (ptr != NULL) first
Dangling PointerPointer still pointing to freed memorySet ptr = NULL after free(ptr);
Memory LeakAllocated memory never freedAlways free() dynamically allocated memory

Summary

Pointers are one of the most powerful features of C. A pointer stores a memory address and allows direct interaction with memory. The & operator gets the address of a variable, and the * operator accesses the value at an address. Pointers enable pass-by-reference in functions, efficient array traversal, dynamic memory allocation, and building complex data structures like linked lists and trees. Mastering pointers is the gateway to becoming a proficient C programmer.

Leave a Comment

Your email address will not be published. Required fields are marked *