问答题 如何建立和理解非常复杂的声明
【正确答案】
【答案解析】1)一个整型数。
2)一个指向整型数的指针。
3)一个指向指针的指针,它指向的指针是指向一个整型数。
4)一个有10个整型数的数组。
5)一个有10个指针的数组,该指针指向一个整型数。
6)一个指向有10个整型数数组的指针。
7)一个指向函数的指针,该函数有一个整型参数并返回一个整型数。
8)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数。
对于上述问题,可以有如下解答:
1)int a;
2)int *a;
3)int **a;
4)int a[10];
5)int *a[10];
6)int(*a)[10];
7)int(*a)(int);
8)int(*a[10])(int);
为了更好地说明上述问题,以如下两个声明为例:
1)int(*a[])(int);
2)int(*p())[10];
第1)种情况为数组里面是函数指针的情况,因为(int(*)(int]))是一个强制转换方式,将里面的a[]这个数组转换成了一个函数指针的数组,并且该函数是一个带一个整型变量,并且返回一个整型的函数。而第2)种情况是指函数返回的为指向一个一维数组的指针的情况,因为(int(*)[10])将其强制转换成了一个指针,而该指针则是一个指向一维数组的指针。
其实,在C语言中,每个变量声明都由两个部分组成:一个类型和一组具有特定格式的,期望用来对该类型求值的表达式。例如,float *g(),(*h)(),该语句表示*g()和(*h)()都是float表达式。由于()比*优先级更高,绑定得更紧密,所以*g()与*(g())表示的意义相同,即g是一个返回float指针的函数,而h是一个指向返回。float的函数的指针。
对于float *g()声明,它表示g是一个返回float指针的函数,所有(float *())就是它的模型。
除了上述提及的一些函数声明方式以外,还有一些声明方式非常复杂,如(*(void(*)())0)(),该声明表示硬件会调用地址为0处的子程序,但如果写成是(*0)()并不符合要求,因为*运算符要求必须有一个指针作为它的操作数,而不能是数字。而且,这个操作数必须是一个指向函数的指针,以保证*的结果可以被调用,所以此时需要将0转换为一个可以描述“指向一个返回void的函数的指针”的类型,即(void(*)())0。