关于指针指针的问题

时间:2017-01-14 18:03:47

标签: c++

nextDay()

如果我运行上面的C ++代码,输出将是:

0x28fef0

0x28fef0

0

0

我知道x的值是变量a的地址,y的值是变量x的地址。但是怎么来x = y + 1? y + 1,(y + 1)[0]和y [1]是什么意思?谢谢你的帮助!

3 个答案:

答案 0 :(得分:9)

  

怎么来x = y + 1?

偶然。您的编译器恰好在内存中布置xy,使得一个紧跟在另一个之后。它没有义务这样做,所以你不能依赖这种行为。

请注意,解除引用y+1,例如通过(y+1)[0]y[1]*(y+1),也有undefined behaviour

答案 1 :(得分:1)

  • a是一个整数变量,其值为4
  • x是一个指向整数的指针,该整数包含a
  • 的地址
  • y是一个指向整数指针的指针,即它指向一个变量,它是一个整数指针本身,这里,它的值是x的地址。

现在,

  • 当您打印x的值时,会打印出其中包含的地址,即a的地址。
  • y包含x的地址。 y+1y中存储的地址旁边的地址。在这里,巧合的是,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