C Pointers
C - Pointers
Section titled “C - Pointers”Pointers are one of C’s most powerful and distinguishing features. They allow for direct memory manipulation, efficient data handling (like passing large structures to functions), dynamic memory allocation, and are essential for building complex data structures.
At its core, a pointer is a variable that stores the memory address of another variable.
Memory Addresses
Section titled “Memory Addresses”Every variable you declare resides at a specific location in the computer’s memory. This location has a unique address. You can obtain the address of a variable using the address-of operator (&).
To print memory addresses portably, use the %p format specifier with printf and cast the address to (void *).
#include <stdio.h>
int main(void) { int count = 10; double price = 99.99; char grade = 'A';
// Get and print the memory address of each variable printf("Address of count: %p\n", (void *)&count); printf("Address of price: %p\n", (void *)&price); printf("Address of grade: %p\n", (void *)&grade);
return 0;}When you compile and run this, you’ll see hexadecimal numbers representing the memory locations (the exact values will vary each time you run it and on different systems):
Address of count: 0x7ffc1a4b9c8cAddress of price: 0x7ffc1a4b9c90Address of grade: 0x7ffc1a4b9c8bWhat Are Pointers?
Section titled “What Are Pointers?”A pointer variable is declared to hold such an address. The declaration specifies the type of data the pointer will point to. This is crucial because it tells the compiler how many bytes to read/write when the pointer is dereferenced and how to perform pointer arithmetic.
Pointer Declaration Syntax:
type *pointer_variable_name;Here, type is the data type of the variable that the pointer will point to (e.g., int, double, char, struct Point). The asterisk (*) indicates that pointer_variable_name is a pointer.
Examples of pointer declarations:
int *p_int; // Pointer to an integerdouble *p_double; // Pointer to a doublechar *p_char; // Pointer to a characterstruct Point *p_pt; // Pointer to a struct Point variableNote: The actual value stored in any pointer variable (regardless of the type it points to) is a memory address (often represented as a large unsigned integer). The type part is essential for the compiler’s interpretation when using the pointer.
How to Use Pointers?
Section titled “How to Use Pointers?”The fundamental operations involving pointers are:
- Declaration: Declare a pointer variable of the appropriate type.
- Assignment: Assign the address of a variable (obtained using
&) to the pointer. - Dereferencing: Access the value at the address stored in the pointer using the dereference (or indirection) operator (
*).
Example:
#include <stdio.h>
int main(void) { int score = 95; int *p_score; // 1. Declare a pointer to an integer
p_score = &score; // 2. Assign the address of 'score' to 'p_score'
printf("Address of score variable : %p\n", (void *)&score); printf("Address stored in p_score : %p\n", (void *)p_score); printf("Value of score variable : %d\n", score);
// 3. Dereference p_score to get the value stored at that address printf("Value via p_score (*p_score): %d\n", *p_score);
// Modifying the value *through* the pointer *p_score = 100; // Change the value at the address p_score holds printf("New value of score : %d\n", score); // Original 'score' is changed!
return 0;}Output (addresses will vary):
Address of score variable : 0x7ffd6e0f8a5cAddress stored in p_score : 0x7ffd6e0f8a5cValue of score variable : 95Value via p_score (*p_score): 95New value of score : 100NULL Pointers
Section titled “NULL Pointers”It’s crucial to initialize pointers before using them. If you don’t have a valid address to assign immediately, initialize the pointer to NULL. NULL is a special macro (defined in <stddef.h>, <stdio.h>, and others) representing a null pointer constant (typically (void *)0).
A NULL pointer signifies that the pointer is intentionally not pointing to any valid memory location.
#include <stdio.h>#include <stddef.h> // For NULL definition
int main(void) { int *p_data = NULL; // Initialize pointer to NULL
printf("Value of p_data: %p\n", (void *)p_data);
// --- Attempting to dereference a NULL pointer causes Undefined Behavior (often a crash!) --- // *p_data = 10; // DANGER! DO NOT DO THIS!
// Always check if a pointer is NULL before dereferencing if (p_data != NULL) { printf("Value pointed to: %d\n", *p_data); } else { printf("p_data is a NULL pointer.\n"); }
// Alternative check if (!p_data) { // Evaluates to true if p_data is NULL printf("p_data is NULL (checked using !p_data).\n"); }
return 0;}Output:
Value of p_data: (nil) // Or 0x0, depending on system printfp_data is a NULL pointer.p_data is NULL (checked using !p_data).Dereferencing a NULL pointer is a common programming error that typically leads to a program crash (Segmentation Fault). Always check pointers, especially those returned from functions like malloc or used in data structures, before dereferencing.
C Pointer Concepts
Section titled “C Pointer Concepts”Pointers enable many essential C programming techniques:
| Concept | Description |
|---|---|
| Pointer Arithmetic | Performing arithmetic operations (+, -, ++, --) on pointers. Incrementing a pointer moves it forward by sizeof(pointed-to-type) bytes. Essential for array traversal. |
| Pointers and Arrays | An array name often ‘decays’ into a pointer to its first element in expressions. Pointers are commonly used to iterate through arrays efficiently. |
| Array of Pointers | Creating arrays where each element is a pointer (e.g., an array of strings, where each element points to the first character of a string). |
| Pointer to Pointer (Double Pointer) | A pointer that stores the address of another pointer (e.g., int **p). Used for modifying pointers passed to functions or for arrays of pointers. |
| Pointers and Functions | Passing pointers to functions allows the function to modify the original data (pass-by-reference simulation). Functions can also return pointers (e.g., malloc). |
| Dynamic Memory Allocation | Using functions like malloc, calloc, realloc (from <stdlib.h>) to allocate memory at runtime. These functions return pointers to the allocated block, which must be managed (freed using free) by the programmer. |
| Function Pointers | Pointers that store the address of a function. Allow functions to be passed as arguments to other functions (callbacks) or stored in data structures. |
These concepts build upon the fundamental understanding of pointer declaration, assignment, and dereferencing, and will be explored in more detail in relevant sections.