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

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

一、发现

#include

int (*drink(void)) (void)
{
    static int i;
    i++;
    printf("(%d)\n", i);
    return (int(*)(void))drink;
}

int main()
{
    drink()();
    return 0;
}

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

#include 

typedef long long (*p_fun)(void);

p_fun fun()
{
    printf("()");
    return fun;
}

int main()
{
    fun()();
    return 0;
}

运行结果:
[c语言]深入返回值为函数指针的函数_第1张图片

二、探索

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

#include 

typedef long long (*p_fun)(void);
typedef p_fun (*p_fun2)(void);

p_fun2 fun()
{
    printf("()");
    return fun;
}

int main()
{
    fun()()();
    return 0;
}
#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;
}

运行结果:
[c语言]深入返回值为函数指针的函数_第2张图片

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

#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;
}

运行结果:
[c语言]深入返回值为函数指针的函数_第3张图片

三、深究

其实用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);

这是我们把这个类型重命名为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);

接下来重新写一下代码

#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;
}

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

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

#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;
}

或者

#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;
}

[c语言]深入返回值为函数指针的函数_第4张图片
或者我们可以在fun()函数里面加点私货,就可以看到我们调用过多少次函数
[c语言]深入返回值为函数指针的函数_第5张图片

四、复用

这么多的代码难道你以为我是自己写的???
还记得博主之前自己用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;
}

你可能感兴趣的:(就是玩,C语言,c语言,1024程序员节)