热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用C语言模仿Python函数

首先得说明一点,C语言不是函数式编程语言,要想进行完全的函数式编程,还得先写个虚拟机,然后再写个解释器才行(相当于CPython)。下面我们提供一个例子,说明即便不写虚拟机,C语言函数也是可

首先得说明一点,C 语言不是函数式编程语言,要想进行完全的函数式编程,还得先写个虚拟机,然后再写个解释器才行(相当于 CPython )。

下面我们提供一个例子,说明即便不写虚拟机, C 语言函数也是可以“适度地模仿” Python 函数。

我们有如下的 Python 程序:

1 def line_conf(a, b):
2 def line(x):
3 return a*x + b
4 return line
5
6 line1 = line_conf(1, 1)
7 line2 = line_conf(4, 5)
8 print(line1(5), line2(5))
Python Code

 

我们在C程序中适度地模拟其中的line_conf函数:

  1 /* MIT License
2
3 Copyright (c) 2017 Yuandong-Chen
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE. */
22
23 ///////////////////////////////////////////////////////////////////////////////
24
25 // Note: The C program is almost equivalent to the Python program as follows:
26 // def line_conf(a, b):
27 // def line(x):
28 // return a*x + b
29 // return line
30 //
31 // line1 = line_conf(1, 1)
32 // line2 = line_conf(4, 5)
33 // print(line1(5), line2(5))
34
35 #include
36 #include
37 #include
38 #include
39
40 typedef int Func();
41
42 Func *line_conf(int x, int y,...)
43 {
44 va_list ap;
45 va_start(ap, y);
46
47 asm volatile(
48 "push %%eax\n\t"
49 "subl $40, %%esp\n\t"
50 "movl 8(%%ebp), %%eax\n\t"
51 "movl %%eax, -36(%%ebp)\n\t"
52 "movl 12(%%ebp), %%eax\n\t"
53 "movl %%eax, -40(%%ebp)\n\t"
54 "addl $40, %%esp\n\t"
55 "pop %%eax\n\t"
56 :::"memory"
57 );
58
59 if(va_arg(ap,int) == 1){
60
61 LINE:
62
63 asm volatile(
64 "push %%ebp\n\t"
65 "movl %%esp, %%ebp\n\t"
66 "movl 8(%%ebp), %%eax\n\t"
67 "imul -36(%%ebp), %%eax\n\t"
68 "addl -40(%%ebp), %%eax\n\t"
69 "movl %%ebp, %%esp\n\t"
70 "pop %%ebp\n\t"
71 "ret\n\t"
72 :::"memory","%eax"
73 );
74 }
75 __END:
76 va_end(ap);
77 return (Func *)(&&LINE);
78 }
79
80 int main(int argc, const char *argv[]){
81 printf("====TEST START====\n");
82 printf("34*234+6 ?= %d\n",line_conf(34,6)(234));
83 printf("1*3+2 ?= %d; 324*65+3 ?= %d; 13*66+2 ?= %d\n",line_conf(1,2)(3),line_conf(324,3)(65),line_conf(13,2)(66));
84
85 int fd = line_conf(1,6)(4);
86 Func *fun = line_conf(3,3);
87 int a = 1; // Limited point
88 printf("3*3+3 ?= %d; 1*4+6 ?= %d\n",fun(3),fd);
89 printf("====TEST END====\n");
90 return 0;
91 }
92
93 // Compile it by the following command:
94 // gcc -m32 -O0 -fno-stack-protector CFunctional.c; ./a.out
95 // The terminal output should looks like:
96 // ====TEST START====
97 // 34*234+6 ?= 7962
98 // 1*3+2 ?= 5; 324*65+3 ?= 21063; 13*66+2 ?= 860
99 // 3*3+3 ?= 12; 1*4+6 ?= 10
100 // ====TEST END====
101 //Note: The limitation happens between line 86 and line 88, we cannot insert any function here
102 // whose stack is larger than 40 bytes.(Why is 40? check the inline assembler language)
C Code

结果在MacOSX和Ubuntu上(i386)都能通过简单的测试。但是可以看到,仅仅是简单的模拟,我们也得用到大量(按比例)的汇编,可读性很差,而且模拟程度非常有限,代码长度也更长。

注意:这只是个玩具,别这么写代码,除非想搞破坏(充斥着各种漏洞,极易被侵入)。


推荐阅读
  • pypy 真的能让 Python 比 C 还快么?
    作者:肖恩顿来源:游戏不存在最近“pypy为什么能让python比c还快”刷屏了,原文讲的内容偏理论,干货比较少。我们可以再深入一点点,了解pypy的真相。正式开始之前,多唠叨两句 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 本文将介绍由密歇根大学Charles Severance教授主讲的顶级Python入门系列课程,该课程广受好评,被誉为Python学习的最佳选择。通过生动有趣的教学方式,帮助初学者轻松掌握编程基础。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • This document outlines the recommended naming conventions for HTML attributes in Fast Components, focusing on readability and consistency with existing standards. ... [详细]
  • Splay Tree 区间操作优化
    本文详细介绍了使用Splay Tree进行区间操作的实现方法,包括插入、删除、修改、翻转和求和等操作。通过这些操作,可以高效地处理动态序列问题,并且代码实现具有一定的挑战性,有助于编程能力的提升。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 文件描述符、文件句柄与打开文件之间的关联解析
    本文详细探讨了文件描述符、文件句柄和打开文件之间的关系,通过具体示例解释了它们在操作系统中的作用及其相互影响。 ... [详细]
  • 本教程涵盖OpenGL基础操作及直线光栅化技术,包括点的绘制、简单图形绘制、直线绘制以及DDA和中点画线算法。通过逐步实践,帮助读者掌握OpenGL的基本使用方法。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 根据最新发布的《互联网人才趋势报告》,尽管大量IT从业者已转向Python开发,但随着人工智能和大数据领域的迅猛发展,仍存在巨大的人才缺口。本文将详细介绍如何使用Python编写一个简单的爬虫程序,并提供完整的代码示例。 ... [详细]
  • Linux设备驱动程序:异步时间操作与调度机制
    本文介绍了Linux内核中的几种异步延迟操作方法,包括内核定时器、tasklet机制和工作队列。这些机制允许在未来的某个时间点执行任务,而无需阻塞当前线程,从而提高系统的响应性和效率。 ... [详细]
author-avatar
mobiledu2502877207
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有