测试题:
0. 除了“山上有座庙,庙里有个小和尚和老和尚……”这个故事之外,你还听过哪些与递归相关的故事?
答:放牛娃的故事
1. 就程序来说,递归实现的本质是什么?
答:调用本身
答案:函数调用自身的行为。
2. 确保递归程序不崩溃的前提是什么?
答:有退出机制
答案:设置至少一个结束递归的条件。这很重要,否则递归程序会一直走下去,直到崩溃。
3. 请至少列举使用递归的三个缺点?
答:1、占用内存 2、容易出bug 3、不易理解程序
答案:递归的执行效率通常比迭代低很多,所以递归程序要更消耗时间;由于递归函数是不断调用函数本身,在最底层的函数开始返回之前,程序都是一致在消耗栈空间的,所以递归程序要“吃”更多的内存空间;递归的结束条件设置非常重要,因为一旦设置错误,就容易导致程序万劫不复(崩溃)。
4. 如果不上机,你能看出下面代码会输出什么吗?
#include <stdio.h>
void up_and_down(int n);
void up_and_down(int n)
{
printf("%d ", n);
if (n > 0)
{
up_and_down(--n);
}
printf("%d ", n);
}
int main(void)
{
int n;
printf("请输入一个整数:");
scanf("%d", &n);
up_and_down(n);
putchar('\n');
return 0;
}
用户输入的整数是:5
答:5 4 3 2 1 0(错误)
答案:如下图
动动手:
0. 编写一个程序,反向打印用户输入的英文句子。
程序实现如下:
答:
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
int num,i;
printf("请输入依据以感叹号结尾的英文句子:");
fgets(str,100,stdin);
num = strlen(str);
for(i=num;i>=0;i--)
{
printf("%c",str[i]);
}
}
答案:
#include <stdio.h>
void getInput();
void getInput()
{
int ch;
if ((ch = getchar()) != '!')
{
getInput();
}
else
{
printf("反向输出:");
}
putchar(ch);
}
int main(void)
{
printf("请输入一句以感叹号结尾的英文句子:");
getInput();
putchar('\n');
return 0;
}
1. 编写一个程序,用递归实现斐波那契数列。
斐波那契数列定义如下:第一个和第二个数字都是 1,而后续的每个数字时其前两个数字之和。所以,斐波那契数列的前 10 个数字就是 1, 1, 2, 3, 5, 8, 13, 21, 34 和 55。
程序实现如下:
答:对照答案,写了一遍
#include <stdio.h>
int num_flag = 0;
unsigned int fibonacc(unsigned int n)
{
num_flag++;
if(n == 1 || n == 2)
{
return 1;
}
else
{
return fibonacc(n-1) + fibonacc(n-2);
}
}
int main()
{
unsigned int number, i;
printf("请输入一个整数:");
scanf("%u", &number);
printf("斐波那契数列的前%d个数字是:",number);
for(i=1;i<=number;i++)
{
printf("%2u",fibonacc(i));
printf("\n");
}
printf("程序调用%d次 fibonacc 函数",num_flag);
return 0;
}
答案:
#include <stdio.h>
unsigned int fibonacci(unsigned int n);
unsigned int fibonacci(unsigned int n)
{
if (n == 1 || n == 2)
{
return 1;
}
else
{
return fibonacci(n-1) + fibonacci(n-2);
}
}
int main(void)
{
unsigned int number, i;
printf("请输入一个整数:");
scanf("%u", &number);
printf("斐波那契数列的前 %d 个数字是:", number);
for (i = 1; i <= number; i++)
{
printf("%lu ", fibonacci(i));
}
putchar('\n');
return 0;
}
进一步思考:递归是否真的很浪费资源呢?我们不妨在代码中插入一个全局变量,用于统计 fibonacci 函数到底调用了多少次,结果令人咋舌……X
计算前 10 个斐波那契数值要调用 276 次函数,而计算前 15 个竟然需要 3177 次函数……a
不夸张的讲,如果你用迭代来实现斐波那契数列,效率至少可以提高几十万倍!
2. 编写一个程序,用递归实现将一个十进制的正整数转换成二进制的形式显示。
参考资料:
程序实现如下:
答:不会
答案:
#include <stdio.h>
void binary(unsigned long n);
void binary(unsigned long n)
{
int r;
r = n % 2;
if (n >= 2)
{
binary(n / 2);
}
putchar('0' + r); // '0' + 1 == '1'
}
int main(void)
{
unsigned long number;
printf("请输入一个正整数:");
scanf("%lu", &number);
binary(number);
putchar('\n');
return 0;
}
SF1a!Gs3dg#yv&.P^'QNt
T{:}fxA ^#~lvsUF!Z;Ydj)HpRkP