用C语言模仿Python函数

首先得说明一点,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 <stdio.h>
 36 #include <stdlib.h>
 37 #include <unistd.h>
 38 #include <stdarg.h>
 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)都能通过简单的测试。但是可以看到,仅仅是简单的模拟,我们也得用到大量(按比例)的汇编,可读性很差,而且模拟程度非常有限,代码长度也更长。相反,对于这类一般功能的函数,Python可以很容易地模拟C语言的函数,而且模拟程度很高。

时间: 2024-07-29 13:25:32

用C语言模仿Python函数的相关文章

在Julia语言中调用Python函数

在PyCall扩展包中,模仿Python的import语句,提供了一个可以导入Python模块的@pyimport宏.并且,为能在Julia中使用模块内的函数和常量做了封装,以及支持在Julia与Python间的自动类型转换. 同时,它还提供了对Python对象进行底层操作的设施.其中包括能与不透明的Python对象相对应的'PyObjec'类型,以及在Julia语言中对Python函数进行调用且做类型转换的pycall. 安装 在Julia中,只需要使用Pkg.add("PyCall"

在使用python语言的open函数时,提示错误OSError: [Errno 22] Invalid argument: ‘文件路径’

如题,在使用python语言的open函数时,提示错误OSError: [Errno 22] Invalid argument: '文件路径',在查阅了大量资料后也得到了一些解决方案,但是这些解决方案对于作者的情况都不适用,依然报错,没办法,虽然作者的英语水平很不咋地,但中文帮不了作者,只好求助于英文了. ? ? ? ?建议各位看客在修改时,仔细看清楚自己的情况是否适用.废话不多说,开始正文. ? ? ? ?作者的路径为open('D:\LearningBooks\test.txt') ? ?

浅析python函数

慢慢的开始进入状态啦,被明老师说我什么都不会后我觉得是该反思下自己这个学期的学习了,虽然我对实验没有很大的兴趣,但是既然名老师要求我开始做实验,我就跟着小丹师姐好好学学,用Tanger师兄的话来说就是:做实验有利于你理解生物信息学数据处理的原理,也许有一天,未来做生物信息的学弟学妹会看到这段话,就像我在码迷上看到free_mao的博文一样,生物信息还是基于生物的,生物原理必须要理解,不然和做计算机有什么区别呢?以前对书本的知识不够重视,语言的学习进度很缓慢,现在希望能分享一些学习心得体会给大家,

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二部分将第一部分的示例进行扩展,展示了如何在python中调用多线程的C模块:第三部分扩展了第二部分,增加了在C模块的线程中回调python的演示. 本文所用的环境为:64位Win7 + python 3.4 x86 + vs2010 一.windows下的C语言多线程程序 windows下多线程编程

【Python之旅】第三篇(一):Python函数

说明: 使用函数可以使程序实现功能模块化,大大简洁我们的程序,这里主要讨论Python中函数的下列内容: 1.函数定义与函数参数 2.局部变量和全局变量 3.函数默认参数和关键参数 4.*Args和**Kargs 因为函数部分内容跟C语言中的很多内容都十分相似,所以会结合C语言来进行对比学习. 1.函数定义与函数参数 --基本格式1:不参参数 ·定义: def sayHi():     print "Hello!" ·调用: >>> sayHi() Hello --基

Python日志之Python函数

Python日志之Python函数: 一.认识函数 1.什么是函数 函数,function,通俗来说,函数,就是功能的意思,函数是用来封装特定功能的,比如,在Python中,len()是一个函数,len()这个函数实现的功能可能是返回一个字符串的长度,所以说len()这个函数他的特定功能就是返回长度,再比如,我们可以定义一个函数,然后编写这个函数的功能,之后要使用的时候再调用这个函数.所以函数分为两种类型,一种是系统自带的不用我们编写其功能的,比如len()这种函数,再一种就是我们自己定义的,需

正确理解Python函数是第一类对象

正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松平常了.但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性.那到底什么是第一类对象呢? 函数是对象 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性

用C语言实现python的扩展模块

用C语言实现python的扩展模块 示例1: 1 Example.c int add(int a,int b) { return a+b; } int sub(int a,int b) { return a -b; } int mul(int a,int b) { return a*b; } int div1(int a,int b) { if(0 == b) { return b; } return a/b; } 2 wrap.c include //python.h中已经包含了常用的头文件