SrcForge

Lesson 18

Pointers

A pointer in C is a special variable that stores the memory address of another variable instead of storing the actual value. Pointers enable direct memory access, efficient data passing, dynamic memory allocation, and complex data structures.

C Track

Save progress as you learn.

44 lessons

Lesson content

Pointers in C Programming: A Complete Beginner to Advanced Guide

What are Pointers in C Programming?

A pointer in C is a special variable that stores the memory address of another variable instead of storing the actual value.

Think of a pointer like a house address. The value inside a house is like a normal variable, while the address of the house is like a pointer. Knowing the address allows you to locate and access the value stored there.

int age = 25;
int *ptr = &age;

Here, age stores the value 25, &age gives the memory address of age, and ptr stores that memory address.

Why Do Pointers Exist?

Pointers make C powerful and efficient by allowing programs to:

  • Access memory directly
  • Pass large data efficiently to functions
  • Create dynamic memory
  • Build complex data structures
  • Share data between functions
  • Improve program performance

Without pointers, many advanced features of C, such as linked lists, trees, and dynamic memory allocation, would not be possible.

Real-World Use Cases

Pointers are widely used in:

  • Dynamic memory allocation
  • Linked lists
  • Stacks and queues
  • Trees and graphs
  • File handling
  • Operating systems
  • Device drivers
  • Embedded systems
  • String manipulation

Prerequisites

Before learning Pointers in C Programming, you should understand:

  • Variables
  • Data types
  • Arrays
  • Functions
  • Memory basics
  • Input and output functions

Core Concepts of Pointers in C Programming

What is a Pointer?

A pointer is a variable that stores the address of another variable.

int number = 10;
int *ptr = &number;

Memory representation: number holds the value 10 at address 1000, and ptr holds the value 1000 (the address of number).

Pointer Declaration

Syntax

data_type *pointer_name;

Example

int *ptr;
char *letter;
float *price;

The * indicates that the variable is a pointer.

Address Operator (&)

The address-of operator (&) returns the memory address of a variable.

int x = 50;

printf("%p", (void *)&x);

%p is the format specifier used to print memory addresses.

Dereference Operator (*)

The dereference operator (*) accesses the value stored at the address held by a pointer.

int x = 50;

int *ptr = &x;

printf("%d", *ptr);

Output: 50

Pointer Initialization

Always initialize pointers before using them.

int number = 100;

int *ptr = &number;

Avoid:

int *ptr;

An uninitialized pointer contains an indeterminate address, and dereferencing it results in undefined behavior.

NULL Pointer

A pointer that points to nothing should be initialized to NULL.

#include <stddef.h>

int *ptr = NULL;

Always check for NULL before dereferencing.

Pointer Arithmetic

Pointers can be incremented and decremented.

ptr++;
ptr--;

When incremented, a pointer moves to the next element of its data type. For an integer pointer, on systems where int occupies 4 bytes, incrementing an int * advances it by 4 bytes (for example, from address 1000 to 1004, 1008, 1012).

Pointers and Arrays

The name of an array represents the address of its first element.

int numbers[] = {10, 20, 30};

int *ptr = numbers;

These are equivalent: numbers[1] and *(numbers + 1). Both access the second element.

Pointers and Functions

Pointers allow functions to modify the original variable.

void changeValue(int *num)
{
    *num = 100;
}

Code Examples

Example 1: Beginner – Basic Pointer

#include <stdio.h>                      // Include standard input/output library

int main(void)                          // Program entry point
{
    int number = 25;                    // Declare an integer variable

    int *ptr = &number;                 // Store the address of number in ptr

    printf("Value = %d\n", number);     // Print the value of number

    printf("Address = %p\n", (void *)ptr); // Print the memory address stored in ptr

    printf("Using Pointer = %d\n", *ptr); // Dereference ptr to print the value

    return 0;                           // Indicate successful execution
}

Example 2: Intermediate – Modify a Variable Using a Pointer

#include <stdio.h>                      // Include standard input/output library

int main(void)                          // Program entry point
{
    int age = 20;                       // Declare an integer variable

    int *ptr = &age;                    // Store the address of age

    *ptr = 35;                          // Modify age through the pointer

    printf("Age = %d\n", age);          // Print the updated value

    return 0;                           // End the program
}

Output: Age = 35

Example 3: Intermediate – Swap Two Numbers Using Pointers

#include <stdio.h>                      // Include standard input/output library

void swap(int *a, int *b)               // Define a function that accepts two pointers
{
    int temp = *a;                      // Store the value pointed to by a
    *a = *b;                            // Copy the value pointed to by b into a
    *b = temp;                          // Copy the original value into b
}

int main(void)                          // Program entry point
{
    int x = 10;                         // First number
    int y = 20;                         // Second number

    swap(&x, &y);                       // Pass the addresses of x and y

    printf("x = %d\n", x);              // Print the swapped value of x
    printf("y = %d\n", y);              // Print the swapped value of y

    return 0;                           // End the program
}

Example 4: Advanced – Traverse an Array Using a Pointer

#include <stdio.h>                      // Include standard input/output library

int main(void)                          // Program entry point
{
    int numbers[] = {10, 20, 30, 40, 50}; // Declare and initialize an integer array

    int *ptr = numbers;                 // Point to the first element of the array

    for (int i = 0; i < 5; i++)         // Loop through the array
    {
        printf("%d ", *(ptr + i));      // Print each element using pointer arithmetic
    }

    printf("\n");                       // Move to the next line

    return 0;                           // End the program
}

Output: 10 20 30 40 50

Example 5: Advanced – Pass a Pointer to a Function

#include <stdio.h>                      // Include standard input/output library

void increment(int *value)              // Define a function that accepts a pointer
{
    (*value)++;                         // Increment the value pointed to by the pointer
}

int main(void)                          // Program entry point
{
    int number = 50;                    // Declare an integer variable

    increment(&number);                 // Pass the address of the variable

    printf("Number = %d\n", number);    // Print the updated value

    return 0;                           // End the program
}

Common Mistakes and Pitfalls

WrongCorrect
Using an uninitialized pointerInitialize it or set it to NULL
Dereferencing a NULL pointerCheck for NULL before dereferencing
Confusing * and &Use & to get an address and * to access the value
Returning the address of a local variableReturn dynamically allocated memory or pass an output pointer
Accessing memory outside an arrayStay within valid array bounds

Wrong:

int *ptr;

*ptr = 100;

Correct:

int value = 100;

int *ptr = &value;

*ptr = 200;

Best Practices

  • Always initialize pointers before use.
  • Set pointers to NULL when they do not point to valid memory.
  • Check pointers for NULL before dereferencing.
  • Use meaningful pointer names such as studentPtr or head.
  • Avoid unnecessary pointer arithmetic.
  • Keep pointer scopes as small as possible.
  • Use const with pointers when the referenced data should not be modified.
  • Free dynamically allocated memory after use to prevent memory leaks.

When NOT to Use This

Avoid using pointers when:

  • A simple variable is sufficient.
  • Pointer arithmetic makes code difficult to understand.
  • Passing small values (such as int or char) by value is simpler.
  • Direct memory access is unnecessary.

Use pointers only when they improve efficiency, enable data sharing, or are required by the problem.

Summary / Key Takeaways

  • Pointers in C programming store memory addresses instead of values.
  • Use & to obtain a variable's address.
  • Use * to declare pointers and dereference them.
  • Initialize pointers before use.
  • Use NULL for pointers that do not reference valid memory.
  • Arrays and pointers are closely related, but they are not identical.
  • Pointers enable functions to modify caller variables.
  • Pointer arithmetic allows traversal of arrays.
  • Careless pointer usage can lead to undefined behavior, crashes, or security vulnerabilities.

FAQ About Pointers in C

1. What is a pointer in C?

A pointer is a variable that stores the memory address of another variable.

2. What is the difference between * and &?

& returns the address of a variable, while * declares a pointer or dereferences a pointer to access the value stored at its address.

3. Why are pointers important?

Pointers enable efficient memory management, dynamic memory allocation, pass-by-reference, and implementation of advanced data structures such as linked lists and trees.

4. What is a NULL pointer?

A NULL pointer does not point to any valid memory location. Initializing unused pointers to NULL helps avoid accidental access to invalid memory.

#include <stddef.h>

int *ptr = NULL;

5. Are arrays and pointers the same?

No. Although an array name usually decays to a pointer to its first element in many expressions, an array and a pointer are different types with different properties. Arrays have a fixed size, while pointers are variables that can point to different memory locations.

Prev: I/O FunctionsBack to hub