我有旧考试中的这段代码。
第一次打印生成 5a9b1740。
问题是第二次打印会生成什么。
- x:未知,因为我们不知道 *k 代表什么。
- y:35。
- z: ffff ffff。为什么?
- p:5c9b1748。为什么?
{
int x = 4;
int y = 15;
int *k = &x;
int z;
int *p;
*k = *k * (*k + 1);
y = x + y;
k = &z;
int a[] = {7,9,3,8};
p = a;
printf("%x\n",(unsigned int)p);
x = *k + 1;
p = p + 2;
z = *p - 4;
printf("%d %d %x %x\n",x,y,z,(unsigned int)p);
}
编辑:抱歉造成困惑,第一个打印是 5a9b1740,第二个打印是 5c9b1748。不是 5a9b1740,5c961748。问题就此进行了编辑。
最佳答案
x
: unknown since we do not know what*k
holds.
从技术上讲,*k
的值当x = *k + 1;
被执行是不确定,因为它指向 z
和z
当时尚未初始化。这意味着该值要么是未指定(即它可以具有任何值),要么是陷阱表示(即它不代表有效值,并且如果读取则可能会触发错误)。如果该值恰好是陷阱表示,则读取会调用 undefined behavior .
在某些情况下,读取未初始化的变量仍然可能是未定义的,即使它不是陷阱表示,但这里的情况并非如此,因为 z
地址已被占用。
y: 35.
此时:
*k = *k * (*k + 1);
y = x + y;
k
指向x
4 的值为 4,因此第一行与 x = 4 * (4 + 1)
相同。这一套x
到 20,然后将其添加到 y
的当前值(15) 给出 35。
z: ffff ffff. WHY?
p: 5c9b1748. WHY?
看看这些行:
p = a;
p = p + 2;
z = *p - 4;
这第一点p
到 a
的第一个元素,该指针的值为 5a9b1740,如第一个 printf
所示。 。然后下一行将其指向该元素之后的 2 个元素。假设 int
在你的系统上是 4 个字节,这意味着指针的原始值 p
增加了 2 * 4 = 8。所以 p
的值现在是 5a9b1740 + 8 = 5a9b1748。
与 p
现在指向 a
的第三个元素其值为 3,以下行设置 z
至-1。然后用 %x
打印该值格式说明符,将值解释为 unsigned int
并以十六进制打印它。假设负数的二进制补码表示(再次)是 4 字节 int
,该值的表示形式为 ffffffff
。当读作unsigned int
时这是打印出来的。
关于C 代码、指针及其内容。考试题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60615967/