指针具有二维数组

请考虑以下代码

#include  #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中,多维数组只是一个数组数组。 在许多上下文中,使用数组的名称“衰减”为指向该数组的第一个元素的指针。 这就是两个打印语句中发生的情况。 在第一种情况下:

 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

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

数组和指针

一维数组

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

二维数组

  • 考虑一个包含两个1D数组的数组,每个数组都有两个元素; a[2][2]
  • 由于维度的数量增加,我们有一个更高级别的层次结构,即&aa*a将指向相同的位置,但它们指向相同的类型。
  • &a将指向整个数组int[][] 。 指针类型是int(*)[][]
  • a ,当它衰减到指针时,将指向2D数组的第一个元素,即int[] 。 指针类型是int(*)[]
  • 通过使用*a ,我们将指向一维数组的指针取消引用。 因此,我们将有一个int *指向2D数组的第一个整数值。

我认为输出的格式化会让你失望。 你是对的,第一个数组元素的地址(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 

就1D与2Darrays而言,这只是一个解释问题。 都

 int x[4]; 

 int x[2][2]; 

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

二维数组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]基本上指向相同的地址,但它们的类型传达了关于如何操作它们的信息。