C 为什么可以';调用函数信号返回的函数(信号处理器)?

C 为什么可以';调用函数信号返回的函数(信号处理器)?,c,signals,C,Signals,在计算出信号函数的签名后,我修改了由给出的示例 但是为什么我不能调用信号返回的函数(信号处理程序),而可以直接调用它呢 void(*信号(int-sig,void(*handler)(int)))(int) 信号函数返回指向函数的指针,即void(*)(int) 返回值 成功时之前的信号处理程序或失败时的信号处理程序SIG_ERR(在某些实现中可以禁用设置信号处理程序) #包括 #包括 无效信号处理器(int信号) { printf(“哈哈哈”\n); } 内部主(空) { 无效(*f1)(内

在计算出
信号
函数的签名后,我修改了由给出的示例

但是为什么我不能调用
信号返回的函数(信号处理程序),而可以直接调用它呢


void(*信号(int-sig,void(*handler)(int)))(int)

信号
函数返回指向函数的指针,即
void(*)(int)

返回值 成功时之前的信号处理程序或失败时的信号处理程序
SIG_ERR
(在某些实现中可以禁用设置信号处理程序)

#包括
#包括
无效信号处理器(int信号)
{
printf(“哈哈哈”\n);
}
内部主(空)
{
无效(*f1)(内部);
f1=信号(SIGINT,信号处理器);
f1(3);//获取信号SIGSEGV失败
//信号处理器(3);//正常
升起(SIGINT);
}
我知道这看起来像一个毫无意义的问题,但问题是,
f1
指向
signal\u handler
,所以调用
f1(3)
就像调用
signal\u handler(3)
,我不明白为什么后者可以,但前者不行,不应该有“把戏”我认为,这可以在这两个调用函数状态之间进行转换

在以下行中:

f1 = signal(SIGINT, signal_handler);
f1
分配了一个以前的信号处理程序(它不是代码中的
signal\u处理程序
),它可能不是指向可以使用
int
参数调用的函数的指针

要实现此效果,您需要定义第二个信号处理程序,并将其分配到上述行之后的
f1

大概是这样的:

#include <signal.h>
#include <stdio.h>

void signal_handler2(int signal)
{
    printf("hahahah2222\n");
}

void signal_handler(int signal)
{
    printf("hahahah\n");
}

int main(void)
{
    void (*f1)(int);
    f1 = signal(SIGINT, signal_handler);
    f1 = signal(SIGINT, signal_handler2);
    f1(3);  //Success
    signal_handler2(3); //OK
    raise(SIGINT);    
}

请参阅Live至少有3个值是
signal()
可以返回的,它们不是实际函数的指针:

  • SIG_DFL
    -通常
    ((void(*)(int))0)
  • SIG\u IGN
    -通常
    ((void(*)(int))1)
  • SIG_ERR
    -通常
    ((void(*)(int))-1)
  • 当程序启动时,信号处于
    SIG_IGN
    SIG_DFL
    模式;随后可以将它们设置为另一个值


    当您调用
    f1=signal(SIGINT,signal\u处理程序)时
    ,则返回一个
    SIG\u DFL
    SIG\u IGN
    ——这两个都不是指向可调用函数的指针(即使它们的类型是指向正确类型的函数的指针)。

    前面的信号处理程序不一定是指向函数的指针。@user3386109 Hmm,不明白
    signal
    返回
    void(*)(int)
    ,这不是指向函数的指针(函数指针)并可以调用它吗?响应编辑:
    f1
    不指向
    signal\u处理程序
    。它指向前面的信号处理程序。您可以使用
    printf
    %p
    格式说明符来显示
    f1
    signal\u处理程序
    ,您会看到它们是不同的。@user3386109是的,您是对的。谢谢你告诉我要使用
    %p
    :D。事实就是这样。。文件总是有点误导。既然我已经注册了一个新的处理程序,我自然会认为之前的处理程序应该是我刚刚注册的那个。。。谢谢你(顺便说一句;)模式
    #定义了HAHA(void(*)(int))2
    的含义是什么?我猜它定义了一个函数指针,指针的值是
    2
    。但是我只熟悉像
    #define CONSTANT value
    这样的模式。我试图通过做
    #定义HAHA float 2.3
    来模仿,但失败了:(.这是我第一次看到这种用法,你能给我一些提示或可能是一些参考吗?我看到了其他两个问题,但答案并没有真正的帮助。是的;
    哈哈
    是一个数值为2的函数指针。它不能安全地用于
    (*HAHA)(3)
    哈哈(3)
    -这两种符号都有效,但前者在C89标准发布之前是必需的。好的,我明白了。谢谢。你知道在一些官方文档或标准上哪里可以找到这种用法吗?好的,符号
    (void(*)(int))
    后跟一个值就是将该值转换为指向函数的指针。转换
    2
    (或
    1
    0
    -1
    )可能没有任何官方文件记录。快速扫描C11标准没有发现任何有用的东西。哦,我明白了。除了铸造之外没有什么特别的。耶,这是我需要的。然后我肯定可以做
    #定义HAHA(float)2.3
    。谢谢!
    #include <signal.h>
    #include <stdio.h>
    
    void signal_handler2(int signal)
    {
        printf("hahahah2222\n");
    }
    
    void signal_handler(int signal)
    {
        printf("hahahah\n");
    }
    
    int main(void)
    {
        void (*f1)(int);
        f1 = signal(SIGINT, signal_handler);
        f1 = signal(SIGINT, signal_handler2);
        f1(3);  //Success
        signal_handler2(3); //OK
        raise(SIGINT);    
    }
    
    hahahah
    hahahah2222
    hahahah2222