在《C陷阱与缺陷》这本书的第2.1节“理解函数声明”中,作者通过对函数声明的一步步分析、引导、深入,最后得到一个signal函数:
但是,当我第一次看到的时候也觉得没法理解,看过好多遍之后还是没法理解。这几天看《C++Primer》,突然明白了,所以就赶紧记录下来。
我记得以前我在CSDN论坛上提过一个问题:请问signal函数如何调用?其实,如果理解了signal函数的定义,又怎能问这样肤浅的问题?
下来我来分析一下signal函数
signal函数
参数:1)int。
2)一个返回值为void,带一个int参数的函数指针。
返回值:
一个返回值为void,带一个int参数的函数指针。
下来我们从函数指针的声明来剖析: void (*(signal)(int,void(*)(int)))(int)
1)既然这是一个函数声明,那么就先从最里层函数名signal来看。void (*(signal)(int,void(*)(int)))(int)
可以看出:signal带int和void(*)(int)两个参数 void (*(signal)(int,void(*)(int)))(int)
2)如果能理解第一步,那么第二步就很好理解了。
你看以这样看这个声明 void (*(signal)(int,void(*)(int)))(int)
将绿色的部分看成一个整体就变成了 void (*p)(int)
p带了一个*,那么p的返回值肯定是指针了,是什么类型的指针呢?看看指针形式, void (*)(int) 为其类型!!!
(以上所有如果还有疑问,请继续看《C陷阱与缺陷》此节)
所以,就成了 void (*(signal)(int,void(*)(int)))(int)
你看,如果用typedef的话就很明了了,对吧!
如何调用?简单!
我做了两个小例子
#if 0
#include <stdio.h>
/*
typedef void (*HANDLER)(int);
HANDLER signal(int,HANDLER);
*/
void (*mysignal(int a,void(*p)(int)))(int)
{
printf("x = %d\n",a);
p(a);
return p;
}
void fun(int x)
{
printf("y = %d\n",x);
}
int main(void)
{
mysignal(1,fun);
}
#endif
#include <stdio.h>
int (*myfun(int (p)(int x,int y),int x,int y))(int x,int y)
{
printf("x = %d\n",x);
printf("y = %d\n",y);
printf("x + y = %d\n",p(x,y));
return p;
}
int add(int x,int y)
{
return x + y;
}
int main(void)
{
printf("myfun的返回值 = 0x%x\n",myfun(add,4,7));
printf("add函数的地址 = 0x%x\n",add);
}
如果能用typedef,必须要用!不然代码很晦涩,增加维护成本!!!