使用 & 和不使用 & 的 C 3d 数组指针衰减

标签 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;
}

操作:

 &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 数组的第一个位置一个。 当我们获取这两个指针的差异时,它们的行为就像指向 2 元素的一维数组 ((int*)[]) 的指针。

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

  1. (int*)[][][]
  2. (int*)[][]
  3. (int*)[]
  4. (int*)

就指针的值而言,所有类型都会衰减到单个元素位置。

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

最佳答案

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

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

所以当你这样做时&a[1] - &a[0] ,你问有多少int [][] &a[1]之间有和&a[0]答案是1 .

但是当你减去a[1][0]时与 a[0][0]a[1]a[0] ,您有未定义的行为,因为:

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

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 .

请随时告诉我我错了。我对这个答案并不确定。

关于使用 & 和不使用 & 的 C 3d 数组指针衰减,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41232948/

相关文章:

c - 在函数的参数中声明指针类型以修改链表

c - x86 汇编例程无缘无故卡住

c - 通过 UART 使用 ASCII

c - 检查文件是否存在后更改 fopen 模式的正确方法是什么?

java - 从 ArrayList 中获取随机元素,添加到另一个 ArrayList 并从第一个 ArrayList 中删除该元素 Android

pointers - F# - 是否需要明确删除引用单元格?

c - 如何修复序列反转程序中的这个段错误?

javascript - 同时循环遍历两个数组,并使用 Angular js [Angular 新手] 将每个数组的第一个元素一次传递给函数

arrays - 从 Swift 数组中获取随机元素出现

C++:原始指针的容器