• [c语言]深入返回值为函数指针的函数


    之前写过个好玩代码
    c语言返回值为函数指针的函数

    一、发现

    #include
    
    int (*drink(void)) (void)
    {
        static int i;
        i++;
        printf("(%d)\n", i);
        return (int(*)(void))drink;
    }
    
    int main()
    {
        drink()();
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    这个代码定义了一个返回值为函数指针的函数,然后就能直接调用两次函数,但这种方法对于调用三次函数来说好像不太可能。
    后来我想一想,好像可以先定义一个函数指针类型,然后这样函数的定义也稍微简介一些

    #include 
    
    typedef long long (*p_fun)(void);
    
    p_fun fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    运行结果:
    在这里插入图片描述

    二、探索

    然后我又仔细想了想,是不是可以套娃,然后就有了下面的代码

    #include 
    
    typedef long long (*p_fun)(void);
    typedef p_fun (*p_fun2)(void);
    
    p_fun2 fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    #include 
    
    typedef long long (*p_fun)(void);
    typedef p_fun (*p_fun2)(void);
    typedef p_fun2 (*p_fun3)(void);
    
    p_fun3 fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()()()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行结果:
    在这里插入图片描述

    然后我们可以一直定义函数指针类型,就可以一直循环操作下去,最终可以实现比较难懂的代码

    #include 
    
    typedef long long (*p_fun)(void);
    typedef p_fun (*p_fun2)(void);
    typedef p_fun2 (*p_fun3)(void);
    typedef p_fun3 (*p_fun4)(void);
    typedef p_fun4 (*p_fun5)(void);
    typedef p_fun5 (*p_fun6)(void);
    typedef p_fun6 (*p_fun7)(void);
    typedef p_fun7 (*p_fun8)(void);
    typedef p_fun8 (*p_fun9)(void);
    typedef p_fun9 (*p_fun10)(void);
    typedef p_fun10 (*p_fun11)(void);
    typedef p_fun11 (*p_fun12)(void);
    typedef p_fun12 (*p_fun13)(void);
    typedef p_fun13 (*p_fun14)(void);
    typedef p_fun14 (*p_fun15)(void);
    typedef p_fun15 (*p_fun16)(void);
    typedef p_fun16 (*p_fun17)(void);
    typedef p_fun17 (*p_fun18)(void);
    typedef p_fun18 (*p_fun19)(void);
    typedef p_fun19 (*p_fun20)(void);
    typedef p_fun20 (*p_fun21)(void);
    typedef p_fun21 (*p_fun22)(void);
    
    p_fun22 fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()()()()()()()()()()()()()()()()()()()()()()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    运行结果:
    在这里插入图片描述

    三、深究

    其实用gcc这样编译会报warning
    warning: returning ‘long long int (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* ()())())(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void)’ from a function with incompatible return type ‘a’ {aka 'long long int ( (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*)())(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void)’} [-Wincompatible-pointer-types]
    return fun;
    然后我们能看到一个比较复杂的类型,我们再次根据这个类型进行定义
    这是原始类型

    long long int (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*)())(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void);
    
    • 1

    这是我们把这个类型重命名为a

    typedef long long int (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*a)())(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void);
    
    
    • 1
    • 2

    接下来重新写一下代码

    #include 
    
    typedef long long int (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*a)())(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void);
    
    a fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()()()()()()()()()()()()()()()()()()()()()()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    发现还是能用,聪明的你能说出他的类型名吗?

    其实我们可以更疯狂一点:

    #include 
    
    typedef long long (*p_fun0)(void);
    typedef p_fun0 (*p_fun1)(void);
    typedef p_fun1 (*p_fun2)(void);
    typedef p_fun2 (*p_fun3)(void);
    typedef p_fun3 (*p_fun4)(void);
    typedef p_fun4 (*p_fun5)(void);
    typedef p_fun5 (*p_fun6)(void);
    typedef p_fun6 (*p_fun7)(void);
    typedef p_fun7 (*p_fun8)(void);
    typedef p_fun8 (*p_fun9)(void);
    typedef p_fun9 (*p_fun10)(void);
    typedef p_fun10 (*p_fun11)(void);
    typedef p_fun11 (*p_fun12)(void);
    typedef p_fun12 (*p_fun13)(void);
    typedef p_fun13 (*p_fun14)(void);
    typedef p_fun14 (*p_fun15)(void);
    typedef p_fun15 (*p_fun16)(void);
    typedef p_fun16 (*p_fun17)(void);
    typedef p_fun17 (*p_fun18)(void);
    typedef p_fun18 (*p_fun19)(void);
    typedef p_fun19 (*p_fun20)(void);
    typedef p_fun20 (*p_fun21)(void);
    typedef p_fun21 (*p_fun22)(void);
    typedef p_fun22 (*p_fun23)(void);
    typedef p_fun23 (*p_fun24)(void);
    typedef p_fun24 (*p_fun25)(void);
    typedef p_fun25 (*p_fun26)(void);
    typedef p_fun26 (*p_fun27)(void);
    typedef p_fun27 (*p_fun28)(void);
    typedef p_fun28 (*p_fun29)(void);
    typedef p_fun29 (*p_fun30)(void);
    typedef p_fun30 (*p_fun31)(void);
    typedef p_fun31 (*p_fun32)(void);
    typedef p_fun32 (*p_fun33)(void);
    typedef p_fun33 (*p_fun34)(void);
    typedef p_fun34 (*p_fun35)(void);
    typedef p_fun35 (*p_fun36)(void);
    typedef p_fun36 (*p_fun37)(void);
    typedef p_fun37 (*p_fun38)(void);
    typedef p_fun38 (*p_fun39)(void);
    typedef p_fun39 (*p_fun40)(void);
    typedef p_fun40 (*p_fun41)(void);
    typedef p_fun41 (*p_fun42)(void);
    typedef p_fun42 (*p_fun43)(void);
    typedef p_fun43 (*p_fun44)(void);
    typedef p_fun44 (*p_fun45)(void);
    typedef p_fun45 (*p_fun46)(void);
    typedef p_fun46 (*p_fun47)(void);
    typedef p_fun47 (*p_fun48)(void);
    typedef p_fun48 (*p_fun49)(void);
    typedef p_fun49 (*p_fun50)(void);
    typedef p_fun50 (*p_fun51)(void);
    typedef p_fun51 (*p_fun52)(void);
    typedef p_fun52 (*p_fun53)(void);
    typedef p_fun53 (*p_fun54)(void);
    typedef p_fun54 (*p_fun55)(void);
    typedef p_fun55 (*p_fun56)(void);
    typedef p_fun56 (*p_fun57)(void);
    typedef p_fun57 (*p_fun58)(void);
    typedef p_fun58 (*p_fun59)(void);
    typedef p_fun59 (*p_fun60)(void);
    typedef p_fun60 (*p_fun61)(void);
    typedef p_fun61 (*p_fun62)(void);
    typedef p_fun62 (*p_fun63)(void);
    typedef p_fun63 (*p_fun64)(void);
    typedef p_fun64 (*p_fun65)(void);
    typedef p_fun65 (*p_fun66)(void);
    typedef p_fun66 (*p_fun67)(void);
    typedef p_fun67 (*p_fun68)(void);
    typedef p_fun68 (*p_fun69)(void);
    typedef p_fun69 (*p_fun70)(void);
    typedef p_fun70 (*p_fun71)(void);
    typedef p_fun71 (*p_fun72)(void);
    typedef p_fun72 (*p_fun73)(void);
    typedef p_fun73 (*p_fun74)(void);
    typedef p_fun74 (*p_fun75)(void);
    typedef p_fun75 (*p_fun76)(void);
    typedef p_fun76 (*p_fun77)(void);
    typedef p_fun77 (*p_fun78)(void);
    typedef p_fun78 (*p_fun79)(void);
    typedef p_fun79 (*p_fun80)(void);
    typedef p_fun80 (*p_fun81)(void);
    typedef p_fun81 (*p_fun82)(void);
    typedef p_fun82 (*p_fun83)(void);
    typedef p_fun83 (*p_fun84)(void);
    typedef p_fun84 (*p_fun85)(void);
    typedef p_fun85 (*p_fun86)(void);
    typedef p_fun86 (*p_fun87)(void);
    typedef p_fun87 (*p_fun88)(void);
    typedef p_fun88 (*p_fun89)(void);
    typedef p_fun89 (*p_fun90)(void);
    typedef p_fun90 (*p_fun91)(void);
    typedef p_fun91 (*p_fun92)(void);
    typedef p_fun92 (*p_fun93)(void);
    typedef p_fun93 (*p_fun94)(void);
    typedef p_fun94 (*p_fun95)(void);
    typedef p_fun95 (*p_fun96)(void);
    typedef p_fun96 (*p_fun97)(void);
    typedef p_fun97 (*p_fun98)(void);
    typedef p_fun98 (*p_fun99)(void);
    typedef p_fun99 (*p_fun100)(void);
    
    p_fun100 fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115

    或者

    #include 
    
    typedef long long int (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*a)())(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void))(void);
    
    a fun()
    {
        printf("()");
        return fun;
    }
    
    int main()
    {
        fun()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    运行结果
    或者我们可以在fun()函数里面加点私货,就可以看到我们调用过多少次函数
    在这里插入图片描述

    四、复用

    这么多的代码难道你以为我是自己写的???
    还记得博主之前自己用c语言写c语言代码的博客吗?
    [C语言]关于我用C语言写C语言代码
    所以我自己又写了一个c语言来帮我写c语言代码
    下面是参考代码

    #include 
    #define M 99
    
    int main()
    {
        int i;
        printf("#include \n\n");
    
        printf("typedef long long (*p_fun0)(void);\n");
        for(i = 0 ; i <= M ; ++i)
        {
            printf("typedef p_fun%d (*p_fun%d)(void);\n", i, i+1);
        }
    
        printf("\np_fun%d fun()\n{\n", i);
        printf("    printf(\"()\");\n");
        printf("    return fun;\n}\n\n");
    
        printf("int main()\n{\n");
        printf("    fun()");
        for(i = 1 ; i <= M + 2 ; ++i)
        {
            printf("()");   
        }
        printf(";\n");
        printf("    return 0;\n}\n");
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    用连续内存空间实现线性表
    HashMap面试原理梳理-简单一看就懂
    【代码随想录】算法训练营 第一天 第一章 数组 Part 1
    CocosCreator3.8研究笔记(十三)CocosCreator 音频资源理解
    【无标题】
    03-Redis主从架构
    C专家编程 第7章 对内存的思考 7.1 Intel 80x86系列
    使用EFCore连接SQLite
    IntelliJ IDEA 安装 GitHub Copilot插件 (最新)
    网络安全(黑客)自学
  • 原文地址:https://blog.csdn.net/qq_28406527/article/details/134021020