开发者社区> 问答> 正文

C语言高手帮忙分析一下复杂的函数声明

C语言高手帮忙分析一下下面这个复杂的声明,最好有详细步骤:

void (signal(int sig, void (handler)(int)))(int);
该函数原型来自C语言标准库 signal.h.

展开
收起
a123456678 2016-06-07 20:10:02 3208 0
7 条回答
写回答
取消 提交回答
  • 右左原则

    2020-03-17 17:04:07
    赞同 展开评论 打赏
  • 右左原则

    2020-03-17 11:02:39
    赞同 展开评论 打赏
  • 专注物联网

    在对上面的例子作分析之前,我们需要了解C语言的声明优先级,《C专家编程》P64原文如下:

    image

    规则A规定了要按照优先级来解释声明(算是一句废话)。规则C请参照本人上一篇笔记:http://www.cnblogs.com/deyuanqin/p/5705967.html。规则B的具体实践过程如下图:

    image

    本着抛砖引玉的目的,我们使用以上规则分析void (signal(int sig, void (handler)(int)))(int)这个复杂的声明。从易到难的顺序:

    void (*handler)(int):
    ① handler右边是圆括号,所以handler不是数组或者函数。再看其左边,是(星号),所以handler是一个指向*的指针。

    ② (handler)(int)。(handler)的右边是圆括号,因而(handler)(int)中的()(int)是一个返回的函数。结合上一步分析,handler是一个指向返回*的函数的指针。

    ③ (*handler)(int)的右边没有符号,左边是void。综上,handler是一个指向返回void值的函数的指针。

    void (signal(int sig, void (handler)(int)))(int):
    void (handler)(int)在上面的步骤已经做了分析,我们可以使用语句typedef void (handler)(int)将其简化(将handler声明为一个新的类型,这个类型是是一个指向返回void值的函数的指针。有关typedef的知识改日再做分析),则void (signal(int sig, void (handler)(int)))(int)就被简化为void (signal(int sig, handle h))(int)。下面我们对void (signal(int sig, handle h))(int)作分析:

    ① signal右边是圆括号,因而signal()是一个返回**的函数。

    ② signal()的左边是,因而signal()是一个返回指向*的指针的函数。

    ③ (signal(int sig, handle h))右边是圆括号,因此(signal(int sig, handle h))(int)是一个返回的函数。综上,signal是一个返回指向返回函数的指针的函数。

    ④ (*signal(int sig, handle h))右边是void。因而,signal(这个标识符)是一个返回指向返回void值的函数的指针的函数。

    以上的分析过程可能有错漏,请各位看官多指教。

    2019-07-17 19:30:58
    赞同 展开评论 打赏
  • 软件开发,安全加密

    在对上面的例子作分析之前,我们需要了解C语言的声明优先级,《C专家编程》P64原文如下:

    image

    规则A规定了要按照优先级来解释声明(算是一句废话)。规则C请参照本人上一篇笔记:http://www.cnblogs.com/deyuanqin/p/5705967.html。规则B的具体实践过程如下图:

    image

    本着抛砖引玉的目的,我们使用以上规则分析void (signal(int sig, void (handler)(int)))(int)这个复杂的声明。从易到难的顺序:

    void (*handler)(int):
    ① handler右边是圆括号,所以handler不是数组或者函数。再看其左边,是(星号),所以handler是一个指向*的指针。

    ② (handler)(int)。(handler)的右边是圆括号,因而(handler)(int)中的()(int)是一个返回的函数。结合上一步分析,handler是一个指向返回*的函数的指针。

    ③ (*handler)(int)的右边没有符号,左边是void。综上,handler是一个指向返回void值的函数的指针。

    void (signal(int sig, void (handler)(int)))(int):
    void (handler)(int)在上面的步骤已经做了分析,我们可以使用语句typedef void (handler)(int)将其简化(将handler声明为一个新的类型,这个类型是是一个指向返回void值的函数的指针。有关typedef的知识改日再做分析),则void (signal(int sig, void (handler)(int)))(int)就被简化为void (signal(int sig, handle h))(int)。下面我们对void (signal(int sig, handle h))(int)作分析:

    ① signal右边是圆括号,因而signal()是一个返回**的函数。

    ② signal()的左边是,因而signal()是一个返回指向*的指针的函数。

    ③ (signal(int sig, handle h))右边是圆括号,因此(signal(int sig, handle h))(int)是一个返回的函数。综上,signal是一个返回指向返回函数的指针的函数。

    ④ (*signal(int sig, handle h))右边是void。因而,signal(这个标识符)是一个返回指向返回void值的函数的指针的函数。

    以上的分析过程可能有错漏,请各位看官多指教。

    2019-07-17 19:30:58
    赞同 展开评论 打赏
  • C++/C并不是一门函数语言,函数也无法作为一等公民在这语言中出现,所以Cpp/C在传递参数为函数时(实际上传递的是函数的内存地址),都会将函数原型(函数名、参数)一并传入

    2019-07-17 19:30:58
    赞同 展开评论 打赏
  • 乐于学习与分析

    在对上面的例子作分析之前,我们需要了解C语言的声明优先级,《C专家编程》P64原文如下:

    image

    规则A规定了要按照优先级来解释声明(算是一句废话)。规则C请参照本人上一篇笔记:http://www.cnblogs.com/deyuanqin/p/5705967.html。规则B的具体实践过程如下图:

    image

    本着抛砖引玉的目的,我们使用以上规则分析void (signal(int sig, void (handler)(int)))(int)这个复杂的声明。从易到难的顺序:

    void (*handler)(int):
    ① handler右边是圆括号,所以handler不是数组或者函数。再看其左边,是(星号),所以handler是一个指向*的指针。

    ② (handler)(int)。(handler)的右边是圆括号,因而(handler)(int)中的()(int)是一个返回的函数。结合上一步分析,handler是一个指向返回*的函数的指针。

    ③ (*handler)(int)的右边没有符号,左边是void。综上,handler是一个指向返回void值的函数的指针。

    void (signal(int sig, void (handler)(int)))(int):
    void (handler)(int)在上面的步骤已经做了分析,我们可以使用语句typedef void (handler)(int)将其简化(将handler声明为一个新的类型,这个类型是是一个指向返回void值的函数的指针。有关typedef的知识改日再做分析),则void (signal(int sig, void (handler)(int)))(int)就被简化为void (signal(int sig, handle h))(int)。下面我们对void (signal(int sig, handle h))(int)作分析:

    ① signal右边是圆括号,因而signal()是一个返回**的函数。

    ② signal()的左边是,因而signal()是一个返回指向*的指针的函数。

    ③ (signal(int sig, handle h))右边是圆括号,因此(signal(int sig, handle h))(int)是一个返回的函数。综上,signal是一个返回指向返回函数的指针的函数。

    ④ (*signal(int sig, handle h))右边是void。因而,signal(这个标识符)是一个返回指向返回void值的函数的指针的函数。

    以上的分析过程可能有错漏,请各位看官多指教。

    2019-07-17 19:30:58
    赞同 展开评论 打赏
  • void (signal(int sig, void (handler)(int)))(int);

                       ^^^^^^^^^^^^^^^^^^^^^
                       // 是函数指针,设为 Func1

    void (*signal(int sig, Func1))(int)

       ^^^^^^^^^^^^^^^^^^^^^^
       // 是普通函数,设为 Func2

    void (*Func2)(int)
    ^^^^^^^^^^^^^^^^^^
    // 是函数指针,设为 Func3
    Func1: void(*)(int)
    Func2: signal(int, Func1)
    Func3: void(*)(int) == Func1
    于是该函数声明可简化为:

    Func1 signal(int, Func1);
    还觉得难吗?

    再补充上用法吧,可能更加清楚:

    void my_handler (int param)
    {
    signaled = 1;
    }

    void (*prev_handler)(int); // 声明一个函数指针
    prev_handler = signal (SIGINT, my_handler);
    应该很清楚了,该函数声明中,主体是 Func2, 返回值与参数 2 的类型都是 Func1.

    2019-07-17 19:30:58
    赞同 展开评论 打赏
滑动查看更多
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载

相关实验场景

更多