Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. C Language Dictionary
  3. Pointer Basics (* / &)

Pointer Basics (* / &)

Since: C89(1989)

A pointer is a variable that stores the memory address of another variable. Use the & operator to get an address, and the * operator to read or write the value at that address. Pointers are a core feature of C and are fundamental to arrays, strings, dynamic memory, and function pointers.

Syntax

// Declares a pointer variable (a pointer to the specified type).
type *pointerName;

// Gets the address of a variable (address-of operator).
&variableName

// Reads or writes the value at the address the pointer points to (dereference operator).
*pointerName

// Declares and initializes a pointer at the same time.
type *pointerName = &variableName;

// Null pointer (represents a pointer that points to nothing).
type *pointerName = NULL;

Pointer Operators

OperatorNameDescription
&Address-of operatorReturns the memory address of a variable. Used to assign to a pointer or pass to a function.
* (in declaration)Pointer declarationIndicates that a variable is a pointer. Written after the type name.
* (in expression)Dereference operatorReads or writes the value at the address the pointer points to. Also called dereferencing.
NULLNull pointer constantRepresents a pointer that does not point to any address. Used to initialize pointers or indicate an invalid state.

Sample Code

double_value() modifies the caller's variable through a pointer. swap() swaps the values of two variables.

pointer_basic.c
#include <stdio.h>

void double_value(int *p) {
    *p = *p * 2; // Doubles the value at the address the pointer points to.
}

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

int main(void) {
    int x = 10;
    int *p = &x; // Stores the address of x in p.

    printf("Value of x: %d\n", x);              // Prints '10'.
    printf("Address of x: %p\n", (void *)&x);
    printf("Value of p (address): %p\n", (void *)p);
    printf("Value p points to: %d\n", *p);      // Prints '10'.

    // Modifies the value through the pointer.
    *p = 20;
    printf("x after modification: %d\n", x);    // Prints '20'.

    // Passes a pointer to a function to modify the value.
    double_value(&x);
    printf("x after doubling: %d\n", x);        // Prints '40'.

    // Swapping values.
    int a = 5, b = 9;
    swap(&a, &b);
    printf("a = %d, b = %d\n", a, b);           // Prints 'a = 9, b = 5'.

    // Example of a NULL check.
    int *q = NULL;
    if (q == NULL) {
        printf("The pointer is NULL.\n");
    }

    return 0;
}
gcc pointer_basic.c -o pointer_basic
./pointer_basic
Value of x: 10
Address of x: 0x...
Value of p (address): 0x...
Value p points to: 10
x after modification: 20
x after doubling: 40
a = 9, b = 5
The pointer is NULL.

Pointers and Arrays

In C, an array name is treated as a pointer to its first element. Pointers and arrays differ in notation, but internally they use the same address arithmetic.

pointer_array_demo.c
#include <stdio.h>

int main(void) {
    int scores[5] = {85, 92, 78, 95, 88};
    int *p = scores; // 'scores' is equivalent to '&scores[0]'.

    // Pointers and arrays refer to the same elements.
    printf("scores[2] = %d\n", scores[2]);  // 78
    printf("*(p + 2) = %d\n", *(p + 2));   // 78 (pointer arithmetic)
    printf("p[2]     = %d\n", p[2]);        // 78 (array notation)

    // Loop through an array using a pointer.
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(p + i)); // 85 92 78 95 88
    }
    printf("\n");

    // Strings can also be handled with pointers.
    const char *name = "Kusanagi Kyo";
    printf("%s\n", name); // Kusanagi Kyo

    return 0;
}
gcc pointer_array_demo.c -o pointer_array_demo
./pointer_array_demo
scores[2] = 78
*(p + 2) = 78
p[2]     = 78
85 92 78 95 88
Kusanagi Kyo

For more details on pointers and arrays, see Pointers and Arrays.

Double Pointers (Pointer to a Pointer)

A double pointer (double indirection) holds the address of a pointer variable. It is used when a function needs to modify the caller's pointer—for example, to allocate memory inside a function.

double_pointer.c
#include <stdio.h>
#include <stdlib.h>

// Initializes the caller's pointer inside the function.
void init_array(int **pp, int size) {
    *pp = malloc(sizeof(int) * size);
    if (*pp == NULL) return;
    for (int i = 0; i < size; i++) {
        (*pp)[i] = (i + 1) * 10;
    }
}

int main(void) {
    int *arr = NULL;
    init_array(&arr, 5); // Pass the address of 'arr' to let the function initialize it.
    if (arr == NULL) { return 1; }

    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); // 10 20 30 40 50
    }
    printf("\n");

    free(arr);
    arr = NULL;
    return 0;
}
gcc double_pointer.c -o double_pointer
./double_pointer
10 20 30 40 50

Common mistake 1: dereferencing an uninitialized pointer

Dereferencing an uninitialized pointer causes undefined behavior (runtime crash). Always initialize a pointer to NULL when you declare it.

uninitialized_ptr_ng.c
// NG: Dereferencing an uninitialized pointer (undefined behavior).
int *p;
*p = 42; // Causes a crash.
gcc -o uninitialized_ptr_ng uninitialized_ptr_ng.c
./uninitialized_ptr_ng
Segmentation fault (core dumped)
// OK: Always initialize to NULL before use.
int *p = NULL;
if (p != NULL) {
    *p = 42; // Use only after a NULL check.
}

Common mistake 2: dangling pointer

Using a dangling pointer (a pointer to freed memory) causes undefined behavior. Always assign NULL after freeing.

// NG: Using a dangling pointer (pointer to freed memory).
int *q = malloc(sizeof(int));
free(q);
*q = 99; // Memory is already freed — undefined behavior.
// OK: Assign NULL after freeing.
free(q);
q = NULL; // Prevents a dangling pointer.

Notes

In C, function arguments are passed by value (copied) by default. To modify a variable inside a function, pass a pointer to it. The function can then write to that address to change the caller's variable.

Dereferencing an uninitialized pointer or a pointer to freed memory causes crashes and undefined behavior. Initializing pointers when you declare them and assigning NULL after use helps avoid undefined behavior.

For the relationship between pointers and arrays, see Pointers and Arrays. For dynamic memory allocation and deallocation, see malloc() / free().

If you find any errors or copyright issues, please .