Fundamentals 12 min read

Mastering C Pointers: From Value Semantics to Advanced Pointer Types

This article explains C's value semantics versus reference semantics, introduces pointers as the bridge between them, details pointer definitions, types, operators, and common pitfalls such as null, dangling, and wild pointers, and demonstrates pointer arithmetic with clear code examples.

AI Cyberspace
AI Cyberspace
AI Cyberspace
Mastering C Pointers: From Value Semantics to Advanced Pointer Types

Value Semantics and Reference Semantics

In C, variables use "value semantics": the variable name is compiled into a memory address, and the stored data is accessed directly via that address.

Variable name : after compilation it becomes the memory address, transparent to the developer.

Variable value : the actual data stored at that address; this is the essence of value semantics.

Advantages of value semantics are simplicity, directness, and high‑performance data access, but it lacks flexibility. For example, a variable name is bound one‑to‑one with its value, and function arguments are copied, leading to extra memory usage for large structures.

Variable name and value are tightly coupled; multiple names cannot refer to the same value.

Function calls copy arguments, incurring overhead.

High‑level languages like Python adopt "reference semantics", where a name refers to an address that points to the actual data. C achieves reference semantics through pointers, providing both high performance and flexibility.

Pointers are the mechanism that enables C to combine value and reference semantics.

Definition of Pointers

A pointer is a special C data type whose size depends on the CPU and OS (typically 4 bytes on 32‑bit systems, 8 bytes on 64‑bit systems).

Pointer : a memory address.

Pointer variable : a variable that stores a memory address.

Pointer variable type : informs the programmer and compiler about the type and size of the data the pointer points to.

Variable Pointer and Pointer Variable

Variable pointer : essentially a pointer that points to a variable’s address, roughly equivalent to the variable name.

Pointer variable : a variable with a data type that stores an address pointing to another variable or data. Declaration syntax:

type* var-name; // type*: pointer variable type.
// var-name: pointer variable name.

Common examples of pointer variables:

/* basic data types */
int a;          // (int)
int* a;         // (int pointer)

/* array */
int a[n];       // (int array) with n int elements
int* a[n];      // (pointer array): n pointers to int
int (*a)[n];    // (array pointer): pointer to an int array, equivalent to the array name

/* function */
int func();      // (int) function returning int
int* func();     // (int pointer) function returning int pointer
int (*func)();   // (function pointer): pointer to function, equivalent to function name

/* double pointer */
int **a;        // pointer to int pointer

int* i or int *i ?

Both syntaxes are equivalent; the choice is a matter of style.

int* i viewpoint : emphasizes the type; int* i, j does NOT declare j as a pointer, so the habit is to write int* i = &a; int* j = &b;.

int *i viewpoint : emphasizes the variable; the asterisk belongs to the variable name.

Dereference and Address Operators

* (dereference operator) : used to define a pointer variable and to obtain the value stored at the address the pointer points to.

& (address‑of operator) : obtains the memory address of a variable.

Example:

#include <stdio.h>

int main ()
{
    int  var = 20;
    int* ip;    /* pointer variable */

    ip = &var;  /* assign address of var to ip */

    printf("Address of var variable: %p
", &var);
    printf("Address stored in ip variable: %p
", ip);
    printf("Value of *ip variable: %d
", *ip);  // get the value
    return 0;
}

Output:

Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20

Kinds of Pointers

Double Pointer

A double pointer (pointer to pointer) provides multi‑level indirect addressing.

#include <stdio.h>

int main ()
{
    int   var  = 3000;
    int*  ptr  = NULL;
    int** pptr = NULL;  // double pointer

    ptr  = &var;
    pptr = &ptr;

    printf("Value of var = %d
", var);
    printf("Value available at *ptr = %d
", *ptr);
    printf("Value available at **pptr = %d
", **pptr);
    return 0;
}

Null Pointer

Assigning NULL to a pointer that has no valid address is good practice. NULL is defined in the C standard library as the constant 0x0; accessing address 0x0 is prohibited by the OS.

#include <stdio.h>

int main ()
{
    int* ptr = NULL;
    printf("ptr address is %p
", ptr); // prints 0x0
    return 0;
}

Checking a null pointer:

if (ptr)   /* non‑null */
if (!ptr)  /* null */

Dangling Pointer

A dangling pointer refers to memory that has already been freed. Using it can cause undefined behavior.

Bad example (creates a dangling pointer):

void* p = malloc(size);
assert(p);
free(p);  // p is now dangling

Good practice (nullify after free):

void* p = malloc(size);
assert(p);
free(p);
p = NULL; // avoid dangling pointer

Wild Pointer

A wild pointer is an uninitialized pointer whose value is indeterminate.

void* p;  // p is a wild pointer

Wild pointers can corrupt data or cause crashes; initializing them to NULL mitigates the risk.

Pointer Arithmetic

Pointers are essentially hexadecimal numbers, so they support arithmetic operators ++, --, +, and -. Incrementing moves to the next element; decrementing moves to the previous element. The step size depends on the pointed‑to type (e.g., int steps by 4 bytes).

Pointers can also be compared with ==, <, and > when they point into the same array.

#include <stdio.h>

const int MAX = 3;

int main ()
{
    int var[] = {10, 100, 200};
    int i;
    int* ptr;

    /* address of first element */
    ptr = var;
    i = 0;
    while (ptr <= &var[MAX-1])
    {
        printf("Address of var[%d] = %x
", i, ptr);
        printf("Value of var[%d] = %d
", i, *ptr);
        ptr++;   // move to next element
        i++;
    }
    return 0;
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

memory managementCprogramming fundamentalsreference semantics
AI Cyberspace
Written by

AI Cyberspace

AI, big data, cloud computing, and networking.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.