函数指针
除了变量以外,函数也有自己的地址。既然函数有地址,也就会有指针。例如:
void ThatsAFunction() {}
int main() {
("%p\n", &main);
printf("%p\n", &ThatsAFunction);
printfreturn 0;
}
不出意外会得到两个函数的内存地址:
0x40112d
0x401126
函数指针也有自己的类型,比如对如上函数的指针类型为:
void (*func) = &ThatsAFunction;
对于有参数的函数则直接加上对应参数即可:
void (*func)(int param, int len) = &AnotherFunc;
可以得出,任何一个变量的指针类型就是加上一个指针变量的名字,就像
int
-> *int
一样。
既然函数指针也是个指针,我们也可以按指针的方式使用它:
AnotherFunc(1, 2); 等效于:
func(1, 2);
(*func)(1, 2);
(*AnotherFunc)(1, 2); // 会提示 redundant
看上去和数组有些相似,我们也可以将函数名当成指针使用。
在对复杂函数使用函数指针显然非常麻烦,所以就要用到 C 语言中的一个特性:
typedef
typedef 用于给一个类型起一个别名,将长串的类型转为自定义的简短字符。
比如标准库中的 wchar_t
,就是使用了 typedef
起的别名,实际类型为 unsigned short
。
对于一个函数,我们可以像这样使用别名:
typedef int (*Func)(int, double);
int Add(int left, double ano);
= &Add; // 等效于 (*func)(int, double) Func func1
C 语言直到 C99 之前都没有直接的布尔值类型使用,因此我们可以利用 typedef 声明一个布尔值,便于分辨:
typedef int Boolean;
对于数组也有:
typedef int IntArr[];
= {1,3,4,5}; IntArr arr
当然,我们已经指定了
[]
,因此再尝试给出数组大小是会报错的。因此重定义数组一般不被推荐。