之前写过个好玩代码
c语言返回值为函数指针的函数
一、发现
#include<stdio.h>
int (*drink(void)) (void)
{
static int i;
i++;
printf("(%d)\n", i);
return (int(*)(void))drink;
}
int main()
{
drink()();
return 0;
}
这个代码定义了一个返回值为函数指针的函数,然后就能直接调用两次函数,但这种方法对于调用三次函数来说好像不太可能。
后来我想一想,好像可以先定义一个函数指针类型,然后这样函数的定义也稍微简介一些
#include <stdio.h>
typedef long long (*p_fun)(void);
p_fun fun()
{
printf("()");
return fun;
}
int main()
{
fun()();
return 0;
}
运行结果:
二、探索
然后我又仔细想了想,是不是可以套娃,然后就有了下面的代码
#include <stdio.h>
typedef long long (*p_fun)(void);
typedef p_fun (*p_fun2)(void);
p_fun2 fun()
{
printf("()");
return fun;
}
int main()
{
fun()()();
return 0;
}
#include <stdio.h>
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;
}
运行结果:
然后我们可以一直定义函数指针类型,就可以一直循环操作下去,最终可以实现比较难懂的代码
#include <stdio.h>
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;
}
运行结果:
三、深究
其实用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 <stdio.h>
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 <stdio.h>
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 <stdio.h>
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;
}
或者我们可以在fun()函数里面加点私货,就可以看到我们调用过多少次函数
四、复用
这么多的代码难道你以为我是自己写的???
还记得博主之前自己用c语言写c语言代码的博客吗?
[C语言]关于我用C语言写C语言代码
所以我自己又写了一个c语言来帮我写c语言代码
下面是参考代码
#include <stdio.h>
#define M 99
int main()
{
int i;
printf("#include <stdio.h>\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;
}