C函数声明可以有多个标识符吗?
示例3中有一个C函数声明C函数声明可以有多个标识符吗?,c,signals,function-pointers,typedef,C,Signals,Function Pointers,Typedef,示例3中有一个C函数声明信号: void (*signal(int, void (*fp)(int)))(int); 我想知道怎么会有两个标识符signal,fp,它仍然通过编译(我在现有代码中随机添加了这一行,它成功编译了)?名称fp通常用于FILE*类型的变量,但它可以用于各种其他用途(浮点、渔业保护、函数指针等) 问题中的函数声明与C标准中的声明相同,只是它使用了fp,其中标准使用了func,并且标准为sig的第一个参数指定了名称sig 您可以从函数声明(原型)中删除fp;无重大更改:
信号
:
void (*signal(int, void (*fp)(int)))(int);
我想知道怎么会有两个标识符
signal
,fp
,它仍然通过编译(我在现有代码中随机添加了这一行,它成功编译了)?名称fp
通常用于FILE*
类型的变量,但它可以用于各种其他用途(浮点、渔业保护、函数指针等)
问题中的函数声明与C标准中的声明相同,只是它使用了fp
,其中标准使用了func
,并且标准为sig
的第一个参数指定了名称sig
您可以从函数声明(原型)中删除fp
;无重大更改:
void (*signal(int, void (*)(int)))(int);
您还可以在整个过程中为参数使用有意义的名称:
void (*signal(int signum, void (*handler)(int signum)))(int signum);
每次出现的signum
标识提供信号号的位置。signal()的第一个参数
本身是一个信号号;handler
的参数表示将使用信号号调用处理函数;最外面的signum
表示signal()
返回的函数指针与handler
的类型相同,应该是(is)呼叫时传递了一个信号号码
另请参见。名称
fp
通常用于FILE*
类型的变量,但它也可用于各种其他用途(浮点、渔业保护、函数指针等)
问题中的函数声明与C标准中的声明相同,只是它使用了fp
,其中标准使用了func
,并且标准为sig
的第一个参数指定了名称sig
您可以从函数声明(原型)中删除fp
;无重大更改:
void (*signal(int, void (*)(int)))(int);
您还可以在整个过程中为参数使用有意义的名称:
void (*signal(int signum, void (*handler)(int signum)))(int signum);
每次出现的signum
标识提供信号号的位置。signal()的第一个参数
本身是一个信号号;handler
的参数表示将使用信号号调用处理函数;最外面的signum
表示signal()
返回的函数指针与handler
的类型相同,应该是(is)呼叫时传递了一个信号号码
另请参见。否,C函数声明/原型不能有多个标识符。请参阅cplusplus.com上的参考页和信号示例代码: 在本宣言中:
void (*signal(int sig, void (*func)(int)))(int);
我们正在声明一个名为signal
的函数,它返回一个指向函数的指针,该函数返回void
,并接受一个int
——即:指向如下函数的指针:
void func(int);
信号
函数的输入是1,一个int
,2,一个指向函数的指针,该函数返回一个void
,并接受一个int
——同样,一个指向类似上述func
函数的指针。现在,在C中,当声明一个函数时,该函数返回一个指向函数的指针,并接受一个指向函数的指针在一开始,它看起来很傻(看起来乱七八糟),这就是为什么我们一开始都很困惑(而且一次又一次频繁)查看函数声明,如signal
。在C中定义函数,如signal
,有两种更清晰的方法,让这一切都清晰明了,它们都是这样的,而这两种方法都与看起来呆滞呆滞的方法相同:
// 1. typedef a function--call it `func_t` for "func type"
typedef void func_t(int);
// 2. Use the typedef above to define `signal`
func_t* signal(int sig, func_t* fp); // Ah, now this makes sense!
或
记住,函数声明中的每个输入参数类型在C中都是无关的,甚至不必在头文件和源文件之间匹配。
例:
my\u模块.h:
// Any of these 3 prototypes are equivalent, valid, and identical
// (although using sensible names which match between the header &
// source files is most clear and helpful to the reader!):
func_p signal(int sig, func_p fp);
func_p signal(int signal, func_p whatsupdude);
func_p signal(int, func_p);
func_p signal(int sig, func_p fp)
{
// define the function here
}
my_模块.c:
// Any of these 3 prototypes are equivalent, valid, and identical
// (although using sensible names which match between the header &
// source files is most clear and helpful to the reader!):
func_p signal(int sig, func_p fp);
func_p signal(int signal, func_p whatsupdude);
func_p signal(int, func_p);
func_p signal(int sig, func_p fp)
{
// define the function here
}
现在,我最初是如何理解这一切的?答:我看了。这有助于把这一切弄清楚,因为你可以看到
信号的返回值是如何分配给prev\u handler
,它是一个函数的指针,你可以看到my\u handler
,它被定义为一个函数,是如何作为第二个参数传递给信号的d可能还提到,这两行是相同的,并且都是完全有效的:
prev_handler = signal (SIGINT, my_handler);
prev_handler = signal (SIGINT, &my_handler);
这是因为,如果您将函数作为参数传入,编译器知道无论如何只需获取其地址
/*信号示例*/
#包括/*printf*/
#包括/*信号、上升、信号*/
sig_原子信号=0;
作废我的_处理程序(int参数)
{
信号=1;
}
int main()
{
无效(*上一页)(整数);
prev_handler=信号(SIGINT,my_handler);
/* ... */
升起(SIGINT);
/* ... */
printf(“发出信号的是%d.\n”,发出信号的);
返回0;
}
参考资料:
关于如何键入定义函数和函数指针的提示,因为这几乎让所有人都感到困惑,并且需要不时重新验证:
否,C函数声明/原型不能有多个标识符。请参阅cplusplus.com上的参考页和信号示例代码:
在本宣言中:
void (*signal(int sig, void (*func)(int)))(int);
我们正在声明一个名为signal
的函数,它返回一个指向函数的指针,该函数返回void
,并接受一个int
——即:指向如下函数的指针:
void func(int);
信号
函数的输入是第一个int
,第二个是指向函数的指针,该函数返回void
,并接受int
——同样,是指向上面类似func
的函数的指针