请考虑以下代码
#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数组相同的地址。请解释。< / p>
答案 0 :(得分:7)
重新构建问题中的图表并合并先前答案中的信息,我正在创建以下答案。
a[4]
a
和&a
都指向同一位置。但 指向同一类型。&a
将指向整个数组int[]
。指针类型为int(*)[]
a
,当它衰减到指针时,将指向数组的第一个元素int
。指针类型为int *
a[2][2]
。&a
,a
和*a
将指向相同的位置,但不是< / strong>指向相同的类型。&a
将指向整个数组int[][]
。指针类型为int(*)[][]
。a
,当它衰减到指针时,将指向2D数组的第一个元素int[]
。指针类型为int(*)[]
*a
,我们将指向一维数组的指针。因此,我们将有int *
指向2D数组的第一个整数值。答案 1 :(得分:6)
数组不是指针,而在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 :(得分:0)
我认为输出的格式化会让你失望。你是对的,第一个数组元素(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与2D阵列而言,这只是一个解释问题。两个
int x[4];
和
int x[2][2];
创建4个“int-sized”元素的连续块。在这两种情况下,表达式“x”指的是第0个条目的地址(例如,数组的地址)。
答案 3 :(得分: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
数组a
和a[0]
基本上指向相同的地址,但它们的类型传达了有关如何操作它们的信息。