- typedef是C语言用来为一个声明起别名的关键字。
- typedef的难点就在于为函数起别名,这篇文章着重讲解typedef如何为复杂函数声明起别名以及它与#define最显著的区别。
复杂函数声明
下面通过几个案例看懂一些常用的复杂函数声明。
1. void (* f[10]) (void (*)());
- 首先,明确一点,第一个括号这个整体可以理解为函数名(函数所在的地址)。
- 其次,由于 [] 的优先级高于 * 的优先级,所以第一个括号里表明 f 数组的第11个元素中存放指向这个函数地址的指针。
- 再看第二个括号,第二个括号里的是函数的参数,很明显这个 f 函数的参数是一个函数指针。
2. doube (*)() (*f)[9];
- 同样,第一个括号是函数指针,第二个括号是函数的参数,这两个括号与double一起构成一个完整的(无参数,返回值是double型)函数声明。
- 后面的 (*f)[9] 很明显是个函数数组,所以这个函数声明其实是一个函数数组的声明,第一个函数成为第二个函数数组中各个元素(无参数,括号省略)的返回值类型。
- 其实把 doube (*)() 看作是 f1 函数,那么 (*f)[9]就是由函数 f2() 构成的9个数组。整体看来就是 “f1 f2()[9]” 。
复杂函数声明的别名
1. void (* f[10]) (void (*)());
- 明确,我们起别名是对一个类型起别名,指向函数地址的指针其实可以是看作一个类型。
- 基于上面一点和之前我们对这个函数声明的讲解,可以写如下代码:
typdef void (*function1)(function2);
2. doube (*)() (*f)[9];
先给左边的函数起别名
typdef double(*function1)();
替换后变成function1 (*f)[9],再给右边的起别名
typdef function1 (*function2)[9];
define与typedef
一个很简单的例子就能分清楚了
typedef char* pStr1; //pStr1成为了一个指针类型
#define pStr2 char*
pStr1 s1, s2; //相当于char *s3, *s4;
pStr2 s3, s4; //相当于char *s3, s4;
总结
- typedef语句只能用来定义类型名,而不能用来定义变量。而typedef是给指向函数函数地址的指针起别名。
- 函数声明从左往右的第一个括号基本代表这个函数的地址。
- define只是简单的字符串替换。