C 将两个二维指针等价于二维数组
我正在尝试以下代码C 将两个二维指针等价于二维数组,c,pointers,C,Pointers,我正在尝试以下代码 #include<stdio.h> int main() { int A[3][4] = {{1,2,3,4},{5,6,7,8,},{9,10,11,12}}; int **t = &A[0]; //I do this or **t = A,I guess both are equivalent printf("%d %p\n\n",*t,A[0]); return 0; } #包括 int main() {
#include<stdio.h>
int main()
{
int A[3][4] = {{1,2,3,4},{5,6,7,8,},{9,10,11,12}};
int **t = &A[0]; //I do this or **t = A,I guess both are equivalent
printf("%d %p\n\n",*t,A[0]);
return 0;
}
#包括
int main()
{
int A[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12};
int**t=&A[0];//我这样做或**t=A,我想两者是等价的
printf(“%d%p\n\n”,*t,A[0]);
返回0;
}
我所期望的是:
现在t是一个2d指针(指向指针的指针),它持有[0]的地址,而[0]又持有[0][0]的地址。所以*t应该给我A[0]的值,也就是A[0][0]的地址,**t应该给我A[0][0]的值,在本例中是1
我得到的是:
*t给出了1的值。试图找到**t是不可能的,因为它导致了分段错误
谁能告诉我为什么会这样
我尝试了下面的解释,但不确定它是否是“正确”的解释。
t保存[0]的地址,但由于A是数组,A[0]是数组指针(它“不完全”是指针),C不会为指针A或A[0]分配内存,这与其他指针变量不同。它只为整个阵列分配内存。因此A[0]和A[0](即A[0][0]的地址)的地址本质上是相同的,都属于同一屋檐下,不像是“单独的”实体。结果,t又间接地持有a[0][0]的地址,*t给出a[0][0]的值,即1
上面的解释正确吗?看起来有点奇怪。数组不是指针。
嗯,甚至更多
多维数组不是双指针、三指针等。
因此,您所拥有的只是错误,您的程序多次调用未定义的行为,,而没有任何您可以期待的。
假设数组在内存中是连续的,您可以这样重写示例:
int A[3][4] = {{1,2,3,4},{5,6,7,8,},{9,10,11,12}};
int *p = &A[0][0];
printf("%d %d %p\n", A[0][0], *p, (void *)p);
我尝试了下面的解释,但不确定它是否是“正确”的解释
不完全是,但有点接近
t
保存A[0]
的地址,但由于A
是一个数组,A[0]
是一个数组指针
A[0]
是一个数组,具体来说,它的类型是int[4]
(它“不完全”是指针),C不为指针a
或a[0]
分配内存,特别是与其他指针变量不同
数组和指针是本质上不同的实体类型。别把他们弄糊涂了
在大多数情况下,T数组类型的表达式被转换为指向T的指针类型的值(指向数组的第一个元素)这一事实肯定会造成混淆,但我们不能忘记这是一种转换。特别是,对于高维数组或数组的数组,数组的元素类型本身就是数组类型,因此转换的结果是指向数组的指针
它只为整个阵列分配内存。因此A[0]
和A[0]
(即A[0][0]
的地址)的地址基本相同
不,它们本质上是不同的,一个-A[0]
-是数组,int[4]
,另一个-&A[0]
-是指向四个int
,int(*)数组的指针。两者都不是&A[0][0]
但是当A[0]
转换为指向其第一个元素&A[0][0]
的指针时,生成的地址通常与A[0]
的地址相同(通常,指向对象的指针包含属于该对象的地址最低的字节的地址,并且由于A[0]
属于(是其一部分)对象A
,地址最低的对象,是A[0]
的第一个字节,是A
的第一个字节
所以&A[0]
和&A[0][0]
通常有相同的表示,但一个是int(*)[4]
,另一个是int*
两者都属于同一屋檐下,不像“独立”的实体。因此,t
依次间接持有a[0][0]
的地址,*t
给出a[0][0]
的值,即1
除了导致取消引用t
未定义行为的类型不匹配之外,该部分或多或少是正确的。从形式上讲,未定义的行为允许任何事情发生
在实践中,如果sizeof(int)==sizeof(int*)
,则取消引用t
会将int
1(即A[0][0]
解释为地址,如果将其打印为int
(另一个未定义的行为),则会打印出1
。如果sizeof(int*)==2*sizeof(int)
,这在64位系统上很常见,那么对t
的解引用通常会将两个int
sA[0][0]
和A[0][1]
一起解释为一个地址-0x20000001
或0x10000002
,这可能取决于端度。数组不是指针。int**
假设的内存布局不同于int[x][y]
的内存布局。你的编译器听到这段代码时不是在痛苦地尖叫吗?@KerrekSB我肯定会的,就像内核的内存管理器模块一样。