C 语言学习笔记 10 - typedef

函数指针

除了变量以外,函数也有自己的地址。既然函数有地址,也就会有指针。例如:

void ThatsAFunction() {}

int main() {
    printf("%p\n", &main);
    printf("%p\n", &ThatsAFunction);
    return 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);

Func func1 = &Add; // 等效于 (*func)(int, double)

C 语言直到 C99 之前都没有直接的布尔值类型使用,因此我们可以利用 typedef 声明一个布尔值,便于分辨:

typedef int Boolean;

对于数组也有:

typedef int IntArr[];

IntArr arr = {1,3,4,5};

当然,我们已经指定了 [],因此再尝试给出数组大小是会报错的。因此重定义数组一般不被推荐。

comments powered by Disqus