DevAcademia
C++C#CPythonJava
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz

Loading C tutorial…

Loading content
C BasicsTopic 43 of 64
←PreviousPrevNextNext→

C Pointers

Introduction to Pointers

Pointers are variables that store memory addresses instead of values. They are one of the most powerful features of C, allowing direct memory manipulation and efficient data handling.

Key concepts:

- Pointers store memory addresses

- The & operator gets the address of a variable

- The * operator dereferences a pointer (accesses the value at the address)

- Pointers have types that determine valid dereferencing and pointer arithmetic

Note: In standard C, pointer arithmetic is only defined within the bounds of the same array object (including one-past-the-end).

Pointer Declaration and Initialization

Example
data_type *pointer_name;
ℹ️ Note: Always initialize pointers (e.g., to the address of a valid object or to NULL). Uninitialized pointers may point to random memory, causing undefined behavior. The pointer's type should match the pointed-to object type.

Basic Pointer Operations

Example
#include <stdio.h>

int main(void) {
    int num = 10;
    int *ptr = &num;
    printf("Value of num: %d\n", num);
    printf("Address of num: %p\n", (void*)&num);
    printf("Value of ptr: %p\n", (void*)ptr);
    printf("Value pointed to by ptr: %d\n", *ptr);
    *ptr = 20;
    printf("New value of num: %d\n", num);
    return 0;
}
Output
Value of num: 10
Address of num: 0x7ffd42a8b54c
Value of ptr: 0x7ffd42a8b54c
Value pointed to by ptr: 10
New value of num: 20
ℹ️ Note: The * token declares a pointer in declarations (e.g., int *p) and dereferences a pointer in expressions (e.g., *p). Use %p with a (void*) cast when printing addresses.

Pointer Arithmetic

Pointer arithmetic moves by the size of the pointed-to type. For an int* on a system where sizeof(int) == 4:

- ptr + 1 advances by 4 bytes

- ptr - 1 moves 4 bytes back

Only perform pointer arithmetic within the same array object (or one past the last element).

Example
#include <stdio.h>

int main(void) {
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr; // arr decays to &arr[0]
    printf("Element 0: %d at %p\n", *ptr, (void*)ptr);
    ptr++;
    printf("Element 1: %d at %p\n", *ptr, (void*)ptr);
    return 0;
}
Output
Element 0: 10 at 0x7ffc5f3a8b60
Element 1: 20 at 0x7ffc5f3a8b64

Void Pointers (Generic Pointers)

A void* can hold the address of any object type, but you must cast it back to the correct type before dereferencing. Standard C does not allow arithmetic on void*.

Example
#include <stdio.h>

int main(void) {
    int x = 42;
    void *vp = &x;            // store address of int in a generic pointer
    printf("x via void*: %d\n", *(int*)vp); // cast before dereferencing
    return 0;
}
Output
x via void*: 42

Null Pointers

A null pointer points to no valid object. Initialize pointers to NULL when they have no valid target yet and always check before dereferencing.

NULL is a macro defined in several headers (e.g., , ) and expands to a null pointer constant. It is not guaranteed to be the same as integer 0 in representation, though it compares equal to 0 in pointer contexts.

⚠️ Warning: Dereferencing a null pointer is undefined behavior and typically crashes the program.
Example
#include <stdio.h>
#include <stddef.h>  // for NULL

int main(void) {
    int *ptr = NULL;
    if (ptr == NULL) {
        printf("Pointer is NULL - safe to check\n");
    }
    return 0;
}

Common Pitfalls & Best Practices

1. Never dereference uninitialized or NULL pointers.

2. After freeing dynamically allocated memory, set the pointer to NULL to avoid dangling pointers.

3. Keep pointer arithmetic within array bounds; out-of-bounds access is undefined behavior.

4. Use const-correctness (e.g., const int *p) when not modifying the pointed-to data.

5. Remember sizeof(*ptr) gives the element size; sizeof(ptr) gives the pointer size.

6. Do not assume pointer size equals int size; both are implementation-defined.

Test your knowledge: C Pointers
Quiz Configuration
4 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
C BasicsTopic 43 of 64
←PreviousPrevNextNext→