Sim*_*Sun 12 c linux syntax function-declaration
如今,我正在阅读APUE.我发现函数定义如下:
void (*signal(int signo, void (*func)(int)))(int);
Run Code Online (Sandbox Code Playgroud)
我很困惑,我知道signal是指向函数的指针,而last(int)是他的参数.我不知道是什么(int signo,void(*func)(int)).
Joh*_*ode 24
一般程序:找到最左边的标识符并解决问题.没有带括号的显式分组,后缀运算符如()和[]一元运算符之前绑定*; 因此,以下都是真的:
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
Run Code Online (Sandbox Code Playgroud)
将这些规则应用于声明,它将其分解为
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
Run Code Online (Sandbox Code Playgroud)
简而言之,signal返回一个返回函数的指针void. signal有两个参数:一个整数和一个返回另一个函数的指针void.
您可以使用typedef使这更容易阅读(并且signalUbuntu linux上的手册页就是这样); 但是,我认为显示非typedef类型以证明语法的工作原理是很有价值的.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;
}
Run Code Online (Sandbox Code Playgroud)
编辑我将示例代码扩展为signal希望更具说明性的内容.
Arm*_*yan 16
void (*signal(int signo, void (*func)(int)))(int);
Run Code Online (Sandbox Code Playgroud)
signal是一个函数,它接受int和一个函数获取int并返回void的函数,并返回一个带int的函数指针并返回void.那是,
typedef void(*funcPtr)(int)
Run Code Online (Sandbox Code Playgroud)
然后我们有
funcPtr signal(int signo, funcPtr func); //equivalent to the above
Run Code Online (Sandbox Code Playgroud)
语法确实很奇怪,使用typedef可以做得更好.作为一个例子,如果你想声明一个带有int的函数并返回一个指向函数的指针,它接受char并返回double将是
double (*f(int))(char);
Run Code Online (Sandbox Code Playgroud)
编辑:在评论"Wooooooow"之后,我提供了另一个更"woooow"的例子:)
让我们声明一个函数,它
带有一个指向5个指向数组的数组的指针,每个函数都接受float并返回double.
2.指向3个ponter到4个int数组的数组的
指针,并返回一个指向函数的指针,该函数接受一个指向函数的指针,该函数接受int并返回指向函数的指针,该指针指向float并返回void并返回unsigned int.
typedef解决方案是这样的:
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);
Run Code Online (Sandbox Code Playgroud)
现在,有趣的部分:) 没有typedef这将是:
unsigned int (*TheFunction( double (*(*)[5])(float), int(*(*)[3])[4]))( void(*(*)(int))(float))
Run Code Online (Sandbox Code Playgroud)
我的上帝,我刚刚写了吗?:)
Pau*_*her 12
顺时针螺旋规则将有所帮助:http: //c-faq.com/decl/spiral.anderson.html
有三个简单的步骤:
从未知元素开始,以螺旋/顺时针方向移动; 在制定以下元素时,用相应的英语声明替换它们:
[X]或[] =>数组X大小...或数组未定义大小...
(type1,type2)=>函数传递type1和type2返回...
- =>指针到......
继续以螺旋/顺时针方向执行此操作,直到所有令牌都被覆盖.始终先解决括号中的任何内容!
请参阅"示例#3:'终极'",这正是您所要求的:
"signal是一个传递int的函数和一个传递int的函数的指针,返回没有任何东西(void)返回一个指向传递int的函数的指针(void)