一.声明
1.首先需要更新一下对于声明的理解:
int *f;
我们可以将其看做两部分:一是数据类型,而是声明表达式。对声明表达式求值就会返回一个给定类型(这里为int类型)的值。
2.之后我们还要区分旧式的声明与新式的声明:以上给出的就是一个旧式的声明方式,而ANSI C要求要求我们使用完整的函数原型进行声明,使声明更为明确。即还需要给出函数的参数类型,如下例所示:
int *f(int, double);
3.如下代码,依据上文,我们要先对声明表达式进行求值,f先与()结合,说明它是一个函数,之后与*结合。函数与寻址操作符结合就是对函数进行寻址操作,即对函数的返回值进行寻址操作。
int *f();
4.如果a的属性为external或者作为函数参数,那么即使在声明时未注明长度,也任然是合法的。
int a[];
5.(*f)()为函数指针,就像上文提到的*与函数结合表示对函数的返回值进行寻址操作后会得到一个int类型的值。
int *(*f)();
6.f是一个函数,它返回的是一个整型数组。但是这个声明是非法的,函数只能返回标量值,不能返回数组。
int f()[]
7.f似乎是一个数组,它的类型是返回值为整型的函数。这个声明也是非法的,因为数组元素必须具有相同的长度,而函数显然可能具有不同的长度。
int f[]();
8. 首地址为0的函数
- (void(*)()) 对void(*)()添加括号即为类型转换符,将0转换为此类型函数的指针。
- *(void(*)()) 对函数寻址,即得到函数名(当然编译器在调用时函数转换为指针)。
- (*(void(*)())) 调用函数。
( *(void(*)())0 )();
9. 1.*f[]指针数组。 2.(*f[])() 数组中的指针指向的是函数类型 3.与*结合即对函数寻址后得到的是int类型的数据。即:所以这个声明创建了一个指针数组,指针所指向的类型是返回值为int类型的指针。
int *(*f[])();
二.类型转换符
根据一个已有的声明,只需要两步就可以得到类型转换符:
- 将 变量名 和 声明末尾的分号去掉。
- 再将剩余的部分用一个括号封装起来。
以下为声明:
float (*h)();
以下就是此类型的类型转换符:
(float (*)())
三.函数指针
- 初始化函数指针时,对函数名&的操作是可选的。因为函数名被使用时总是由编译器转换为函数指针,&操作符只是显示地说明了编译器将隐式完成的任务。
- int ( *(*f()) )[10];
- int ( * ( (*x) [10] ) )();