C 3d阵列指针衰减与&没有& amp;

时间:2016-12-20 00:04:41

标签: c arrays pointers memory-management

#include <stdio.h>
int main(int argc, char const *argv[]) {
     /* code */
     int a[2][3][2] = {{{1,2},
                        {9,8},
                        {3,7}},
                       {{2,2},
                        {1,4},
                        {5,4}}};
     int i,j,k;
     printf("\n\n\n");
     for (i = 0; i < 2; ++i) {
          for (j = 0; j < 3; ++j) {
               for (k = 0; k < 2; ++k) {
                    printf("\t &a[%d][%d][%d] = %p  ",i,j,k,(&a[i][j][k]) ) ;
               }
               printf("\n");
          }
          printf("\n");
     }


     printf("\t a[1] = %p  a[0] = %p\n",a[1],a[0] );
     printf("\t a[1] - a[0] = %d\n",a[1] - a[0] );            //  ????

     printf("\t a[1][0] = %p  a[0][0]= %p\n",a[1][0],a[0][0] );

     printf("\t a[1][0] - a[0][0] = %d\n", a[1][0] - a[0][0]);      // ??????


     return 0;
}

O / P:

 &a[0][0][0] = 0023FF04      &a[0][0][1] = 0023FF08  
 &a[0][1][0] = 0023FF0C      &a[0][1][1] = 0023FF10  
 &a[0][2][0] = 0023FF14      &a[0][2][1] = 0023FF18  

 &a[1][0][0] = 0023FF1C      &a[1][0][1] = 0023FF20  
 &a[1][1][0] = 0023FF24      &a[1][1][1] = 0023FF28  
 &a[1][2][0] = 0023FF2C      &a[1][2][1] = 0023FF30  

 a[1] = 0023FF1C  a[0] = 0023FF04
 a[1] - a[0] = 3
 a[1][0] = 0023FF1C  a[0][0]= 0023FF04
 a[1][0] - a[0][0] = 6

我理解指针的衰减。在上面的代码中,a[1]a[0]都会在实际数组2d内衰减到每个a数组的第一个位置。 当我们采用这两个指针的差异时,它们的行为类似于指向(int*)[]元素的1d数组(2)。

因为我们在这个c程序中处理一个3d数组,我们有四种可能的指针类型。

  1. (int*)[][][]
  2. (int*)[][]
  3. (int*)[]
  4. (int*)
  5. 就指针的值而言,所有类型都会衰减为单个元素位置。

    我的疑问是,即使在腐烂之后,TYPES等可能会产生不同结果的 a[],a[][],&a,a 。 (如上述程序中指针差异的情况)

1 个答案:

答案 0 :(得分:1)

请注意,a不是指针是数组。

所以当你减去指向另一个指针的指针时。结果不是真正的地址,它们之间的元素数量。结果的类型为ptrdiff_t,您应该使用%td打印。

因此,当您执行&a[1] - &a[0]时,您会询问int [][]&a[1]之间有多少&a[0],答案是1

但是,当您使用a[1][0]a[0][0]使用a[1]减去a[0]时,您会有一个未定义的行为,因为:

  

当减去两个指针时,两个指针都应该指向   相同的数组对象,或者超过数组对象的最后一个元素;   结果是两个数组的下标的差异   元件。

a[1][0]a[0][0]a[1]a[0]不是同一个数组/指针。所以你不应该减去它们。但就像我说a是一个数组,所以你有一些结果,如63。对阵列有一些特别的想法。但这只是一个“运气”,它是未定义的行为。

你只能这样做

&a[i] - &a[j];
&a[i][j] - &a[i][k];
&a[i][j][k] - &a[i][j][l];

在您的情况下,因为a是一个数组:

assert(&a[2] - &a[0] == sizeof a / sizeof *a);

了解详情herehere

随意告诉我,我错了。在这个答案中,我不确定自己。