关于c和c++的类型(4)
这里仅讨论数组和函数相关的复杂类型的简化。
一、用typedef简化复杂类型声明
嵌在对象定义中的隐式类型不容易认读,因此我们可以用typedef
来简化类型声明。
typedef在定义类型而不是对象!
1) 简化数组类型
typedef int arr_t[10];
解读步骤如下:
-
找到
typedef
中的新名字。这里的新名字是
arr_t
。这是一种新的类型名。 -
找到
arr_t
附近的修饰符。arr_t
左侧没有修饰符,右侧有[]
。这样,arr_t
就是一个数组类型。 -
去掉名字。
剩下的是:
int [10]这就是新类型
arr_t
的代表的已有类型。很明显,这是一种数组类型。 -
得出结论
综上,类型
arr_t
就是一个数组类型;这种类型的数组具有这样的特征:- 是一维的
- 长度为10。
- 基类型为
int
。
-
应用
arr_t a; //等价于:int a[10];
2) 简化函数类型
typedef int fn_t(int);
解读步骤如下:
-
找到
typedef
中的新名字。这里的新名字是
fn_t
。这是一种新的类型名。 -
找到
fn_t
附近的修饰符。fn_t
左侧没有修饰符,右侧有()
。这样,fn_t
就是一个函数类型。 -
去掉名字。
剩下的是:
int (int)这就是函数类型
fn_t
的代表的已有类型。很明显,这是一种函数类型。 -
得出结论
综上,类型
fn_t
就是一个函数类型;这种类型的函数签名具有这样的特征:- 带有一个参数,这个参数的类型是
int
。 - 函数返回值类型为
int
。
- 带有一个参数,这个参数的类型是
-
应用
C/C++规定,不能定义函数类型的对象。函数类型只能作为函数的参数类型。
int f(int x, fn_t fn); //参数fn的类型是函数
3) 简化函数指针类型
typedef int (*pf_t)(int);
解读步骤如下:
-
找到
typedef
中的新名字。这里的新名字是
pf_t
。这是一种新的类型名。 -
找到
pf_t
附近的修饰符。pf_t
左侧有修饰符*
,并且和pf_t
一起括在()
中。这对()
提升了*
的优先级,因此*
先和pf_t
结合。这样,无论如何,pf_t
就是一个指针类型。 - 去掉名字及其就近的修饰符。
剩下的是:
int (int)
这就是指针类型
pf_t
的基类型。很明显,这是一种函数类型。 -
得出结论
综上,类型
pf_t
就是一个指向函数的指针类型;这种类型的指针指向的函数签名具有这样的特征:- 带有一个参数,这个参数的类型是
int
。 - 函数返回值类型为
int
。
- 带有一个参数,这个参数的类型是
-
应用
可以定义函数指针类型的对象。
int g(int x) {...} pf_t pf; pf = g; pf(2);
函数指针类型也常作为函数的参数类型。
int f(int x, pf_t fn); //参数fn的类型是函数指针类型,fn是指向函数的指针
4) 函数类型参数和函数指针类型参数是等效的
以下两个函数的签名是等效的:
int f(int x, fn_t fn); //fn是函数
int f(int x, pf_t fn); //fn是函数指针
二、C++的using语句
C++的using
语句可以替代typedef
语句,并且可读性更强。例如:
using arr_t = int [10];
using fn_t = int (int);
using pf_t = int (*)(int);
三、更复杂的案例
如果有定义:
int (*a(int))(int);
那么名字a是什么呢?
解读步骤:
-
找到
a
附近的修饰符。前后有
*
和()
。由于()
的优先级更高,因此a
首先和()
结合。因此,a
一定是个函数。很明显,这个函数带有一个整型参数。 -
去掉
a(int)
,剩下的是int (*)(int)
。这是函数
a
的返回值类型。很明显,这是一种指向函数的指针类型。 -
总结
综上,函数
a
的特征是:- 带有一个整型参数
- 返回函数指针
-
使用
a(1)(2); //用参数1调用a(),返回函数指针;再调用函数指针指向的函数,参数为2
-
简化
显然,函数
a
的类型非常复杂,不好认读。因此最好简化。typedef int (*pf_t)(int); //C //using pf_t = int (*)(int); //C++ pf_t a(int);
以下是完整的示例程序。
#include <stdio.h> int f(int x) { printf("f: %d\n", x); } int (*a(int i))(int) { printf("a: %d\n", i); return f; } int main() { a(1)(2); return 0; }
结果是:
a: 1 f: 2