如何理解这个定义

发布于 2024-09-30 23:31:41 字数 189 浏览 9 评论 0原文

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

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

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

Nowadays , i was reading the APUE.and i found the function defined as below:

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

i was confused, i know signal is pointer to a function and the last (int) is his parameter.
i did not know what is (int signo,void (*func)(int)).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

孤独患者 2024-10-07 23:31:42

此站点对 C 乱码进行了声明:

C 胡言乱语 <->英语

This site gives declerations to C gibberish:

C gibberish <-> English

不知在何时 2024-10-07 23:31:42

为您的发行版安装cdecl(如果有)或转到这里

否则,我相信Armen Tsirunyan的答案是正确的。

Install cdecl for your distribution (if available) or go here

Otherwise, I believe Armen Tsirunyan's answer is correct.

十年不长 2024-10-07 23:31:41

一般过程:找到最左边的标识符并找到出路。如果没有使用括号进行显式分组,后缀运算符(例如 ()[])会绑定在一元运算符(例如 *)之前;因此,以下内容都是正确的:

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 版本以准确演示语法的工作原理是很有价值的。 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 的示例代码扩展为希望更具说明性的内容。

The general procedure: find the leftmost identifier and work your way out. Absent an explicit grouping with parentheses, postfix operators such as () and [] bind before unary operators like *; thus, the following are all true:

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

Applying these rules to the declaration, it breaks down as

       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

In short, signal returns a pointer to a function returning void. signal takes two parameters: an integer and a pointer to another function returning void.

You could use typedefs to make this easier to read (and the man page for signal on Ubuntu linux does just that); however, I think it's valuable to show the non-typedef'd version to demonstrate exactly how the syntax works. The typedef facility is wonderful, but you really need to understand how the underlying types work in order to use it effectively.

The signal function sets up a signal handler; the second argument is the function that is to be executed if a signal is received. A pointer to the current signal handler (if any) is returned.

For example, if you want your program to handle interrupt signals (such as from 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;
}

EDIT I extended the example code for signal to something that's hopefully more illustrative.

裂开嘴轻声笑有多痛 2024-10-07 23:31:41
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 将在

double (*f(int))(char);

“Wooooooow”的注释之后编辑:,我提供另一个更“woooow”的例子:)

让我们声明一个函数,它需要
1. 一个指向数组的指针,该数组包含 5 个指向函数的指针,每个函数都采用 float 并返回 double。
2. 指向 3 个整数数组的指针到 4 个整数数组
并返回一个指向函数的指针,该函数接受一个指向采用 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);

现在,有趣的部分:) 如果没有 typedef,这将是

 unsigned int (*TheFunction( double (*(*)[5])(float), int(*(*)[3])[4]))( void(*(*)(int))(float))

天哪,我刚刚写了那个吗? :)

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

signal is function that takes int and a pointer to function taking int and returning void and returns a function pointer taking int and returning void. That is,

typedef void(*funcPtr)(int)

then we have

funcPtr signal(int signo, funcPtr func); //equivalent to the above

The syntax is indeed strange, and such things better be done with a typedef. As an example, if you want to declare a function that takes an int and returns a pointer to a function taking char and returning double will be

double (*f(int))(char);

Edit: after a comment that reads "Wooooooow", I am providing another example which is more "woooow" :)

Let's declare a function that takes
1. a pointer to array of 5 pointers to functions each taking float and returning double.
2. a pointer to array of 3 ponters to arrays of 4 ints
and returns a pointer to function that takes a pointer to function taking int and returning a pointer to function taking float and returning void and returns unsigned int.

The typedef solution would be this:

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);

Now, the funny part :) Without typedefs this will be:

 unsigned int (*TheFunction( double (*(*)[5])(float), int(*(*)[3])[4]))( void(*(*)(int))(float))

My god, did I just write that? :)

终止放荡 2024-10-07 23:31:41

顺时针螺旋规则将有助于:
http://c-faq.com/decl/spiral.anderson.html

需要遵循三个简单的步骤:

从未知元素开始,沿螺旋/顺时针方向移动;遇到以下内容时,将其替换为相应的英文语句:

[X] 或 [] =>数组 X 大小...或数组未定义大小...

(类型1,类型2)=>函数传递 type1 和 type2 返回...

  • =>;指向...的指针

继续以螺旋/顺时针方向执行此操作,直到覆盖所有标记。
始终首先解决括号中的任何问题!

请参阅“示例#3:‘终极’”,这几乎正是您所要求的:

“信号是一个传递 int 和指向传递 int 的函数的指针的函数,不返回任何内容 (void),返回指向 a 的指针传递 int 的函数不返回任何内容 (void)”

The Clockwise Spiral rule will help:
http://c-faq.com/decl/spiral.anderson.html

There are three simple steps to follow:

Starting with the unknown element, move in a spiral/clockwise direction; when ecountering the following elements replace them with the corresponding english statements:

[X] or [] => Array X size of... or Array undefined size of...

(type1, type2) => function passing type1 and type2 returning...

  • => pointer(s) to...

Keep doing this in a spiral/clockwise direction until all tokens have been covered.
Always resolve anything in parenthesis first!

See "Example #3: The 'Ultimate'", which is pretty much exactly what you are asking for:

"signal is a function passing an int and a pointer to a function passing an int returning nothing (void) returning a pointer to a function passing an int returning nothing (void)"

拥抱没勇气 2024-10-07 23:31:41

如果您现在无法访问 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

In case you don't have access to cdecl right now, here is the cdecl output:

$ 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文