这里我有一个2D数组。我想声明一个指向数组第一行的指针。首先,我做了类似的事情
#include <stdio.h>
int main ()
{
int arr[2][2]={{6,2},{3,4}};
int *ptr=arr;
printf("%d",*(ptr+0));
}
2D阵列的第一行也是一个数组。一维数组的类似类型的指针声明不会发出任何警告。为什么我在编译期间收到警告。
[警告]从不兼容的指针类型初始化[启用 默认]
以下没有发出任何警告
int main ()
{
int arr[2][2]={{6,2},{3,4}};
int (*ptr)[2]=arr;
printf("%d",*(ptr+0));
}
答案 0 :(得分:2)
除非它是sizeof
或一元&
运算符的操作数,否则表达式类型为“N
- 元素数组{{1} “将被转换(”衰减“)到”指向T
的指针“类型的表达式,表达式的值将是数组的第一个元素的地址。
在第
行T
表达式 int *ptr=arr;
的类型为“{element}的2元素数组的2元素数组”(IOW,arr
是“2元素数组” int
“)。由于表达式T
不是int
或一元arr
运算符的操作数,因此它被转换(“衰减”)到类型为“指向2元素数组的指针”的表达式sizeof
“或&
,表达式的值是数组第一个元素的地址。
这就是为什么你得到了上面一行的警告,而不是
int
因为在这种情况下类型匹配正确。
鉴于声明
int (*)[2]
以下都是真的:
int (*ptr)[2]=arr;
所以int arr[2][2]={{6,2},{3,4}};
,Expression Type Decays To Equivalent Value
---------- ---- --------- ----------------
arr int [2][2] int (*)[2] &arr[0][0]
&arr int (*)[2][2] &arr[0][0]
*arr int [2] int * &arr[0][0]
arr[i] int [2] int * &arr[i][0]
&arr[i] int (*)[2] &arr[i][0]
*arr[i] int arr[i][0]
arr[i][j] int
&arr[i][j] int *
,arr
,&arr
和arr[0]
都评估为相同的值(地址)数组的第一个元素与数组本身的地址相同,但类型都是不同的。
我想要了解的一个非常重要的一点(特别是因为它出现在其他几个答案中)是数组对象不存储任何指针值。如果您查看内存中&arr[0]
的内容,您会看到以下内容:
&arr[0][0]
任何指针都没有存储空间。编译代码时,任何引用数组的表达式都会被替换,并带有指向数组第一个元素的指针。
答案 1 :(得分:1)
arr
是整数数组的数组,而ptr
是指向整数的指针。在数组数组中,您需要两个间接级别来达到整数(arr[0][0]
),而在指针中只需要一个(ptr[0]
)。您可以将某个类型的元素数组分配给指向同一类型元素的指针,但如果类型不同则不会,这是这种情况。
正如您所看到的,它们是两个不同的东西,因此编译器可以很好地对您的分配抱怨。
答案 2 :(得分:-2)
2D数组包含(如arrurri所提到的)一个指向指针数组的指针,每个指针都指向实际的元素。所以,arr是一个指向指针的指针,它的每个索引值(arr [i])是一个指向行的指针。
那么,你需要做的是ptr = arr [0];代替。