#include<stdio.h>
int main(int argc , char *argv[])
{
int array[2][2] = {{1,100},{1000,10000}};
int *pointer = array;
int *ppointer = &array;
int *pppointer = array[0];
int *ppppointer = &array[0];
printf("%d\n",*pointer);
printf("%d\n",*ppointer);
printf("%d\n",*pppointer);
printf("%d\n",*ppppointer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
四个指针指向数组的第一个元素.上面显示的哪个定义更好?我不知道为什么数组和数组的值相同?
所有定义编译的唯一原因是你的C编译器在指针类型转换方面过于允许.如果你使用一些在这方面使它更迂腐的开关,它应该立即告诉你只有第三次初始化是有效的,而其余的是错误的.
在大多数情况下(少数例外),当T[N]在表达式中使用类型数组时,它会"衰减"(被隐式转换)为指针类型T *- 指向其第一个元素的指针.换句话说,在任何数组的上下文中A,A表达式相当于&A[0].数组类型衰减不发生的唯一上下文是一元运算&符,sizeof运算符和字符串文字,用作char数组的初始值设定项.
在您的示例中array是int [2][2]type 的值.当在初始化的右侧使用时,它会衰减到指针类型int (*)[2].因此,这是无效的
int *pointer = array;
Run Code Online (Sandbox Code Playgroud)
右边是int (*)[2],而左边是int *.这些是不同的指针类型.你不能用另一个初始化一个.
该
int *ppppointer = &array[0];
Run Code Online (Sandbox Code Playgroud)
完全等同于前一个:右侧产生int (*)[2]类型的值.由于同样的原因,它是无效的.
该&array表达式生成一个int (*)[2][2]类型的指针.再次,出于这个原因
int *ppointer = &array;
Run Code Online (Sandbox Code Playgroud)
是无效的.
您的示例中唯一有效的初始化是
int *pppointer = array[0];
Run Code Online (Sandbox Code Playgroud)
array[0]是一个int [2]类型的表达式,它衰减为int *类型 - 与左侧相同的类型.
换句话说,这里没有哪个"更好".只有一个初始化有效,其他初始化是非法的.有效的初始化也可以写成
int *pppointer = &array[0][0];
Run Code Online (Sandbox Code Playgroud)
由于我上面描述的原因.现在,哪个右侧"更好"(array[0]或&array[0][0])是您个人喜好的问题.
为了使您的其他初始化有效,指针应声明如下
int (*pointer)[2] = array;
int (*ppointer)[2][2] = &array;
int (*ppppointer)[2] = &array[0];
Run Code Online (Sandbox Code Playgroud)
但是这样的指针将具有与指针不同的语义int *.你显然需要int *特别的.