C语言拾遗(三):分析C语言声明

C语言非常难理解的是指针,可是比指针还难理解的是什么呢?我想莫非是C语言的声明了。

比如看下一个系统调用signal()的函数声明:

void (*signal(int sig, void(*func)(int))) (int);

是不是很晕乎?从哪个标识符开始读,singnal?sig?还是int?往左读还是往右读?

其实理解了C语言声明的优先级规则就好办了。

A 声明从它的名字开始读取,然后按照优先级的顺序依次读取。

B 优先级从高到低:

  B.1标识符被小括号扩起来的那部分

  B.2后缀操作符:( )表示这是一个函数,[]表示这是一个数组。

  B.3前缀操作符:星号*表示“指向...的指针”

C  如果const和(或)volatile关键字的后面紧跟类型说明符(int,long等)那么它作用于类型说明符,否则往前看,关键字作用于左边紧邻的类型符或指针星号。

好了,理论用于实践,来看一个例子。

char * const *(*next)();

首先,读到next,往左前缀是*,表示next是一个指针,再后面(),说明next指向函数,函数的返回值是指针,指针指向char*const,表示指向字符类型的常量指针(const作用于指针)。

再来看一个

char *(* c[10])(int **p)

分析:c是一个数组,数组的元素个数为10,元素是指针,这些指针指向函数,函数的参数是int **p(指向指针的指针),函数的返回类型是char *(字符指针)。

好了,再回头看singal()的声明:

void (*signal(int sig, void(*func)(int))) (int);

分析:signal是一个函数,signal函数的参数,一个是int sig,还有一个是 void(*func)(int), 表示一个函数指针,指向一个参数为int,返回void的函数

signal函数的返回也是一个函数指针,也是指向一个一个参数为int,返回void的函数。

这样就比较清楚了。像庖丁解牛一样。这时你发现了没有signal还是挺绕,不够简洁,看分析中蓝色字体,是不是几乎一样?

试试typedef吧。

typedef void (*ptr_to_func)(int);

为一个类型取了一个新名字,该类型是指向一个参数为int,返回void的函数指针。这样signal就可以这么声明了:

ptr_to_func singal(int sig, ptr_to_func func);

是不是很简洁,当然,如果不考虑可读性,还可以更简洁(不推荐啊)

typedef void (*A)(int);
A singal(int sig, A func);

Note: typedef只是给某种类型取一个新名字,并不是声明一种新的类型。

---End---

 

posted on 2013-03-24 17:15  Randy Xu  阅读(1194)  评论(4编辑  收藏  举报

导航