【问题标题】:Why application of indirection to a two-dimensional array gives a pointer?为什么对二维数组应用间接寻址会给出一个指针?
【发布时间】:2021-03-10 21:54:58
【问题描述】:

在阅读了这个网站上的一些帖子后,我意识到 C 中的数组不仅仅是我最初认为的常量指针,而且它本身是一种独特的类型,但在大多数情况下,数组“衰减”为指向数组的第一个元素。由于这些新信息,我的脑海中出现了一个问题。假设我们有一个二维 A[10][10]。为什么表达式 *A 的结果是指向数组第一个元素的指针?我认为在这个表达式中,A 衰减为指向数组 A[0][0] 的第一个元素的常量指针,然后应用间接寻址应该给我们A[0][0]的值,但实际上它仍然给了我们数组第一个元素的地址。当然,我的逻辑或我对数组或指针的理解有问题,我哪里弄错了?

提前致谢。

【问题讨论】:

    标签: c pointers multidimensional-array indirection


    【解决方案1】:

    A 的第一个元素是A[0],而不是A[0][0]

    这是因为A 是一个由十个事物组成的数组。 C 没有二维数组作为主要类型。具有多个维度的数组被派生或构造为多层数组。对于编译器来说,生成的类型仍然只是一个数组,其元素恰好是更多的数组。

    因此,在*A:

    • A 被转换为指向其第一个元素的指针。那个指针是&A[0],所以*A变成*&A[0]
    • *& 取消,所以表达式变为 A[0]
    • A[0] 是一个包含十个元素的数组,因此它被转换为指向其第一个元素 &A[0][0] 的指针。

    【讨论】:

      【解决方案2】:

      *A 或 A[0] 本身是一个包含 10 个元素的数组,并且数组始终由指向其第一个元素的指针表示。然而,A[10][10](假设是一个整数数组)实际上是一块内存,可容纳 100 个整数,第一行的 10,然后是第二行的 10,依此类推。但是如果表达式 *A 或 A[0] 将返回一个 int 而不是 ptr 到该行,那么就不可能使用表达式 A[0][0],对吧?

      但是,由于这样的多维数组是单个内存块,也可以将其转换为指针,然后使用此类表达式访问它:

      ((int *)A)[iRow * 10 + iCol];
      

      相当于表达式:

      A[iRow][iCol];
      

      但是如果这样声明的二维数组是可能的:

      int main()
      {
          int A[10][10] = { 0 };
          A[9][9] = 9999;
          printf("==> %d\n", ((int *)A)[9 * 10 + 9]); //==> 9999
          return 0;
      }
      

      如果内存可能由单独的字节块组成(可能需要多次调用 malloc),则不会像这种表达式那样:

      int * A[10]; // or
      int ** A;
      

      【讨论】:

      • 该转换不是一维数组,而是一个指针。这是吹毛求疵,但当它是问题和答案的主要焦点时,最好准确:)。您可以转换为 int(*)[100] 以使其成为指向一维数组的指针。
      【解决方案3】:

      A 衰减为指向数组第一个元素的常量指针 A[0][0]

      不,它没有。为什么?

      C 标准指定*(pointer + integer) == pointer[integer],因此*A 等效于*(A + 0),即A[0]A[0]只为您提供元素 A[0][0],该元素将衰减为指向该数组第一行的第一个元素的指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-02
        • 2021-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-22
        • 2012-03-16
        相关资源
        最近更新 更多