朝花夕拾-C语言指针定义和数组定义的歧义问题-指针和数组疑难辩证-终极解答1
=
=
=
选择题(提示:答案只有一个):
int *p = 100;
到底是下面哪个呢?
答案A: (int *) p
答案B: int (*p)
答案是B。
一定要分清楚指针定义和变量类型的关系。
指针定义的方式是在普通定义方法的变量名前加*。
普通定义的方式为:int i;
指针定义的方式为:在变量名前加*,例如:int *p;
变量类型是指一个变量的类型,比如上面的i的变量类型是:int。p的变量类型是:(int *)。
可以看出这里最不适应的是一个变量类型居然有两个符号(甚至更多)表示,这种特点是需要适应的,尤其是从java等高级语言过来的。
下面到底哪个是数组指针,哪个是指针数组呢:
A)
int *p1[10];
B)
int (*p2)[10];
这个问题迷惑的关键点在于c语言设计之初的迭代改进,或者回望迭代之初设计者没有设计好。
数组类型的定义,本来就应该参考高级语言的方式,使用这种方式定义:int[] a; 或者 int[10] a;
//这种方式的好处是显示了真实情况,变量是a,明显是指针性质的。变量类型是int[],int[10]。
但是教科书都用这种方式定义:int a[10];
//这种方式太糟糕,掩盖了变量的本质和类型。初学者还以为变量类型是int,只不过是个数组而已。
小结:
[]或者[10]本来应该跟类型放在一起,而不是跟变量参合在一起。
等价于[]或则[10]应该提前到变量前面。
int a[10] 应该换成 int[10] a;
int *p[10]应该换成什么?应该换成int *[10] p;本来应该换成这样的。
好了,返回来解决上面的问题。
1 借鉴一下数学概念,变量替换。
2 符号之间的优先级:()
> []
> *
。
A)
int *p1[10];
解放方法1:
因为[]优先级比*高,所以上面的题目改为:int *(p1[10])
变量替换:int *X;//这个定义我们太熟悉了,定义了一个变量X,X是个指针类型,也就是int *类型。
那么X==p1[10]是个数组,意思是数组的每个元素都是指针了。
解决方法2:
移动[],int *p1[10]应该换成什么?应该换成int *[10] p1;本来应该换成这样的。
p1的类型是什么:int *[10]
B)
int (*p2)[10];
这个问题怎么解决?
解放方法:变量替换+移动括号。
int (*p2)[10]; 等价于 int X[10] 等价于 int[10] X 等价于int[10] (*p2)
int[10] (*p2)是什么意思?一个int[10]数组,p2是个指针,指向这个数组。
p2的类型是什么?int[10] *
小结:
C语言在设计之初没有设计好,导致后期迭代改进后,没有彻底修改编译器和形式逻辑。
导致了一些问题。
本来应该用int[10] a; 可是用成了int[10] a;
本来应该用 (int *) p; 可是用成了int (*p);
也可能不对,多多提意见。
为了看看最近的编译器,是不是可以按照我理解的最好方式进行识别和编译,试了试,不行啊。
#include <stdio.h> int main(void){ int (*p); int i = 10; p = &i; printf("p=%d \n", *p); }
如果改成 (int *) p就会报错:
$ gcc prac_point.c
prac_point.c: In function ‘main’:
prac_point.c:4: error: ‘p’ undeclared (first use in this function)
prac_point.c:4: error: (Each undeclared identifier is reported only once
prac_point.c:4: error: for each function it appears in.)
=
=
=