维基百科文章中的函数指针声明
Function pointer decleration in Wikipedia article
在维基百科关于 typedef 的文章中,有以下关于将 typedef 用于函数指针的示例:
typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t func);
也许因为我是C的新手,这让我感到困惑:sighandler_t是一个指向带有1个int参数的函数的指针,如何在下一行用一个int +另一个函数指针来声明信号?
感谢您的帮助!
函数signal
有自己的类型
sighandler_t (int sig, sighandler_t func)
或者写成函数指针 then
sighandler_t ( * )(int sig, sighandler_t func)
是它的return类型,第二个参数类型是函数指针类型sighandler_t
。
那是函数 signal
returns 指向类型 sighandler_t
的函数的指针并且有两个参数:第一个类型 int
和sighandler_t
.
类型的第二个
没有 typedef
typedef void (*sighandler_t)(int);
函数的声明signal
看起来像
void ( * signal(int sig, void ( *func )( int ) )( int );
对于函数 signal
,您可以通过以下方式为其类型引入 typedef
typedef sighandler_t ( signal_t )( int, sighandler_t );
然后像
一样声明(但不定义)函数signal
signal_t signal;
这是一个演示程序,我希望它有助于理解 return 函数指针 or/and 具有函数指针类型参数的函数的函数声明。
#include <stdio.h>
void f( int x )
{
printf( "%d ", x );
}
typedef void ( *FP )( int );
FP g( const int a[], size_t n, FP fp )
{
for ( size_t i = 0; i < n; i++ )
{
fp( a[i] );
}
putchar( '\n' );
return fp;
}
int main(void)
{
enum { N = 5 };
int a[N] = { 1, 2, 3, 4, 5 };
int b[N] = { 5, 4, 3, 2, 1 };
FP fp = g( a, N, f );
g( b, N, fp );
return 0;
}
程序输出为
1 2 3 4 5
5 4 3 2 1
你必须考虑这一点并分阶段建立它。即使使用 typedef 也可能会造成混淆。 (如果没有 typedef,它甚至 更多 令人困惑!)
是的,信号处理程序是一个接受一个 int
并返回 void
的函数,就像这样:
void handler(int);
要创建一个指向这样的函数的指针,我们添加一个 *
(表示一个指针)和一对括号以保持优先顺序:
void (*funcptr)(int);
要“命名”该类型——也就是说,将其简洁但抽象地描述为类型名称,但不提及标识符——我们实际上只是删除了标识符:
void (*)(int)
这是什么意思?好吧,如果我写 int
你知道我在谈论 C 的普通整数类型。如果我写 int *
你知道我在谈论一个指向 int
的指针。如果我写 void (*)(int)
你知道(一旦你理解了相当令人费解的命名法)我在谈论一个指向函数的指针,它接受 int
和 returns void
.
因此,如果需要,我们可以从中创建一个 typedef:
typedef void (*sighandler_t)(int);
这里我在后面加了一个标识符(sighandler_t
),在前面加了关键字typedef
。 typedef
的意思是 sighandler_t
不会像在常规变量声明中那样成为一个指向接受 int
并返回 void
的函数的指针——相反,它是一个alias 或 synonym 类型名称“指向采用 int
并返回 void
的函数的指针”。 (考虑 typedef
的一种方式是,它就像 #define
,但在类固醇上。)
所以现在每当我们说 sighandler_t
时,就像说 void (*)(int)
或“指向函数的指针获取 int
并返回 void
”。
现在,signal
是一个接受 (a) 信号编号和 (b) 指向该信号的新处理函数的指针的函数。所以是
signal(int sig, sighandler_t func)
也就是说,func
将成为指向信号处理函数的指针,该函数接受一个 int
并返回 void
。
但是 signal
也 returns 以前的信号处理程序,被传入的新 func
替换的那个。所以完整的是
sighandler_t signal(int sig, sighandler_t func)
希望这是有道理的。这是有道理的,因为 typedef 为我们执行了重要的符号简化。
如果没有 typedef,我们会有类似的东西
void (*signal(int sig, void (*func)(int)))(int)
这几乎是完全不可读的。我不会试图想出一种从表面上解释这一点的方法。 (我也不打算描述我过去采用更简单、使用 typedef 的形式并在没有真正理解它的情况下机械地派生这个 jawbreaker 的容易出错的过程。)
在这种情况下,第二行将 signal
声明为一个函数,该函数接收指向类型为 sig_handler_t
的函数的指针作为其输入参数之一,并且 returns 是指向sig_handler_t
类型的函数。函数 signal
本身不是 sig_handler_t
.
类型
在维基百科示例中,问题中的两行用于简化:
void (*signal(int sig, void (*func)(int)))(int);
这里void (*func)(int)
指定了一个参数func
,它的类型等同于sig_handler_t
。此外,用 void (* ... )(int)
包装声明将指定类型 sig_handler_t
的 return 值,尽管我从未见过有人在实践中这样做。
在维基百科关于 typedef 的文章中,有以下关于将 typedef 用于函数指针的示例:
typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t func);
也许因为我是C的新手,这让我感到困惑:sighandler_t是一个指向带有1个int参数的函数的指针,如何在下一行用一个int +另一个函数指针来声明信号? 感谢您的帮助!
函数signal
有自己的类型
sighandler_t (int sig, sighandler_t func)
或者写成函数指针 then
sighandler_t ( * )(int sig, sighandler_t func)
是它的return类型,第二个参数类型是函数指针类型sighandler_t
。
那是函数 signal
returns 指向类型 sighandler_t
的函数的指针并且有两个参数:第一个类型 int
和sighandler_t
.
没有 typedef
typedef void (*sighandler_t)(int);
函数的声明signal
看起来像
void ( * signal(int sig, void ( *func )( int ) )( int );
对于函数 signal
,您可以通过以下方式为其类型引入 typedef
typedef sighandler_t ( signal_t )( int, sighandler_t );
然后像
一样声明(但不定义)函数signal
signal_t signal;
这是一个演示程序,我希望它有助于理解 return 函数指针 or/and 具有函数指针类型参数的函数的函数声明。
#include <stdio.h>
void f( int x )
{
printf( "%d ", x );
}
typedef void ( *FP )( int );
FP g( const int a[], size_t n, FP fp )
{
for ( size_t i = 0; i < n; i++ )
{
fp( a[i] );
}
putchar( '\n' );
return fp;
}
int main(void)
{
enum { N = 5 };
int a[N] = { 1, 2, 3, 4, 5 };
int b[N] = { 5, 4, 3, 2, 1 };
FP fp = g( a, N, f );
g( b, N, fp );
return 0;
}
程序输出为
1 2 3 4 5
5 4 3 2 1
你必须考虑这一点并分阶段建立它。即使使用 typedef 也可能会造成混淆。 (如果没有 typedef,它甚至 更多 令人困惑!)
是的,信号处理程序是一个接受一个 int
并返回 void
的函数,就像这样:
void handler(int);
要创建一个指向这样的函数的指针,我们添加一个 *
(表示一个指针)和一对括号以保持优先顺序:
void (*funcptr)(int);
要“命名”该类型——也就是说,将其简洁但抽象地描述为类型名称,但不提及标识符——我们实际上只是删除了标识符:
void (*)(int)
这是什么意思?好吧,如果我写 int
你知道我在谈论 C 的普通整数类型。如果我写 int *
你知道我在谈论一个指向 int
的指针。如果我写 void (*)(int)
你知道(一旦你理解了相当令人费解的命名法)我在谈论一个指向函数的指针,它接受 int
和 returns void
.
因此,如果需要,我们可以从中创建一个 typedef:
typedef void (*sighandler_t)(int);
这里我在后面加了一个标识符(sighandler_t
),在前面加了关键字typedef
。 typedef
的意思是 sighandler_t
不会像在常规变量声明中那样成为一个指向接受 int
并返回 void
的函数的指针——相反,它是一个alias 或 synonym 类型名称“指向采用 int
并返回 void
的函数的指针”。 (考虑 typedef
的一种方式是,它就像 #define
,但在类固醇上。)
所以现在每当我们说 sighandler_t
时,就像说 void (*)(int)
或“指向函数的指针获取 int
并返回 void
”。
现在,signal
是一个接受 (a) 信号编号和 (b) 指向该信号的新处理函数的指针的函数。所以是
signal(int sig, sighandler_t func)
也就是说,func
将成为指向信号处理函数的指针,该函数接受一个 int
并返回 void
。
但是 signal
也 returns 以前的信号处理程序,被传入的新 func
替换的那个。所以完整的是
sighandler_t signal(int sig, sighandler_t func)
希望这是有道理的。这是有道理的,因为 typedef 为我们执行了重要的符号简化。
如果没有 typedef,我们会有类似的东西
void (*signal(int sig, void (*func)(int)))(int)
这几乎是完全不可读的。我不会试图想出一种从表面上解释这一点的方法。 (我也不打算描述我过去采用更简单、使用 typedef 的形式并在没有真正理解它的情况下机械地派生这个 jawbreaker 的容易出错的过程。)
在这种情况下,第二行将 signal
声明为一个函数,该函数接收指向类型为 sig_handler_t
的函数的指针作为其输入参数之一,并且 returns 是指向sig_handler_t
类型的函数。函数 signal
本身不是 sig_handler_t
.
在维基百科示例中,问题中的两行用于简化:
void (*signal(int sig, void (*func)(int)))(int);
这里void (*func)(int)
指定了一个参数func
,它的类型等同于sig_handler_t
。此外,用 void (* ... )(int)
包装声明将指定类型 sig_handler_t
的 return 值,尽管我从未见过有人在实践中这样做。