这里还有一个关于指针的问题:
打印某些内容或不影响存储在特定地址的值有何影响?
l-k 的值等于 1,这就是为什么我要检查存储在 k+1 处的值是否等于 88。
#include <iostream>
int main()
{
int i=55;
int j=88;
int *k=&i;
int *l=&j;
k++;
// printf("%p\n",l-k);
/* Why does uncommenting previous line changes the output from 0 to 88? */
printf("%i",*k);
return 0;
}
同时
k++;
是允许的(您可以设置一个指针,使其超过标量的地址 并且 读取该指针值),k
的后续
取消引用的行为是 未定义。有点矛盾的是,这意味着整个程序的行为是未定义的。
l-k
的行为也将是未定义的。指针算术(包括两个指针之间的差异)仅在数组内定义。为此,可以将对象视为单个元素数组。
关于标题中的问题:
如果指针存储的是变量的地址,并且本身就是一个变量,那么它不是会创建无限的指针并填满整个系统内存吗?
不。我添加了一些代码来转储每个
i
、j
、k
和 l
的地址和内容,结果如下:
Item Address 00 01 02 03
---- ------- -- -- -- --
i 0x7ffee31d3a48 37 00 00 00 7...
j 0x7ffee31d3a44 58 00 00 00 X...
k 0x7ffee31d3a38 48 3a 1d e3 H:..
0x7ffee31d3a3c fe 7f 00 00 ....
l 0x7ffee31d3a30 44 3a 1d e3 D:..
0x7ffee31d3a34 fe 7f 00 00 ....
希望输出是不言自明的 - 每行显示项目的名称、地址和内容(均以十六进制形式和字节序列形式)。
我使用的是小端系统,因此必须从下到上、从右到左读取多字节对象。
无论如何,
i
位于地址0x7ffee31d3a48
并存储值55
(0x37
)。 k
位于地址 0x7ffee31d3a38
并存储值 0x7ffee31d3a48
,即 i
的地址。
地址不存在无限回归。
k
是只是另一个变量 - 它和 i
之间的唯一区别是它存储不同类型的值。
至于你的另一个问题:
为什么取消注释上一行会将输出从 0 更改为 88?
表达式
k++
改变了 k
所指向的内容 - 它不再指向 i
。 这是该表达式之后程序的状态:
Item Address 00 01 02 03
---- ------- -- -- -- --
i 0x7ffee31d3a48 37 00 00 00 7...
j 0x7ffee31d3a44 58 00 00 00 X...
k 0x7ffee31d3a38 4c 3a 1d e3 L:..
0x7ffee31d3a3c fe 7f 00 00 ....
l 0x7ffee31d3a30 44 3a 1d e3 D:..
0x7ffee31d3a34 fe 7f 00 00 ....
不再存储
i
(0x7ffee31d3a48
) 的地址,k
现在存储地址 0x7ffeee31d3a4c
,它……不是程序中任何对象的地址。 此时,尝试取消引用k
会调用未定义的行为 - 您的代码可能会崩溃,或者您可能会得到意外的输出,或者通过一些奇迹您可能会得到您期望的结果。 删除 printf
语句会更改程序在内存中的布局,这将影响 k
表达式后面的 k++
所指向的内容。
实际上,这是未定义的行为。这里:
k++;
增加指针,使其指向不同的内存位置,并将其前进
int
的大小。如果 i
是多个整数的数组,它将指向行中的下一个。但事实并非如此,因此稍后在打印中从该指针读取是未定义的行为,并且它可能从未指定的位置读取。
当我在 MSVC 中尝试这个程序时,它不会打印
0
或 88
,它每次都会打印 -858993460
。不同的编译器可能会打印出完全不同的东西,一些改变的东西,或者只是让程序崩溃,甚至做一些与所有这些不同的事情。
如果取消注释一行会影响输出,则您的代码可能具有未定义的行为。通过实际阅读代码可以清楚地看出这一点,尤其是这两行。
这条线没问题。
int *k=&i;
但是你希望这条线做什么?
k++;
i
是单个 int
,因此将 k
指向 int
没有任何意义或用途,因为您可以访问内存的任何部分,这一点可以从有时得到 0 或有时得到 88 的事实中看出。 .
如有疑问,
如果指针存储的是变量的地址,并且本身就是一个变量,那么它不是会创建无限的指针并填满整个系统内存吗?
不,原因如下。您知道每个变量都存储在程序中的特定地址上(对于不同的编译/用户,它可能会有所不同)。现在,该地址正是变量所在的位置。但是,声明时的指针 - 将收集该地址并将其分配给另一个变量。 例如: 代码1:
int a = 5;
假设“a”存储在地址 xyz123 处。现在,该地址尚未作为信息存储。 但是,在本守则中:
int a = 5;
int* b = &a;
这会将“a”的地址存储在名为“b”的变量中。其中,b 再次具有尚未作为信息存储在存储器中的地址。 希望有帮助!!!