目录

介绍

概述

编程语言如何实现普通函数调用

编程语言如何实现带返回值的函数调用

递归

课后作业

附录


如果你要理解递归,首先你要理解递归.

介绍

我尝试写些关于编程语言的东西. 目前刚开始写,还把握不住严谨(数学上的)和易懂(语言上的)的边界. 我会不断润色,找到那个度. 你有问题就可以给我说.

递归是程序设计中的重要部分, 比如解析文件. 但是

一般的文章或者书籍都是通过介绍和例子来引入概念,没有做到知其所以然.

本文尝试通过引入编程语言的设计和实现来帮助理解递归.

概述

计算机是如何实现函数调用的? 一句话就是保存当前信息, 然后跳入函数中执行, 最后再从此函数返回. 高级的编程语言无非就是在模拟汇编语言执行函数调用的过程. 只是中间这个过程是通过编译器自动转换了.

那问题来了,函数可不可以调用自身?当然可以, 一般情况下,进入新的函数,会在内存中开辟一个新的栈帧来存放数据. 如果调用过深,那么进程的地址空间就不够存这些栈帧了,那么就会栈溢出.

我们今天主要来研究编程语言是怎么实现函数调用,进而理解递归.

编程语言如何实现普通函数调用

为了更好地展示,我们用个Python的例子来解释.例子就是递归打印1-10.

def recursive_print(n):if n == 1:print(n)else:recursive_print(n-1)print(n)recursive_print(10)

发生函数调用时, 进程会保存当前上下文,并创建栈来保存函数的变量.假设当前函数调用是recursive_print(5), 当前栈保存有{n=5}. 你即将进入函数recursive_print(4), 此时创建一个新的栈并存有数据{n=4}.

由此可以看到, 什么递归不递归的,只要是函数调用,只要把相关变量信息保存下来进行函数调用.计算机才不在乎.

编程语言如何实现带返回值的函数调用

如果你理解普通函数调用,带返回值的无非就是约定个地方,然后父函数从这个位置把值取到.

我随便找个x86 CPU的说明:

The caller can expect to find the return value of the subroutine in the register RAX.

给个例子:

def factorial(n):if n == 1:return 1else:return n*factorial(n-1)print(factorial(10))

递归

如果理解上述问题,递归就可以理解为普通函数调用,只是每次调用传入的变量的值可能不一样.

计算机很傻,你给他相关的信息就行,他不关系其他的.

课后作业

  1. 你如何理解二叉树上的递归? 或者说现在可以理解吗?
  2. Haskell语言不存在while语句,如果有兴趣可以尝试用haskell编写上述两个例子.你会更好理解递归.
  3. 如果让你创造一门语言,比如mocca语言(最近疯狂喝这个),你会怎么模拟函数调用?用到哪些数据结构?

附录

The 64 bit x86 C Calling Convention

从编程语言设计的角度理解递归相关推荐

  1. 视频教程-C语言-从汇编角度理解C语言的本质-C/C++

    C语言-从汇编角度理解C语言的本质 擅长JavaWeb开发,游戏逆向外挂与反外挂,游戏保护对抗 孙冉 ¥49.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅 ...

  2. 读不懂Spring源码不要紧,今天从架构设计的角度先了解下底层逻辑

    前言 为什么需要Spring? 什么是Spring? 对于这样的问题,大部分人都是处于一种朦朦胧胧的状态,说的出来,但又不是完全说的出来,今天我们就以架构设计的角度尝试解开Spring的神秘面纱. 本 ...

  3. 斯坦福大学马腾宇:无法理解现有的深度学习算法?那就设计一个能理解的

    2020-01-22 05:41:34 作者 | 丛末 编辑 | Camel 本科毕业于清华姚班.博士毕业于普林斯顿大学,师从 Sanjeev Arora 教授,马腾宇作为 AI 学界一颗冉冉升起的新 ...

  4. python语言的理解-使用Python语言理解递归

    递归 一个函数在执行过程中一次或多次调用其本身便是递归,就像是俄罗斯套娃一样,一个娃娃里包含另一个娃娃. 递归其实是程序设计语言学习过程中很快就会接触到的东西,但有关递归的理解可能还会有一些遗漏,下面 ...

  5. 谷歌Deep Bootstrap Framework:在线优化角度理解神经网络

    The Deep Bootstrap Framework: Good Online Learners are Good Offline Generalizers(ICLR21) 一元@炼丹笔记 理解深 ...

  6. python递归详解_Python理解递归的方法总结

    递归 一个函数在执行过程中一次或多次调用其本身便是递归,就像是俄罗斯套娃一样,一个娃娃里包含另一个娃娃. 递归其实是程序设计语言学习过程中很快就会接触到的东西,但有关递归的理解可能还会有一些遗漏,下面 ...

  7. 从另一个角度理解分布式系统与CAP定理

    从另一个角度理解分布式系统与CAP定理 参考:性能之殇(七)-- 分布式计算.超级计算机与神经网络共同的瓶颈 分布式计算的本质 分布式系统的产生,来源于源于人们日益增长的性能需求与落后的x86架构之间 ...

  8. 以吃货的角度理解 IaaS,PaaS,SaaS 是什么

    转载自 以吃货的角度理解 IaaS,PaaS,SaaS 是什么 随着云计算时代的到来,越来越多的软件,开始采用云服务.越来越多的概念也随之而来.云服务只是一个统称,可以分成三大类. IaaS:基础设施 ...

  9. Python Turtle画分形树理解递归

    递归思想 递归可以把一个复杂问题转化为一个与原问题相似的规模较小的问题,通过自己调用自己,找到最终解决这个问题的条件,达到判断条件时返回. 通过分形树理解递归 Python中的 turtle画图很方便 ...

最新文章

  1. 电脑文档提示无法连接服务器,提示无法将数据库连接到SQL服务器-工业支持中心-西门子中国...
  2. dotnetbar buttonx去除按钮浮动样式_精致好用 去除毛球——大宇毛球修剪器体验
  3. 数论基础-小白学算法必学(一天一夜的成果)万字
  4. 授人以鱼不如授人以渔——CPU漏洞的Symantec解决之道
  5. 爬楼梯与路径类题目记忆化递归与动态规划双解法(Leetcode题解-Python语言)
  6. python中pop用法_Python Set pop()用法及代码示例
  7. 1.11 超过人的表现
  8. 在论坛中出现的比较难的sql问题:14(存储过程问题)
  9. dwz中的table
  10. java并发编程(1)--线程 可见性 volatile怎么用
  11. 2018美赛D翻译从汽油驾驶到 E 驾驶( E 指电,而不是空)
  12. Ubuntu16.04 安装搭建RED5流媒体服务器
  13. php时间格式转换成时间戳,php怎么把时间格式转换为时间戳?
  14. 中国城市云计算首站现场会成都隆重举行
  15. mysql中输出100内质数_SQL 打印 100 以内的质数
  16. VMware Workstation虚拟机环境下Xubuntu系统如何设置中文
  17. 财富管理技术服务商NewBanker完成千万级美元 Pre-C 轮融资...
  18. latex添加背景图片
  19. MFC入门(三)-- MFC图片/文字控件(循环显示文字和图片的小程序)
  20. Pta——敲笨钟,制定位置输出字符串

热门文章

  1. 实现html语句的循环
  2. Nordic芯片如何达到最快的蓝牙传输速率
  3. sigaction函数中关于sa_mask的解释
  4. 牛人教你读文献! 学习了!
  5. mysql TIMESTAMP 不能为NULL
  6. VS2008安装盘整合sp1补丁
  7. 采用UltraISO软碟通制作UbuntuU盘启动盘教程
  8. git更新pull不下来代码_git pull更新错误解决办法
  9. 语法基础——PHP语法基础
  10. D3.js中国地图下钻 1