这段代码的含义是什么?void(*signal(int sig,void(*func)(int)))(int);

pho*_*ton 34 c

我遇到了这段代码,完全迷失了解释它的含义.

#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
Run Code Online (Sandbox Code Playgroud)

第2行代码的详细解释是什么?

我知道void并且int是类型,*func是函数的指针,括号是优先级.但是我仍然没有把(*信号......),(int)和整个事物结合在一起.越详细越好.

可能我已经知道这个宣言的意义/效果了.但我不得不做一些试验来帮助我了解正在发生的事情,如下所示:

  1 #include <signal.h>
  2 void (*signal)(int sig, void (*func)(int));
  3 void (*signal)(int);  // then void (signal)(int) again.
  4 //void (*signal(int sig, void (*func)(int)))(int); //break this line into two lines above
  5
  6 int main(){}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我void (*signal(int sig, void (*func)(int)))(int)分成了两行.对于3号线,我都尝试void (*signal)(int)void (signal)(int),与表明我试图重新声明同样的错误的结果signal:

TestDeclaration.c:2:错误:'signal'重新声明为不同类型的符号/usr/include/signal.h:93:错误:先前'signal'的声明在这里
TestDeclaration.c:3:错误:'signal'重新声明作为不同类型的符号/usr/include/signal.h:93:错误:之前的'信号'声明就在这里

现在我知道两种审判都是不正确的申报方式,但为什么它们不正确呢?为什么声明的原始方式不是重新声明?

CB *_*ley 40

它是一个函数的声明,它接受一个函数int的指针(int返回void)并返回一个指向函数的指针(取int并返回void).


解释或解释指南

您可以通过将括号中的所有内容视为单个实体进行解释,然后使用"声明跟随使用"规则向内工作.

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

括号中的实体看起来像一个函数获取int和返回void.

剥去外部部分:

*signal(int sig, void (*func)(int))
Run Code Online (Sandbox Code Playgroud)

因此,signal获取一些参数并返回可以被解除引用的内容(由于前导*)以形成函数获取int和返回void.

这意味着signal一个函数返回一个指向函数的指针(获取int和返回void).

查看它所需的参数int(即sig),void (*func)(int)它是指向函数的指针(取int和返回void).

  • +1.非常简洁.在尝试解析复杂的C声明时,有助于了解顺时针/螺旋规则. - http://c-faq.com/decl/spiral.anderson.html (10认同)

Bar*_*nau 8

这是复杂的C声明如何变成的经典例子之一.
要理解此声明,通常有助于引入typedef:

typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t func);
Run Code Online (Sandbox Code Playgroud)

typedef声明一个指向函数的指针(接受一个int参数并且不返回任何内容).该函数signal现在可以看作是一个函数,它接受两个参数(一个int和一个指向函数的指针)并返回一个指向函数的指针.

这也可以从原始声明中获得,但需要一些练习.通常的方法是从标识最外层实体的标识符开始(signal在这种情况下):

signal 是......

然后你正确阅读,直到你找到一个不匹配的右括号或声明的结尾: void (*signal(int sig, void (*func)(int))(int)

signal 是一个功能......回来......

现在,您可以选择首先解析参数,还是首先解析返回值.我会先做返回值.为此,您向后读取以找到匹配的左括号:void (signal( / ... */ ))(int)

`signal是一个函数......返回指针...

以这种方式来回读取你会在连续的阶段得到:

`signal是一个函数...返回一个指向a的函数(函数正在......返回......)

`signal是一个函数...返回一个指针(函数取...返回void)

`signal是一个函数...返回一个指向(函数接受int并返回void)的指针

`signal是一个带有两个参数的函数:(一个int)和一个指向函数的指针,它接受一个int并返回void,然后返回一个指针(一个带有int并返回void的函数)