nextDay()
如果我运行上面的C ++代码,输出将是:
0x28fef0
0x28fef0
0
0
我知道x的值是变量a的地址,y的值是变量x的地址。但是怎么来x = y + 1? y + 1,(y + 1)[0]和y [1]是什么意思?谢谢你的帮助!
答案 0 :(得分:9)
怎么来x = y + 1?
偶然。您的编译器恰好在内存中布置x
和y
,使得一个紧跟在另一个之后。它没有义务这样做,所以你不能依赖这种行为。
请注意,解除引用y+1
,例如通过(y+1)[0]
,y[1]
或*(y+1)
,也有undefined behaviour。
答案 1 :(得分:1)
a
是一个整数变量,其值为4
。x
是一个指向整数的指针,该整数包含a
。y
是一个指向整数指针的指针,即它指向一个变量,它是一个整数指针本身,这里,它的值是x
的地址。现在,
x
的值时,会打印出其中包含的地址,即a
的地址。y
包含x
的地址。 y+1
是y
中存储的地址旁边的地址。在这里,巧合的是,y
中存储的地址恰好位于a
的地址之前,因此y+1=x
。没有理由这样做。(y+1)[0]
和y[1]
与*(y+1)
相同。这种解除引用,即提供存储在y
旁边的地址的值,这是未定义的行为。答案 2 :(得分:1)
我们对变量了解的事情:
a是双
& a是指向(double *)
x是指向double类型的元素的指针。
x初始化为指向a,它存储地址(& a)
& x是指向x(双**)
y是指向双/
y初始化为指向x,它存储x地址(& x)
现在,关于表达式:
y + 1以指向的元素大小递增指针,这是指针的大小。
y [0]是y指向的数组的第一个元素。 y指向标量,在这种情况下,它表现为1号元素的数组。它完全等同于解除引用y(* y)。所以,y [0] == * y == x
同样,y [1] == *(y + 1)。由于y指向的“数组”中没有第二个元素,因此该表达式会触发未定义的行为。理想情况下,它会导致异常,但undefined意味着什么。它也可以摧毁宇宙,它将是一个合规的实施。
(y + 1)[0]增加y并对它进行相关,因此(y + 1)[0] == *(y + 1)== y [1]。它等同于前一个,触发相同的未定义行为。
现在,变量的地址完全取决于实现。每次执行时也可能有所不同。
这些变量是自动变量,存储在堆栈中。
在我所知的所有实现中,堆栈从高地址开始并向下增长。
这意味着,同一块中的所有自动变量都会以递减的地址顺序存储在一起。
在您的情况下,编译器按照它们声明的顺序分配堆栈中的变量。
结果是& a> & x> &安培; Y
编译器可能会在中间引入间隙以用于alingment目的。在这种情况下,它要么不是这样,要么在指针算术中考虑它。
因此,当y指向x时,如果向y添加1,则得到a的地址,该地址位于x旁边。
x也指向a,所以你可能会想要说y + 1 == x
在原始地址中,这是真的,但在指针时却不是这样,因为它们的类型不同。
y + 1仍然是双**,而x是双*
我们知道(y + 1)[0] == y [1]。当x [0] == a时,y [1]试图将a的值解释为指向double的指针。在这种情况下你可以说y [1] ==(double *)a
看起来所有这些未定义的行为,在此实现中,导致将值4.0解释为空指针,打印为0