We know that the value of &n is the address of variable
n. However, we haven't discussed that type of &n
until now. The type of &n is int*. Following the same idea,
we can consider the following types as well:
|
|
In general:
int* is a type, we can declare a variable of this type as
follows:
int* p;
p is a memory address.
int n = 1;
int* p;
p = &n; // This assignment makes sense: typeof(p) = int* = typeof(&n)
Indeed, if you have an address, you can access an object at that address in
memory. We call this operation is "dereference". The deference operator is
*.
In a sense, we have two operators having the opposite direction from each other. In particular:
Consider the following code snippet:
|
|
|
What will be the output of code on the right?
Answer: 10 5 |
p points to b (i.e. holds the address of
b). Therefore, *p is really b, which
means that *p = 5 will change the value of b to 5.
|
The picture shows that there are two ways to access an object:
Follow the arrow!
|
// mem.cpp
0 #include <iostream>
1 #include <string>
2 #include <cstdint>
3 using namespace std;
4
5 int main()
6 {
7 int a = 10, b = 7;
8 int* p;
9
10 cout << "&a=" << &a << ", &b=" << &b << ", &p=" << &p << endl;
11 cout << "a=" << a << ", b=" << b << endl;
12
13 uint64_t addr; // uint64_t: 64-bit unsigned integer
14 cin >> hex >> addr; // hex: read in the hexadecimal format
15 p = (int*) addr; // now p contains the address from the terminal
16
17 cout << "*p=" << *p << endl;
18 return 0;
19 }
A sample run up to line 13 is given below:
&a=0x7ffff83497e0, &b=0x7ffff83497e4, &p=0x7ffff83497e8 a=10, b=7
0x7ffff83497e0.
Answer: (Make sure you can draw the following diagram by youself).
address value (variables) ... 0x7ffff83497e0 10 a 0x7ffff83497e4 7 b 0x7ffff83497e8 0x7ffff83497e0 p ...
10
*p corresponds to an int
object at address 0x7ffff83497e0. Well, the int object at address
0x7ffff83497e0 is actually the variable a.
|
|
| operator | in a variable declaration | in an expression |
| * | declaring a pointer type
int* p;
| dereference (*p) = 3;
|
| & | address-of
int* p;
|
int* p; // this is a declaration
// * means pointer declaration
*p = 7; // *p is an expression; the* is used as a unary rather than binary operator
// * means dereference
cout << 3*7; // 3*7 is an expression, and the* is used as a binary operator
// * means multiplication
For example, if x is of type int, then &x is of type int*;
if p is of type int*, then &p is of type int**.
For example, if p is of type int*, then *p is of type int;
if pp is of type int**, then *pp is of type int*;
|
|