c - 如何理解这个定义

标签 c linux syntax function-declaration

现在,我正在阅读 APUE。我发现函数定义如下:

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

我很困惑,我知道信号是指向函数的指针,最后一个 (int) 是他的参数。 我不知道什么是 (int signo,void (*func)(int))。

最佳答案

一般过程:找到最左边的标识符,然后找出路。如果没有带括号的显式分组,()[] 等后缀运算符将在 * 等一元运算符之前绑定(bind);因此,以下都是正确的:

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 的函数的指针。

您可以使用 typedef 使其更易于阅读(Ubuntu linux 上 signal 的手册页就是这样做的);但是,我认为展示非 typedef'd 版本以准确演示语法是如何工作的是有值(value)的。 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 的示例代码扩展到希望更具说明性的内容。

关于c - 如何理解这个定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4123006/

相关文章:

asp.net - 如何发送post请求?

c - 如何在 C 中的堆栈上创建一个结构?

c++ - Curl 命令行有效,C++ curl 库无效

有人可以解释 fork 是如何工作的吗?

linux - cscope: ctrl + ']' 不起作用

linux - lvcreate 在物理卷上创建什么?会删除数据吗?

ruby - `:key => "值"` and `键: "value"` hash notations?有区别吗

java - 如何在 Ubuntu Linux 启动时运行 Java 应用程序

haskell - 为什么在没有额外缩进的情况下换行大小写匹配会出现语法错误,以及推荐的解决方法是什么?

syntax - YAML中序列中的多行