- Get an address with
&and read or change the value a pointer points to with* - Change the caller's variables by passing pointers to a function
- Explain pointer arithmetic and why
arr[i]is the same as*(arr + i) - Recognize the danger of
NULLand uninitialized pointers
To show a friend where you live, you don't carry your house over — you just give the address: “Baku, Nizami Street, 25”. Someone who knows the address can find the house, go inside and even change something there. Computer memory works the same way: every variable lives at a certain address. A variable that stores an address is called a pointer. Pointers are C's most powerful and most feared topic, but the idea is as simple as that address.
Addresses and pointers
A variable whose value is the memory address of another variable. int *p; means “p stores the address of an int”.
| Syntax | Meaning |
|---|---|
int *p; | declares a pointer to an int |
&x | the address of the variable x |
p = &x; | p now points to x |
*p | the value at the address in p (dereferencing) |
NULL | a pointer that points to nothing |
#include <stdio.h>
int main(void) {
int x = 10;
int *p = &x;
printf("x = %d\n", x);
printf("*p = %d\n", *p);
*p = 25;
printf("x = %d\n", x);
printf("Same address? %d\n", p == &x);
return 0;
}x = 10 *p = 10 x = 25 Same address? 1
*p = 25; changed x without mentioning its name, because p holds its address.You can print the address itself with the %p specifier. It usually looks like a hexadecimal number such as 0x7ffd… and may be different every time you run the program:
int x = 10;
int *p = &x;
printf("Address of x: %p\n", (void *) &x);
printf("Value of p: %p\n", (void *) p);Passing pointers to functions: swap
Remember: in C a function receives copies of its arguments, so you cannot swap two variables through ordinary parameters. The solution is to give the function the addresses of the variables. Through the addresses, the function reaches the original variables. This is exactly why scanf("%d", &age) needs the &.
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main(void) {
int x = 3, y = 8;
printf("Before: x = %d, y = %d\n", x, y);
swap(&x, &y);
printf("After: x = %d, y = %d\n", x, y);
return 0;
}Before: x = 3, y = 8 After: x = 8, y = 3
Pointers also let a function “return” several results: return gives back only one value, but a function can write its results to the addresses it was given. The function below finds the lowest and highest of several temperatures measured in Baku:
#include <stdio.h>
void min_max(const int *arr, int n, int *min, int *max) {
*min = arr[0];
*max = arr[0];
for (int i = 1; i < n; i++) {
if (arr[i] < *min) *min = arr[i];
if (arr[i] > *max) *max = arr[i];
}
}
int main(void) {
int temps[5] = {18, 25, 21, 30, 16};
int low, high;
min_max(temps, 5, &low, &high);
printf("Min: %d, max: %d\n", low, high);
return 0;
}Min: 16, max: 30
Pointer arithmetic and arrays
In expressions, an array's name turns into the address of its first element, so you can write int *p = arr;. Adding 1 to a pointer moves it forward by one element, not by one byte: usually 4 bytes for an int *. So *(p + 2) is the third element, and arr[i] is simply a short form of *(arr + i). When you pass an array to a function, what is really passed is a pointer to its first element — that is why the function can change the original array and why the sizeof trick does not work on a parameter.
#include <stdio.h>
int main(void) {
int arr[4] = {10, 20, 30, 40};
int *p = arr;
printf("%d\n", *p);
printf("%d\n", *(p + 2));
p++;
printf("%d\n", *p);
printf("%d\n", arr[3] == *(arr + 3));
int sum = 0;
for (int *q = arr; q < arr + 4; q++) {
sum += *q;
}
printf("Sum: %d\n", sum);
return 0;
}10 30 20 1 Sum: 100
p++ moved the pointer to the next element. The last loop walks through the array with a pointer instead of an index.Dangerous pointers
- An uninitialized pointer holds a random address. Writing through it can destroy other data. Always initialize a pointer with a variable's address or with
NULL. - **Dereferencing a
NULLpointer** (*pwhilepisNULL) usually crashes the program at once. Check before use:if (p != NULL). - A dangling pointer points to a variable that no longer exists. For example, if a function returns the address of its own local variable, that variable disappears when the function ends.
int *make_number(void) {
int local = 5;
return &local;
}local disappears when the function ends, and the returned address points to “nothing”. The result is unpredictable.Key points
- A pointer stores an address:
int *p = &x;—pis the address ofx. &gives the address;*reads or changes the value at that address.- A function that receives pointers can change the caller's variables (
swap,scanf). p + 1moves one element forward;arr[i]means*(arr + i).- Always initialize pointers, check for
NULL, and never return the address of a local variable.
Check yourself
10 questions. Every correct answer earns XP.
int x = 4; int *p = &x; *p = 9;, what is x?