C语言习题讲解-第九讲- 常见错误分类等
- 1. C程序常见的错误分类不包含:( )
- 2. 根据下面递归函数:调用函数 ` Fun(2) ` ,返回值是多少( )
- 3. 关于递归的描述错误的是:( )
- 4. 计算斐波那契数
- 5. 递归实现 n 的 k 次方
- 6. 计算一个数的每位之和(递归实现)
- 7. 求阶乘
- 8. 打印一个数的每一位
1. C程序常见的错误分类不包含:( )
C程序常见的错误分类不包含:()
A.编译错误
B.链接错误
C.栈溢出
D.运行时错误
答案:C
解析:
栈溢出是运行时错误的一种,因此C程序不会将栈溢出错误单独列出来,栈溢出包含在运行时错误中。
因此:选择C
2. 根据下面递归函数:调用函数 Fun(2)
,返回值是多少( )
根据下面递归函数:调用函数Fun(2),返回值是多少( )
int Fun(int n)
{ if(n==5) return 2; else return 2*Fun(n+1);
}
A. 2
B. 4
C. 8
D. 16
答案:D
解析:
Fun(2)--->返回16return 2*Fun(3) 2*8=16|__Fun(3):8return 2*Fun(4) 2*4=8|__Fun(4):4return 2*Fun(5) 2*2=4|__Fun(5):2 return 2
因此,选择D
3. 关于递归的描述错误的是:( )
关于递归的描述错误的是:( )
A.存在限制条件,当满足这个限制条件的时候,递归便不再继续
B.每次递归调用之后越来越接近这个限制条件
C.递归可以无限递归下去
D.递归层次太深,会出现栈溢出现象
答案:C
解析:
递归的两个条件:
-
将问题转化为其子问题,子问题要与原问题具有相同的解法
-
递归的出口
A:正确,限制条件即递归的出口,如果限制条件满足,递归程序就可以退出了
B:正确,因为每次递归,都是将原问题进一步缩小,缩小到限制条件时,就可以往回返,直到第一次递归调用
比如:递归求和
int Sum(int N){if(N == 1)return 1;return Sum(N-1)+N;}
假设:求 Sum(4)
的递归调用过程
Sum(4)<----| || |Sum(3)<----| || |Sum(2)<----| || |Sum(1)-----
C:错误,递归不能无限递归下去,否则会造成死循环和栈溢出
D:正确,因为每次递归,相当于都是一次新的函数调用,而每次函数调用系统必须给该函数划分栈帧空间,内部的递归函数没有退出,上层的递归就不能退出,栈帧就会累积许多块,如果累积超过栈的总大小,就会栈溢出。
4. 计算斐波那契数
递归和非递归分别实现求第n个斐波那契数
例如:
输入:5 输出:5
输入:10, 输出:55
输入:2, 输出:1
参考答案:
/*
思路:
一个问题直接求解时不好求解,如果可以将其划分成其子问题,并且子问题和原问题有相同的解法时,就可以使用递归的方式解决
递归的两个条件:1. 将问题划分成其子问题,要求:子问题要与原问题具有相同的解法2. 递归的出口1 N < 3
Fac(N) Fac(N-1) + Fac(N-2) N >= 3
*/long long Fac(int N)
{if(N < 3)return 1;return Fac(N-1) + Fac(N-2);
}
5. 递归实现 n 的 k 次方
编写一个函数实现 n 的 k 次方,使用递归实现。
参考答案:
/*
思路:1 K==0
Pow(n,K) = Pow(n, K-1)*n*/
int Pow(int n, int k)
{if(k==0)return 1;else if(k>=1){return n*Pow(n, k-1);}
}
6. 计算一个数的每位之和(递归实现)
写一个递归函数 DigitSum(n)
,输入一个非负整数,返回组成它的数字之和
例如,调用 DigitSum(1729)
,则应该返回 1 + 7 + 2 + 9,它的和是 19
输入:1729,输出:19
参考答案:
/*
思路:n n < 10
DigiSum(n) = DibiSum(n/10)+n%10 // 前n-1位之和+第N位
*/int DigitSum(int n)//1729
{if(n>9)return DigitSum(n/10)+n%10;elsereturn n;
}
7. 求阶乘
递归和非递归分别实现求 n 的阶乘(不考虑溢出的问题)
参考答案:
/*
Fac(N) = 1*2*3*……*N递归方式实现:1 N <= 1
Fac(N)Fac(N-1)*N N >= 2
*/long long Fac(int N)
{if(N <= 1)return 1;return Fac(N-1)*N;
}/*
循环方式:从1乘到N即可
*/
long long Fac(int N)
{long long ret = 1;for(int i = 2; i <= N; ++i){ret *= i;}return ret;
}
8. 打印一个数的每一位
递归方式实现打印一个整数的每一位
参考答案:
/*
思路:N N <= 9
Print(N)Print(N-1), 打印N
*/void print(unsigned int n){if(n>9)print(n/10);printf("%d ", n%10);}