所以,让我们一步一步来。我只会向您展示内存操作,并让您了解正在打印的内容。每个内存位置(框)上方是其各自的地址,内部是其内容。
请注意,变量上方的内存地址是指示性的。不能保证变量会以这种方式放置在堆栈中(很可能不会)。
int *p, *q;
在这里,您没有声明“指向p
or的指针q
”,而是声明了 2 个指向int
、 称为p
and的指针q
。
int **s;
int ***t;
同样,指向int
被调用指针的指针和指向被调用指针s
的指针。int
t
所以让我们“绘制”到目前为止的记忆。
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 |
+------+ +------+
k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C
+------+ +------+------+------+------+------+
|0x100C|---->| 10 | 20 | 30 | 40 | 50 |
+------+ +------+------+------+------+------+
p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C
+------+ +------+ +------+ +------+
|XXXXXX| |XXXXXX| |XXXXXX| |XXXXXX|
+------+ +------+ +------+ +------+
现在,让我们运行代码:
p = &i;
现在p
指向i
:
i: 0x1000 j: 0x1004
+------+ +------+
+-->| 50 | | 100 |
| +------+ +------+
|
| k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C
| +------+ +------+------+------+------+------+
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 |
| +------+ +------+------+------+------+------+
|
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C
| +------+ +------+ +------+ +------+
+---|0x1000| |XXXXXX| |XXXXXX| |XXXXXX|
+------+ +------+ +------+ +------+
下一个命令是:
q = &j;
现在q
指向j
:
i: 0x1000 j: 0x1004
+------+ +------+
+-->| 50 | | 100 |<------------------------------------+
| +------+ +------+ |
| |
| k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +------+------+------+------+------+ |
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1000| |0x1004|-+ |XXXXXX| |XXXXXX| |
+------+ +------+ | +------+ +------+ |
| |
+-----------------------------------+
接下来我们有:
s = &p;
s
是指向指针的指针,int
并且p
是指向 的指针int
。所以现在s
指向p
:
i: 0x1000 j: 0x1004
+------+ +------+
+-->| 50 | | 100 |<------------------------------------+
| +------+ +------+ |
| |
| k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +------+------+------+------+------+ |
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1000| |0x1004|-+ |0x1020| |XXXXXX| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
接下来:
t = &s;
t
是指向指针的指针,int
并且s
是指向指针的指针int
。所以现在t
指向s
:
i: 0x1000 j: 0x1004
+------+ +------+
+-->| 50 | | 100 |<------------------------------------+
| +------+ +------+ |
| |
| k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +------+------+------+------+------+ |
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1000| |0x1004|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
p = q;
我们将 的内容分配q
给p
。这意味着p
不再指向i
,而是现在指向指向的位置q
,即j
:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | +->| 100 |<------------------------------------+
+------+ | +------+ |
+-------------+ |
| k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +------+------+------+------+------+ |
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1004| |0x1004|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
s = &q;
我们分配s
指向 的地址q
。所以,现在s
不再指向p
,而是指向q
:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | +->| 100 |<------------------------------------+
+------+ | +------+ |
+-------------+ |
| k: 0x1008 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +------+------+------+------+------+ |
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1004| |0x1004|-+ |0x1024|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+-----------+
下一个:
p = k;
我们将 的内容分配k
给p
。所以现在p
指向指向的位置k
,也就是数组的第一个元素:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 |<------------------------------------+
+------+ +------+ |
+-------------+ |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +->+------+------+------+------+------+ |
| |0x100C|---->| 10 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x100C| |0x1004|-+ |0x1024|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+-----------+
下一个:
*p = *q;
该命令说:“获取指向的位置的内容q
并将其分配给指向的位置p
”。q
指向j
等于 100 的 ,p
指向数组的第一个元素:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 |<------------------------------------+
+------+ +------+ |
+-------------+ |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ +->+------+------+------+------+------+ |
| |0x100C|---->| 100 | 20 | 30 | 40 | 50 | |
| +------+ +------+------+------+------+------+ |
| |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x100C| |0x1004|-+ |0x1024|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+-----------+
下一个:
p++;
这是“棘手”的命令(尽管当您意识到发生了什么时并不那么棘手)。在正常情况下,这将使p
变量增加 1。但由于p
是指针,它将增加它(应该)指向的变量类型的大小,从而p
指向下一个内存位置。在这种情况下sizeof(int)
,假设是 4(这不一定是真的)。所以现在p
指向数组的下一个单元:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 |<------------------------------------+
+------+ +------+ |
+-------------+ |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 20 | 30 | 40 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1010| |0x1004|-+ |0x1024|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+-----------+
下一个:
s = &p
s
指向 的位置p
:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 |<------------------------------------+
+------+ +------+ |
+-------------+ |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 20 | 30 | 40 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1010| |0x1004|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
**s = 500;
该命令说:“转到指向的位置s
并获取其内容,我们称之为*s
,然后转到指向的位置*s
并分配值 500。s
指向p
,并p
指向第二个数组单元格:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 |<------------------------------------+
+------+ +------+ |
+-------------+ |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 30 | 40 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1010| |0x1004|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
q = p + 2;
同样在这里,如上所述,因为q
andp
是指针,所以这个命令分配给plusq
的内容。指向第二个数组单元,所以现在指向第 4 个数组单元:p
2 * sizeof(int)
p
q
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +-------------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 30 | 40 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1010| |0x1018|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
*q = 1000;
q
转到指向的位置并分配1000:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +-------------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 30 | 1000 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1010| |0x1018|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
p = q - 1;
p
现在将指向 where 指向的先前位置p
,即第三个数组单元:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +-------------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 30 | 1000 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1014| |0x1018|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
*p = 750;
转到p
指向并分配750的位置:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +-------------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 750 | 1000 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1014| |0x1018|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
q++;
同上,移动q
指向它所指向的下一个内存位置,即数组的第 5 个单元:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 750 | 1000 | 50 | |
| +------+ | +------+------+------+------+------+ |
| +-------------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1014| |0x101C|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
*q = *q * 100;
转到指向的位置q
并获取其内容 (50)。乘以 100 (=5000)。最后将此值分配给指向的位置q
:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | 750 | 1000 | 5000 | |
| +------+ | +------+------+------+------+------+ |
| +-------------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1014| |0x101C|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
**s = -100;
s
到指向 ( )的位置,p
获取它的内容,我们称之为*s
。现在转到*s
指向(第 3 个数组单元)的位置并分配 -100:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | -100 | 1000 | 5000 | |
| +------+ | +------+------+------+------+------+ |
| +-------------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1014| |0x101C|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
下一个:
***t = -200;
转到t
指向 ( s
) 的位置并获取其内容,我们称之为*t
。现在转到*t
指向 ( q
) 的位置并获取其内容,我们称之为**t
。现在转到指向的位置**t
(再次是数组的第 3 个单元格)并分配 -200:
i: 0x1000 j: 0x1004
+------+ +------+
| 50 | | 100 | +------------+
+------+ +------+ | |
+-------------+ v |
| k: 0x1008 | 0x100C 0x1010 0x1014 0x1018 0x101C |
| +------+ | +------+------+------+------+------+ |
| |0x100C|--+->| 100 | 500 | -200 | 1000 | 5000 | |
| +------+ | +------+------+------+------+------+ |
| +-------------------^ |
| p: 0x1020 q: 0x1024 s: 0x1028 t: 0x102C |
| +------+ +------+ +------+ +------+ |
+---|0x1014| |0x101C|-+ |0x1020|<----|0x1028| |
+------+ +------+ | +------+ +------+ |
^ | | |
| +------+----------------------------+
| |
+------------------------+
我希望这个答案可以为您和其他人澄清事情。在学习和玩指针时总是画出记忆,它会让你的生活更轻松。
问候。