用C语言模仿Python函数的一种简单实现方法

 更新时间:2017年05月13日 13:23:43   投稿:mrr  
这篇文章主要介绍了用C语言模仿Python函数的一种简单实现方法,需要的朋友可以参考下

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

下面我们提供一个例子,说明 C 语言函数可以“适度地模仿” Python 函数。

我们有如下的 Python 程序:

def line_conf(a, b):
  def line(x):
    return a*x + b
  return line
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))

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

/* MIT License
Copyright (c) 2017 Yuandong-Chen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. */
///////////////////////////////////////////////////////////////////////////////
// Note: The C program is almost equivalent to the Python program as follows:
// def line_conf(a, b):
//   def line(x):
//     return a*x + b
//   return line
//
// line1 = line_conf(1, 1)
// line2 = line_conf(4, 5)
// print(line1(5), line2(5))
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdarg.h>
typedef int Func();
Func *line_conf(int x, int y,...)
{ 
  va_list ap; 
  va_start(ap, y);
  asm volatile(
    "push %%eax\n\t"
    "subl $40, %%esp\n\t"
    "movl 8(%%ebp), %%eax\n\t"
    "movl %%eax, -36(%%ebp)\n\t"
    "movl 12(%%ebp), %%eax\n\t"
    "movl %%eax, -40(%%ebp)\n\t"
    "addl $40, %%esp\n\t"
    "pop %%eax\n\t"
    :::"memory"
    );
if(va_arg(ap,int) == 1){
LINE:
  asm volatile(
    "push %%ebp\n\t"
    "movl %%esp, %%ebp\n\t"
    "movl 8(%%ebp), %%eax\n\t"
    "imul -36(%%ebp), %%eax\n\t"
    "addl -40(%%ebp), %%eax\n\t"
    "movl %%ebp, %%esp\n\t"
    "pop %%ebp\n\t"
    "ret\n\t"
    :::"memory","%eax"
    );
}  
__END: 
  va_end(ap);
  return (Func *)(&&LINE);
}
int main(int argc, const char *argv[]){ 
  printf("====TEST START====\n");
  printf("34*234+6 ?= %d\n",line_conf(34,6)(234));
  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));
  int fd = line_conf(1,6)(4);
  Func *fun = line_conf(3,3);
  int a = 1; // Limited point
  printf("3*3+3 ?= %d; 1*4+6 ?= %d\n",fun(3),fd);
  printf("====TEST END====\n");
  return 0; 
}
// Compile it by the following command:
// gcc -m32 -O0 -fno-stack-protector CFunctional.c; ./a.out
// The terminal output should looks like:
// ====TEST START====
// 34*234+6 ?= 7962
// 1*3+2 ?= 5; 324*65+3 ?= 21063; 13*66+2 ?= 860
// 3*3+3 ?= 12; 1*4+6 ?= 10
// ====TEST END====
//Note: The limitation happens between line 86 and line 88, we cannot insert any function here
// whose stack is larger than 40 bytes.(Why is 40? check the inline assembler language)

结果在MacOSX和Ubuntu上(i386)都能通过简单的测试。但是可以看到,仅仅是简单的模拟,我们也得用到大量(按比例)的汇编,可读性很差,而且模拟程度非常有限,代码长度也更长。相反,对于这类一般功能的函数,Python可以很容易地模拟C语言的函数,而且模拟程度很高。

以上所述是小编给大家介绍的用C语言模仿Python函数的一种简单实现方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言。

相关文章

  • C语言图书管理系统实验

    C语言图书管理系统实验

    这篇文章主要为大家详细介绍了C语言图书管理系统实验,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C语言中读取时间日期的基本方法

    C语言中读取时间日期的基本方法

    这篇文章主要介绍了C语言中读取时间日期的基本方法,分别是time()函数和gmtime()函数的使用,注意返回值的区别,需要的朋友可以参考下
    2015-08-08
  • C++库std::flush的具体使用

    C++库std::flush的具体使用

    std::flush是C++标准库中的一个操作符,用于刷新输出流,本文主要介绍了C++库std::flush的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Qt Design Studio安装图文教程

    Qt Design Studio安装图文教程

    本文主要介绍了Qt Design Studio安装图文教程,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • VS2019+MPI配置过程的实现步骤

    VS2019+MPI配置过程的实现步骤

    本文介绍了在VS2019上配置MPI,包括下载和安装MPI、创建项目、配置属性、导入头文件和库文件、添加依赖项等步骤,具有一定的参考价值,感兴趣的可以了解一下
    2024-12-12
  • C语言圣诞树的实现示例

    C语言圣诞树的实现示例

    本篇主要介绍了C语言圣诞树的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • QSS样式表实现界面换肤功能

    QSS样式表实现界面换肤功能

    这篇文章主要介绍了QSS样式表实现界面换肤功能,对QSS样式表进行简单介绍,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-10-10
  • C++数据结构之二叉搜索树的实现详解

    C++数据结构之二叉搜索树的实现详解

    二叉搜索树作为一个经典的数据结构,具有链表的快速插入与删除的特点,同时查询效率也很优秀,所以应用十分广泛。本文将详细讲讲二叉搜索树的C++实现,需要的可以参考一下
    2022-08-08
  • 深入讲解C++中的构造函数

    深入讲解C++中的构造函数

    这篇文章主要介绍了C++中的构造函数,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C语言实现随机发扑克牌

    C语言实现随机发扑克牌

    这篇文章主要为大家详细介绍了C语言实现随机发扑克牌,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04

最新评论