数组作为指针

时间:2014-02-22 11:10:48

标签: c++ c

int main()
{
   int x[2][2][2]={1,2,3,4,5,6,7,8};
   printf("%d%d%d%d",&x,&*x,&**x,&***x);
}
  

显示的输出是-28 -28 -28 -28。   有人可以请求expalin这个scenerio.address是-28。它指向-28。如果可能的话,请用图解释。

3 个答案:

答案 0 :(得分:1)

欢迎使用数组指针衰减的深度。会发生什么:

  1. x的类型是3D数组,int ()[2][2][2]

  2. 如果你拿它的地址,没有什么特别的事情,你得到一个指向那个数组的指针,i。即&x的类型为int (*)[2][2][2]

  3. 但是,在大多数其他上下文中,数组不是直接使用的,它们首先衰减成指向其第一个元素的指针。因此,在表达式*x中,x首先衰减为类型int (*)[2][2]的指针(3D数组的第一个元素是2D数组)。然后取消引用此指针以生成2D数组int ()[2][2]

  4. 由于首先存储3D阵列的第一个切片,因此其地址与3D阵列的地址相同。 I. e。 &x&*x会产生相同的地址。

  5. 第二次取消引用时会发生同样的事情&**x会为您提供3D数组中第一行的地址(其类型为int (*)[2])。

  6. 同样,当您第三次取消引用时会发生同样的事情,&***x是数组中第一个元素的地址(其类型为int*)。

    < / LI>

    数组指针衰减的机制允许C严格按照指针算法定义数组下标运算符。关键是,所涉及的三种数组类型中的每一种都具有不同的大小,这允许编译器推导出正确的偏移量。 I. e。 sizeof(*x)4*sizeof(int)(请记住*x的类型为int ()[2][2]),sizeof(**x)2*sizeof(int)。因此,x[1][0]x[0][1]会解析为3D数组中的两个不同的线阵列。

答案 1 :(得分:0)

格式说明符%d用于类型int。你给它一些其他类型,因此,程序的行为是未定义的。您可能想尝试%p(虽然它可能会显示类似的结果,此时您需要开始了解指针的内容)。

答案 2 :(得分:0)

结果相同,但它们的类型与下面所示的不同。 首先必须要知道“类型为T的n个元素数组”类型的表达式已经衰减 到“类型为T的指针”,但当array是&amp;,sizeof运算符或字符串文字的操作数时有例外。

表达

&a  // type is  int(*)[2][2][2]
&*a // type is int(*)[2][2]
&**a // type is int(*)[2]
&***a // type is int  *

在上述情况下,您总是使用&运算符,这意味着表达式不会衰减为“T型指针”,如前所述。 请注意,all的输出将相同,但它们的类型不同,输出将是数组的基址。如果你写

,下面是区别
int (*p)[2][2][2] = &a; // note types are same as shown above
//print p here

现在,如果你这样做

p++;
printf("%p",p);

注意p的两个值之间的差异。然后你必须注意到p跳过整个数组,即所有8个元素。 如果你这样做

int (*q)[2][2] =  &*a;    // note types are same

相同
int(*q)[2][2] = &a[0];

之后你做

q++;

然后打印q并注意原始q和更新q的值之间的差异。您会发现它现在指向内存中的下一个位置。 所以差异就在于此。 同时在您的问题中将%d更改为%p