【问题标题】:Pointers with two dimensional array具有二维数组的指针
【发布时间】:2012-10-03 19:07:03
【问题描述】:

请考虑以下代码

#include <stdio.h>
#define ROW_SIZE 2
#define COL_SIZE 2

int main()
{
   int a[ROW_SIZE][COL_SIZE]={{1,2},{3,4}};

   // Base address:Pointer to the first element a 1D array
   printf("Base address of array:%p\n",a);

   //The value at the base address: should be the address of 1st 1D array
   printf("Value at the Base address:%p\n",*a);

   return 0;
}

得到的输出:

Sample Output:
Base address of array:0xbff77434
Value at the Base address:0xbff77434

不知何故,我无法理解 2D 数组的基地址的概念和基地址的值,而基地址的值又是 1D 数组的地址。请解释一下。

【问题讨论】:

标签: c arrays pointers multidimensional-array


【解决方案1】:

数组不是指针,在 C 中,多维数组只是数组的数组。在许多情况下,使用数组名称“衰减”为指向该数组第一个元素的指针。这就是您的两个打印语句中发生的情况。第一种情况:

printf("Base address of array:%p\n",a);

a 成为指向数组第一个元素的指针——即指向数组第一行的指针。在你的情况下,这意味着你得到了一个 int (*)[2] 类型的指针。

第二种情况:

printf("Value at the Base address:%p\n",*a);

同样的衰减发生了,但是你取消了那个指针的引用。这意味着您取消了指向第一行的 int (*)[2] 指针,从而再次为您留下一个数组(第一行)。该数组本身衰减为指向第一个元素的指针,从而为您提供int *指针(指向第一行的第一个元素)。

在这两种情况下,地址都是相同的,因为这就是数组在内存中的布局方式。如果我们说您的 2D 数组从地址 0 开始,它看起来像这样(假设是 4 字节 int 类型):

 Address       Value
    0            1
    4            2
    8            3
   12            4

第一行的地址和第一行的第一个元素的地址都是0

【讨论】:

    【解决方案2】:

    重新构建问题中的图表并整合先前答案中的信息,我正在创建以下答案。

    一维数组

    • 将 4 个整数的数组 a 视为a[4]
    • 基本规则是a&amp;a 都指向同一个位置。但它们指向同一个类型。
    • &amp;a 将指向整个数组,即int[]。指针类型为int(*)[]
    • a,当它衰减为指针时,将指向数组的第一个元素,即int。指针类型为int *

    二维数组

    • 考虑一个包含两个一维数组的数组,每个数组都有两个元素 ;a[2][2]
    • 由于维数增加,我们多了一层层次结构,即&amp;aa*a 将指向同一个位置,但它们指向同一类型。
    • &amp;a 将指向整个数组,即int[][]。指针类型为int(*)[][]
    • a,当它衰减为指针时,将指向二维数组的第一个元素,即int[]。指针类型为int(*)[]
    • 通过使用*a,我们取消了指向一维数组的指针。因此,我们将有一个int * 指向二维数组的第一个整数值。

    【讨论】:

      【解决方案3】:

      我认为您的输出格式会让您感到困惑。你是对的,第一个数组元素的地址 (0xbff77434) 与值 (1) 不同。 %p 在试图强制两者都使用“指针”格式时感到困惑。

      是的,卡尔也是正确的。

      如果您想查看 第一个元素是什么,您可以说以下任何一种:

      printf("%i", a[0][0]);
      
      int* p = &a[0][0];    // point 'p' to the beginning of 'a'
      // (or)
      int* p = a;           // saying "&a[0][0]" is the same as saying "a"
      printf("%i", *p);     // here, the dereference is what you want
      

      就一维数组和二维数组而言,这只是一个解释问题。两者都有

      int x[4];
      

      int x[2][2];
      

      创建由 4 个“int-sized”元素组成的连续块。在这两种情况下,表达式“x”指的是第 0 个条目的地址(例如,数组的地址)。

      【讨论】:

        【解决方案4】:

        二维数组a[2][2]可以看成是一个有4个元素的一维数组。想想当你将a 转换为int* 指针时会发生什么:

        int a[2][2] = {{ 1, 2 }, { 3, 4 }};
        int* p = (int*) a; // == { 1, 2, 3, 4 }
        
        assert(a[1][0] == p[2] == 3); // true
        
        int* a0 = a[0];  // the first row in the bidimensional array
        int* p0 = &p[0]; // the first element in the monodimensional array
        
        assert(*a0 == *p0 == 1); // true
        
        // Or the long version:
        assert(a[0][0] == *a0 == a0[0] == p[0] == *p0 == p0[0] == 1); // true
        
        // And for the second array in a:
        int* a1 = a[1]; // the second row in the bidimensional array
        int p2 = &p[2]; // the third element in the monodimensional array
        
        assert(a[1][0] == *a1 == a1[0] == p[2] == *p2 == p2[0] == 3); // true
        

        数组aa[0] 基本上指向同一个地址,但它们的类型传达了有关如何操作它们的信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-17
          • 1970-01-01
          • 2017-06-11
          • 1970-01-01
          相关资源
          最近更新 更多