文档章节

学点 C 语言(35): 函数 - 递归

涂孟超
 涂孟超
发布于 2014/09/26 15:29
字数 526
阅读 4
收藏 0

1. 递归就是: 函数自己调用自己

这是一个最简单的递归, 不过它会一直执行, 可用 Ctrl+C 终止.
#include <stdio.h>

void prn(void) {
    printf("C++Builder 2009\n");
    prn();  /* 自调用; 注意它会一直执行, 可用 Ctrl+C 终止执行 */
}

int main(void)
{
    prn();
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

2. 使用递归一定要有跳出的条件:
#include <stdio.h>

void prn(int num) {
    printf("%d\n", num);
    if (num > 0) prn(--num);  
}

int main(void)
{
    prn(9);
    getchar();
    return 0;
}

 
 
 
 
 

 

 

  

3. 实例: 翻转字符串
#include <stdio.h>

void revers(char *cs);

int main(void)
{
    revers("123456789");

    getchar();    
    return 0;
}

void revers(char *cs)
{
    if (*cs)
    { 
        revers(cs + 1);
        putchar(*cs);
    }
}

 
 
 
 
 

 

 

  

4. 实例: 阶乘
#include <stdio.h>

int factorial(int num);

int main(void)
{
    int i;
    for (i = 1; i <= 9; i++)
    printf("%d: %d\n", i, factorial(i));

    getchar();    
    return 0;
}

int factorial(int num)
{
    if (num == 1)
        return(1);
    else
        return(num * factorial(num-1));
}

 
 
 
 
 

 

 

  

5. 实例: 整数到二进制
#include <stdio.h>

void IntToBinary(unsigned num);

int main(void)
{
    IntToBinary(255); /* 11111111 */
    getchar();
    return 0;
}

void IntToBinary(unsigned num) {
    int i = num % 2;
    if (num > 1) IntToBinary(num / 2);
    putchar(i ? '1' : '0'); 
//    putchar('0' + i);  /* 可代替上面一句 */
}

 
 
 
 
 

 

 

  

6. 剖析递归:
#include <stdio.h>

void prn(unsigned n);

int main(void)
{
    prn(1);
    getchar();
    return 0;
}

void prn(unsigned n) {
    printf("%d: %p\n", n, &n);  /* A */
    if (n < 4) 
        prn(n+1);               /* B */
    printf("%d: %p\n", n, &n);  /* C */
}

 
 
 
 
 

 

 

  

本例输出效果图:



分析:
程序运行到 A, 输出了第一行.
此时 n=1, 满足 < 4 的条件, 继续执行 B 开始了自调用(接着会输出第二行); 注意 n=1 时语句 C 还有待执行.
...如此循环, 一直到 n=4, A 可以执行, 但因不满足条件 B 执行不了了; 终于在 n=4 时得以执行 C.
但此时内存中有四个函数都等待返回(分别是 n=1、2、3、4 时), 咱们分别叫它 f1、f2、f3、f4.
f4 执行 C 输出了第五行, 函数返回, 返回给 f3(此时 n=3), f3 得以继续执行 C, 输出了第六行.
f3 -> f2 -> 继续 C, 输出了第七行.
f2 -> f1 -> 继续 C, 输出了第八行, 执行完毕!

如此看来, 递归函数还是很费内存的(有时不如直接使用循环), 但的确很巧妙.

本文转载自:http://www.cnblogs.com/del/archive/2008/12/04/1347547.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
我是如何成为一名少儿编程竞赛老师的

一、起缘 2017年9月,我以前一个同事问我能不能教他小孩Theo学习编程,因为以前在同一家公司时,我那同事经常带Theo去公司,我和Theo也认识,所以我答应了。 二、编程语言 那个时候Theo 8岁,...

海天一树X
2018/10/05
0
0
使用 Haskell 将十进制数字转成罗马数字

最近一边看「Haskell 函数式编程入门」一边自学 Haskell。函数式编程对笔者这种受OOP毒害颇深(虽然我完全不会 Java,但是经常会被别人来自 Java 背景的(:」∠))的菜鸟来说,还是很难适应的...

0x11901
2018/07/01
0
0
尾递归和编译器优化

最近看到尾递归,所谓的尾递归wiki解释如下: 尾部递归是一种编程技巧。递归函数是指一些会在函数内调用自己的函数,如果在递归函数中,递归调用返回的结果总被直接返回,则称为尾部递归。尾...

长平狐
2013/03/12
241
1
初尝 Elixir,真的挺好喝的。

Contents 1. 编程就是数据转换 2. 模式匹配 3. 完善的工具,和开发规范 其实,之前从北京回来的时候,我就在考虑学习 Go 还是 Elixir。 因为现在很多的区块链项目和 docker 等虚拟技术都是用...

鹄思乱想
2018/08/21
0
0
Swift2.0语言教程之函数嵌套调用形式

Swift2.0语言教程之函数嵌套调用形式 Swift2.0语言函数嵌套调用形式 在Swift中,在函数中还可以调用函数,从而形成嵌套调用。嵌套调用的形式往往有两种:一种是在一个函数中调用其他函数;另...

大学霸
2015/07/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

新项目技术栈落地(二)——SpringMVC+Spring和SpringBoot的选择

使用SpringBoot进行项目开发已经是大势所趋,但在这里还是要说明为什么选择SpringBoot,选择SpringBoot带来的好处和SpringBoot注意的一些问题。 首先SpringBoot并不是一门新技术而是spring开...

Skqing
29分钟前
1
0
如何使用apache的ab压力测试小工具传参数

前言: windows下安装的phpstudy软件里集成的apache带了ab工具,所以可以不用单独下载。其他的操作系统下的安装或部署这里就不介绍了! 一、 使用windows的cmd进入apache的根目录,输入ab查看...

小谜弟
31分钟前
1
0
angular6.1.0 运行时报错ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected.

angular6.1.0 运行时报错ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected. node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expect......

Jack088
33分钟前
1
0
阿里面试题剖析,如何保证消息不被重复消费?

面试题 如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性? 面试官心理分析 其实这是很常见的一个问题,这俩问题基本可以连起来问。既然是消费消息,那肯定要考虑会不会重复消费...

李红欧巴
34分钟前
1
0
基于 DataLakeAnalytics 的数据湖实践

随着软硬件各方面条件的成熟,数据湖(Data Lake)已经越来越受到各大企业的青睐, 与传统的数仓实践不一样的是,数据湖不需要专门的“入仓”的过程,数据在哪里,我们就从哪里读取数据进行分析...

zhaowei121
35分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部