现在,我正在读APUE.and我发现中定义的功能如下:如何理解这个定义
void (*signal(int signo, void (*func)(int)))(int);
我很困惑,我知道信号是指向函数的指针和最后一个(INT)是他的参数。 我不知道什么是(int signo,void(* func)(int))。
现在,我正在读APUE.and我发现中定义的功能如下:如何理解这个定义
void (*signal(int signo, void (*func)(int)))(int);
我很困惑,我知道信号是指向函数的指针和最后一个(INT)是他的参数。 我不知道什么是(int signo,void(* func)(int))。
的一般程序:找到最左边的标识符并按照你的方式工作。如果没有使用圆括号的明确分组,后缀运算符(如()
和[]
)在诸如*
之类的一元运算符之前绑定;因此,下面都是真:
T *x[N] -- x is an N-element array of pointer to T
T (*x)[N] -- x is a pointer to an N-element array of T
T *f() -- f is a function returning a pointer to T
T (*f)() -- f is a pointer to a function returning T
应用这些规则的声明后,它打破了作为
signal -- signal
signal( ) -- is a function
signal( signo, ) -- with a parameter named signo
signal(int signo, ) -- of type int
signal(int signo, func ) -- and a parameter named func
signal(int signo, *func ) -- of type pointer
signal(int signo, (*func)( )) -- to a function
signal(int signo, (*func)(int)) -- taking an int parameter
signal(int signo, void (*func)(int)) -- and returning void
*signal(int signo, void (*func)(int)) -- returning a pointer
(*signal(int signo, void (*func)(int)))( ) -- to a function
(*signal(int signo, void (*func)(int)))(int) -- taking an int parameter
void (*signal(int signo, void (*func)(int)))(int); -- and returning void
总之,signal
返回一个指向返回void
功能。 signal
需要两个参数:一个整数和指向另一个函数的指针,返回void
。
你可以使用typedefs使它更易于阅读(而Ubuntu的linux上的signal
的手册页就是这么做的);不过,我认为展示非typedef'd版本来演示语法的工作方式是很有价值的。 typedef工具非常棒,但您真的需要了解底层类型如何工作才能有效地使用它。
signal
函数设置了一个信号处理程序;第二个参数是在接收到信号时要执行的功能。返回指向当前信号处理程序(如果有的话)的指针。
例如,如果你希望你的程序来处理中断信号(如按Ctrl-C):
static int g_interruptFlag = 0;
void interruptHandler(int sig)
{
g_interruptFlag = 1;
}
int main(void)
{
...
/**
* Install the interrupt handler, saving the previous interrupt handler
*/
void (*oldInterruptHandler)(int) = signal(SIGINT, interruptHandler);
while (!g_interruptFlag)
{
// do something interesting until someone hits Ctrl-C
}
/**
* Restore the previous interrupt handler (not necessary for this particular
* example, but there may be cases where you want to swap out signal handlers
* after handling a specific condition)
*/
signal(SIGINT, oldInterruptHandler);
return 0;
}
编辑我延长了示例代码signal
的东西,就是希望更多的说明。
+1获得精彩的答案! – Shrayas 2012-10-12 06:51:20
void (*signal(int signo, void (*func)(int)))(int);
signal是一个函数,它接受int和一个指向函数的指针,取int和返回void并返回一个带int和返回void的函数指针。也就是说,
typedef void(*funcPtr)(int)
那么我们有
funcPtr signal(int signo, funcPtr func); //equivalent to the above
语法的确是怪了,这样的事情最好是用一个typedef来完成。举个例子,如果你要声明一个函数,它接受一个int并返回一个指向函数取char和双回将
double (*f(int))(char);
编辑:评论,上面写着“Wooooooow”后,我我提供了另一个更“例外”的例子:)
让我们声明一个函数,其中需要
1.一个指向数组指针的数组,指向每个函数,每个函数使用float和返回double。
2.一个指向数组3个指数到4个数组的指针
并返回一个指向函数的指针,该指针接受一个指向函数的指针,返回一个指向函数的指针,并返回void并返回unsigned int。
的类型定义的解决办法是这样的:
typedef double (*f1ptr) (float);
typedef f1ptr (*arr1ptr)[5];
typedef int (*arr2ptr)[4];
typedef arr2ptr (*arr3ptr)[3];
typedef void(*f2Ptr)(float);
typedef f2ptr (*f3ptr)(int);
typedef unsigned int (*f4ptr) (f3ptr);
f4ptr TheFunction(arr1ptr arg1, arr3ptr arg2);
现在,有趣的部分:) 没有类型定义,这将是:
unsigned int (*TheFunction(double (*(*)[5])(float), int(*(*)[3])[4]))(void(*(*)(int))(float))
我的天啊,我刚写的是什么? :)
Wooooooooooooow – valdo 2010-11-08 12:59:30
@valdo:看到我的编辑更坏wooooow :) – 2010-11-08 13:19:31
有趣吗?非typedef'd版本*完全*透明。 – 2010-11-08 13:38:54
顺时针螺旋规则将帮助: http://c-faq.com/decl/spiral.anderson.html
有三个简单的步骤如下:
与未知元素开始,以螺旋/顺时针方向移动; ecountering以下元素时与相应的英文语句代替它:
的...或数组的大小未定义[X]或[] =>数组X大小...
(TYPE1,TYPE2)= >功能通过Type1和Type2返回...
- =>指针(多个)为...
保存,直到所有令牌已被被覆盖在螺线/顺时针方向这样做。 总是先解决括号中的任何内容吧!
参见“示例#3:‘终极’”,这是相当多的,你问什么了:
“信号传递一个int和指针的函数传递一个int功能返回无(无效)返回一个指针的函数传递一个int返回什么(无效)”
这是一个非常漂亮的资源。谢谢 ! – Shrayas 2012-10-12 07:01:23
本网站为declerations到C乱码:
如果您没有访问cdecl
现在,这里是CDECL输出:
$ cdecl
cdecl> explain void (*signal(int , void (*)(int)))(int);
declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void
获取'cdecl'。它会告诉你所有这些事情。我会问:'void void(* signal(int,void(*)(int)))(int);'它会回答:'将信号声明为函数(int,指向函数的指针(int)返回void)函数(int)返回void' – 2010-11-08 10:57:15
尝试http://cdecl.org/ – 2010-11-08 13:09:28