days since this article was written, please be aware of its timeliness
Preface
Beginners often feel confused about pointers when learning C. Below, I’ll share my understanding of them.
Clarifying a Few Questions First
The Essence of Variables
The essence of a variable is a name representing a memory address. In compiled object code, variable names don’t exist. During compilation, the compiler creates a mapping table linking variable names to their corresponding memory addresses, recording the variable’s type, name, and address.
When declaring a variable, you’re essentially requesting a segment of memory from the operating system. Assigning a value means writing data to that address.
The Nature of Variable Assignment
Declare a variable x with address 0x0001, storing the value 1. Assigning 2 to x involves the following steps:
- Look up variable x’s address in the mapping table, obtaining 0x0001.
- Store the value 2 at that address. Assignment is complete.
Pointer assignment follows the same principle.
The Three Meanings of *
- When declaring a function prototype, such as:The *a here indicates that the function fn accepts a pointer variable (i.e., a memory address) as a parameter, with the parameter being a.
1
void fn(int *a) - In the function body, when *a appears on the left side of an equals sign, it means storing the value on the right into the memory address represented by pointer a, e.g.:
1
2
3void fn(int *a) {
*a = 3;
} - In the function body, when *a appears on the right side of an equals sign, it means retrieving the value stored at the memory address represented by pointer a:
1
2
3void fn(int *a) {
int tmp = *a;
}
Example: A Function to Swap Two Variables’ Values
1 | |
Explanation of the example:
- In main, two variables x and y are declared. Their addresses are &x and &y, storing the values 1 and 2, respectively.
- When encountering the swap function, note that:
- It declares two pointers as parameters. int *a or int *b as formal parameters indicates that they can point to values of type int, meaning the function expects two addresses pointing to int values as arguments. Here, * signifies accepting pointer variables.
- Executing the swap function:
- The formal parameter a is assigned &x, the memory address of x. Thus, the local variable a’s memory address stores x’s memory address. Similarly, formal parameter b is assigned &y, the memory address of y. (Adding * to formal parameters simply indicates they are pointer types.)
- Declare a local integer variable tmp. *a means:
- Step 1: Locate a’s memory address.
- Step 2: Read the value stored at a’s memory address, which is also a memory address—the address of variable x.
- Step 3: Return the value at a’s address, i.e., the value stored at x’s address, which is 1.
- _b means retrieving the value stored at the memory address held by variable b (a memory address), i.e., the value at &y, which is 2. This is then assigned to *a, meaning the value at the memory address &x (since a = &x), i.e., x’s value, which is 1. Note that within swap, the value at x’s memory address in main is modified.
- In the last line, tmp holds the value 1, which is assigned to *b, meaning the value at b’s memory address (originally 2) is overwritten with 1. Here, swap also modifies the value at y’s memory address in main via the pointer.
For better understanding, here’s an illustration:


I often wish that when facing some key decisions in life, someone could tell me the best course of action so that I would not waste my precious time. Putting myself in others' shoes, I therefore write blogs often, hoping to record in this tiny corner of the vast Internet the once-in-a-lifetime experiences that matter to me, and to help those who seek help.