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);}