C语言能否用二维数组的形式访问一维数组

新手上路,请多包涵
char p1[12] = {1,2,3,4,5,6};

char (*p2)[3];

p2 = &p1;

这样可以实现,但是gcc编译时有警告:

warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]

阅读 3.5k
1 个回答

以下只是个人理解,如有谬误,谢谢指出。

首先要明确的概念是:
虽然所有指针的大小都是固定的(如 32 位环境下就是 4 个字节),但指针本身是有类型的,或者说,每个指针都只能指向某种特定类型的对象(void *除外),如 int * 指针就只能指向 int 类型数据。

然后是数组的类型:
我们先声明一个数组int a[10];方便说明,
虽然数组名在很多情况下都会被隐式转换成指向数组首元素的指针,给人一种a == &a[0]的错觉,但数组确实是一种单独的类型,举两种情况就能体会到了——&asizeof(a)
&a 是指向整个数组对象的指针,当我们试图这样写的时候int *p = &a;,编译是通不过的,必须写成int(*p)[10] = &a;,即一个简单的 int 指针是无法接收 &a 的结果的。
当我们打印出sizeof(a)的结果,可以看到是 40 字节而不是 4 字节,显然数组名和指针是两码事了。
理解了数组是一种特殊的类型,我们就能知道,刚上面声明的 a 其实是长度为 10 的 int 数组类型,即int (*)[10]类型,注意这里的 10 不能忽略,长度是数组类型的一部分。

回到问题,
p2 是一个指针,因为它指向的是一个长度为 3 的 char 数组,所以其类型是:char (*)[3]
而 p1 是一个长度为 12 的 char 数组,所以&p1的类型是:char (*)[12]
现在要把&p1赋给 p2,虽然两者都属于指针,即大小是一致的,但类型不一样,所以编译器会报错,
真想这么转,需要做个强制转换:
p2 = (char(*)[3])&p1;

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进