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

news2024/11/18 15:50:07

之前写过个好玩代码
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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1129244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础入门例程11-NP11 单词的长度

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解答&#xff1a; 说明&#xff1a; 描述 牛妹正在学英语&#xff0c;但是背单词实在是太痛苦了&#xff0c;她想让你帮她写一个小程序&#xff0c;能够根据输入的单词&#xff0c;快速得到单词的长度。 输…

测试C#调用Windows Media Player组件

新建基于.net framework的Winform项目&#xff0c;可以通过添加引用的方式选择COM组件中的Windows Media Player组件&#xff0c;如下图所示&#xff1a;   也可以在VS2022的工具箱空白处点右键&#xff0c;选择“选择项…”菜单。   在弹出的选择工具箱项窗口中&#xf…

多线程环境下的原子性问题

什么是原子性呢? 在数据库事务的ACID特性中就有原子性&#xff0c;它是指当前操作中包含的多个数据库事务操作&#xff0c;要么全部成功&#xff0c;要么全部失败&#xff0c;不允许存在部分成功、部分失败的情况。而在多线程中的原子性与数据库事务的原子性相同&…

WPS中图的自动编号及引用

WPS中图的自动编号及引用 图的自动编号图编号的引用图编号及引用的更新 图的自动编号 将光标放置在需要插入编号的位置点击“引用”→“题注”&#xff1a; 点击“引用”→“题注”&#xff1a; 点击“编号”&#xff0c;设置图的编号格式&#xff0c;可勾选“包含章节编号”&…

【RTOS学习】信号量 | 互斥量 | 递归锁

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《RTOS学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 信号量 | 互斥量 | 递归锁 &#x1f37a;信号量&#x1f964;原理&#x1f964;使用信号量的函数&…

Java反射获取内部类方法

Java反射获取内部类方法 结论一、案例准备二、测试方法&#xff1a;使用反射获取类的成员内部类和方法具体操作具体操作&#xff08;使用getDeclaredClasses&#xff09; 结论 Java 通过反射可以获得内部类&#xff0c;包括内部类属性信息和方法。 一、案例准备 创建了一个类…

1024,向着“顶尖程序员“迈进

10月24日&#xff0c;对每个程序员而言&#xff0c;都是一个具有特殊意义的日子。1024这个数字&#xff0c;不再只是计算机存储容量的基础单位&#xff0c;更是我们向着技术巅峰进发的象征。 回顾我的程序员之路&#xff0c;那是一个不断学习、不断成长的过程。起初是对编程充…

『第二章』这只燕子很特别:Swift 特性

在本篇博文中,您将学到如下内容: 1. Swift 语言概览2. Objective-C “练废了”&#xff0c;重新写一门新语言吧&#xff01;3. Swift 的“习性”与优势3.1. Swift 更简洁、更易于阅读、所需代码更少3.2. Swift 更加安全3.3. Swift 内存管理更加统一3.4. Swift 更快3.5. Swift 会…

Redis主从模式(二)---拓扑结构及复制过程

目录 一, Redis主从模式下的复制拓扑结构 1.1 一主一从结构 1.2 一主多从结构 1.3 树形主从结构 二, 主从复制过程 2.1 主从复制建立复制流程图 2.2 数据同步(psyc) 1.replicationid/replid (复制id) 2.offset(偏移量) 2.3 psync运行流程 2.4 全量复制 2.5 部分复制…

Opencv-图像插值与LUT查找表

图像像素的比较 白色是255&#xff0c;黑色是0 min(InputArray src1,InputArray src2,OutputArray dst) max(InputArray src1,InputArray src2,OutpurArray dstsrc1:第一个图像矩阵&#xff0c;通道数任意src2&#xff1a;第二个图像矩阵&#xff0c;尺寸和通道数以及数据类型…

【C++面向对象】5. this指针

文章目录 【 1. 基本原理 】【 2. 实例 】 【 1. 基本原理 】 在 C 中&#xff0c;只有成员函数才有 this 指针&#xff08;友元函数没有 this 指针&#xff0c;因为友元不是类的成员&#xff09;&#xff0c;this 指针是所有成员函数的隐含参数。 在成员函数内部&#xff0c;…

用*画田字形状,numpy和字符串格式化都可以胜任

numpy的字符型元素矩阵&#xff0c;可以方便画&#xff1b;直接python字符串手撕&#xff0c;也可以轻巧完成。 (本笔记适合熟悉循环和列表的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《…

【WinForm详细教程一】WinForm中的窗体、Label、TextBox及Button控件、RadioButton和CheckBox、ListBox

文章目录 1.WinForm文件结构2. 窗体的常用属性、方法与事件2.1 常用属性&#xff08;可直接在属性中设置&#xff09;2.2 常用方法2.3 常用事件 3.Label、TextBox及Button控件4.RadioButton和CheckBox5.ListBox&#xff08;列表框&#xff09; 1.WinForm文件结构 .sln文件 &am…

IEEE754 标准存储浮点数

1. IEEE754 标准简介 IEEE754 标准是一种用于浮点数表示和运算的标准&#xff0c;由国际电工委员会&#xff08;IEEE&#xff09;制定。它定义了浮点数的编码格式、舍入规则以及基本的算术运算规则&#xff0c;旨在提供一种可移植性和一致性的方式来表示和处理浮点数 IEEE754 …

浅谈电力电容器的故障处理及选型

安科瑞 华楠 【摘要】常见的电力电容器都是为了改善电力系统的电压质量和提高输电线路的输电能力&#xff0c;它们在减少系统功率损耗、提高功率因数、降低运行电流、提升电网电压、释放变压器使用裕度等方面有着显著效果。按电压等级可以划分高、低压两部分。虽然它们可以起着…

Vue mixin混入

可以把多个组件中共有的配置提取出来构成一个混入。 一、配置混入 &#xff08;一&#xff09; 创建mixin.js 这里的名字可以自定义&#xff0c;但是为了方便识别&#xff0c;多数场景下都写mixin。 mixin.js 要创建在src目录下&#xff0c;与main.js平级&#xff1a; &…

win10启动venv报错:无法加载文件 venv\Scripts\activate.ps1,因为在此系统上禁止运行脚本。

背景&#xff1a; 最近需要用到python开发&#xff0c;切换虚拟环境时&#xff0c;在win10系统上安装编辑器后创建了虚拟环境&#xff0c;但是执行activate时报错&#xff1a;.\venv\Scripts\activate&#xff0c;报错内容如题&#xff1a; 无法加载文件 venv\Scripts\activa…

HTTPSConnectionPool(host=‘huggingface.co‘, port=443)解决

huggingface&#xff0c;也就是抱抱脸&#xff0c;应该都很熟悉了吧 好用是很好用&#xff0c;就是有一个问题&#xff0c;国内的IP地址总是不灵是吧 今天我就碰到这么个问题 请看图&#xff1a; 。。。。图找不到了&#xff0c;我的问题忘记记录了 我给你们贴上文字吧 (M…

reactNative导入excel文件

组件内导入 import {TouchableOpacity,PermissionsAndroid} from react-native; import RNFS from react-native-fs; import XLSX from xlsx; import DocumentPicker from react-native-document-picker; import {Buffer} from buffer;// 需要安装一下三个,Buffer和react-nati…

Standford Compiler Course Assignment 2

第二部分的作业是语法分析&#xff0c;通过编写cool.y(这个assignment的任务)&#xff0c;利用bison将其自动生成语法分析LALR(1)的代码。 语法分析&#xff0c;就是将词法分析阶段已经识别好的token&#xff0c;按照语法的规则&#xff0c;构建抽象语法树的过程。 比如以下的…