前言 本人在通過《C語言程式設計:現代方法(第2版)》自學C語言時,發現國內並沒有該書完整的課後習題答案,所以就想把自己在學習過程中所做出的答案分享出來,以供大家參考。這些答案是本人自己解答,並參考GitHub上相關的分享和Chegg.com相關資料。因為並沒有權威的答案來源,所以可能會存在錯誤的地 ...
前言
本人在通過《C語言程式設計:現代方法(第2版)》自學C語言時,發現國內並沒有該書完整的課後習題答案,所以就想把自己在學習過程中所做出的答案分享出來,以供大家參考。這些答案是本人自己解答,並參考GitHub上相關的分享和Chegg.com相關資料。因為並沒有權威的答案來源,所以可能會存在錯誤的地方,如有錯誤還希望大家能夠幫助指出。
第二章練習題和編程題答案
練習題
2.2節
1.建立並運行由Kernighan和Ritchie編寫的著名的“hello world”程式:
1 #include <stdio.h>
2 int main(void)
3 {
4 printf("hello world!\n");
5 }
在編譯時是否有警告信息?如果有,需要如何改進呢?
答:如果使用部分比較老的編譯器如turbo C等,會生成警告信息,指出main函數並沒有返回任何值。這是因為在聲明main函數時使用了int,表明函數會返回一個整型數值,這個數值為任意(因為main後面是void)。 但是上面的代碼中並沒有return語句,所以並不會返回任何值。加入return語句後便可消除警告。
1 /* 加入return語句後的版本 */
2 #include <stdio.h>
3 int main(void)
4 {
5 printf("Hello world!\n");
6 return 0;
7 }
如果是使用IDE中的編譯器,且IDE版本比較新(如本人目前使用的Code:Blocks)即使沒有return語句,編譯器也不會生成警告信息。
2.思考下麵的程式:
1 #include <stdio.h> 2 int main(void) 3 { 4 printf("Parkinson's Law:\nWork expands so as to "); 5 printf("fill the time\n"); 6 printf("available for its completion.\n"); 7 return 0; 8 }
(a)請指出程式中的指令和語句。
(b)程式的輸出是什麼?
答:(a)給出的程式中有一個指令#include和三條printf語句和一條return語句組成。
(b)程式的輸出結果為
Parkinson's Law:
Work expands so as to fill the time
available for its completion.
2.4節
3.通過下列方法縮寫程式dweight.c: (1)用初始化式替換對變數height、length和width的賦值;(2)去掉變數weight,在最後的printf語句中計算(volume + 165)/ 166。
答:
1 #include <stdio.h> 2 int main(void) 3 { 4 /* 用初始化替代對變數賦值就是在聲明變數時直接為其賦值 */ 5 int height = 8, length = 12, width = 10, volume = height * length * width; 6 printf("Dimensions: %dx%dx%d\n", length, width, height); 7 printf("Volume (cubic inches): %d\n", volume); 8 /* 此處則省略原來對於weight,並將計算公式直接放入printf語句中 */ 9 printf("Dimensional weight (pounds): %d\n", (volume + 165) / 166); 10 return 0; 11 }
4.編寫一個程式來聲明幾個int型和float型變數,不對這些變數進行初始化,然後直接顯示它們的值。這些值是否有規律?(通常情況下沒有)。
答:
1 #include <stdio.h> 2 int main(void) 3 { 4 int a, b, c; 5 float e, f, g; 6 printf("a:%d\nb:%d\nc:%d\ne:%f\n%f:f\ng:%f\n"a, b, c, d, e, f, g); 7 return 0; 8 }
實際上並沒有什麼規律,上面這些變數既沒有被初始化也沒有在程式中被賦值,這時變數被顯示出來的值取決於許多因素,所以無法確定最終顯示的結果。
2.7節
5.判斷下列C語言標識符哪些不是合法的?
(a) 100_bottles
(b) _100_bottles
(c) one_hundred_bottles
(d) bottles_by_the_hundred_
答:不合法的標識符只有(a),因為標識符只能以字母或下劃線開頭,而100_bottles是以數字開頭的,所以不會發。另外C語言還規定了下劃線後跟一個大寫字母是保留字,不應該在程式中使用(書中後面有提及)。
6.為什麼說在標識符中使用多個相鄰的下劃線(如current___balance)不太合適?
答:因為在閱讀程式時很難分清到底有幾個相鄰的下劃線,如current____balance和current_____balance,前者是4個下劃線後者是5個下劃線。在未來維護程式時不論是編寫者本人還是他人,都容易弄混下劃線的數量,造成不必要的混亂。
7.判斷下列哪些是C語言的關鍵字?
(a) for
(b) If
(c) main
(d) printf
(e) while
答:只有(a)for和(e)while是關鍵字,其餘全都不是。(b) If 是因為C語言區分大小寫,所以If和if並不相同,if是關鍵字但是If不是。(c)main和(d)printf也不是關鍵字,main()函數是C語言自動調用的函數,但是我們依舊可以將變數命名為main(不建議這樣做)。printf()則是我們頭文件<stdio.h>內包含的函數,如果不調用這個頭文件那麼我們一樣可以將變數命名為printf。總的來說只有在關鍵字表裡的單詞才是關鍵字,其餘都不是關鍵字。
2.8節
8.下麵的語句中有多少個記號?
answer=(3*q-p*p)/3;
答:14個記號,分別是answer、=、(、3、*、q、-、p、*、p、)、/、3、;。
9.在練習題8的記號之間插入空格,使該語句更易於閱讀。
答:answer = (3 * q - p * p) / 3;
10.在dweight.c程式(2.4節)中,哪些空格是必不可少的?
答:程式當中出現兩次的int後面空格不能少,return 0; 中間的空格不能少。程式其他部分的空格都是為了易於閱讀而存在的,即使可去掉程式本身依舊能夠正常執行,只是增加了閱讀困難。
編程題
1.編寫一個程式,使用printf在屏幕上顯示下麵的圖形:
*
*
*
* *
* *
*
答:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 printf(" *\n"); 6 printf(" *\n"); 7 printf(" *\n"); 8 printf("* *\n"); 9 printf(" * *\n"); 10 printf(" *\n"); 11 12 return 0; 13 }
2.編寫一個計算球體體積的程式,其中球體半徑為10m,參考公式v=4/3πr ³。註意,分數4/3應寫為4.0f/3.0f。(如果分數寫成4/3會產生什麼結果?)提示:C語言沒有指數運算符,所以需要對r自乘兩次來計算r ³。
答:
1 #include <stdio.h> 2 /* 定義名為PI和SCALE_FACTOR的巨集 */ 3 #define PI 3.14f 4 #define SCALE_FACTOR 4.0f/3.0f 5 6 int main(void) 7 { 8 9 /* 聲明變數並對其初始化,r是半徑,volume為計算結果,r_3是r的立方結果 */ 10 float r = 10.0f; 11 float volume = 1.0f; 12 float r_3 = 0.0f; 13 14 /* 計算半徑為10m的球體體積 */ 15 r_3 = r*r*r; 16 volume = SCALE_FACTOR * PI * r_3; 17 18 /* 顯示結果 */ 19 printf("Result is:%f\n", volume); 20 21 return 0; 22 }
如果把分數4.0f/3.0f編程4/3,則會導致計算結果出現錯誤,因為4/3的結果是1,而不是1.33333333。C語言中整數相除會舍掉後面的小數。
3.修改上題中的程式,使用戶可以自行錄進球體的半徑。
答:
1 #include <stdio.h> 2 /* 定義名為PI和SCALE_FACTOR的巨集 */ 3 #define PI 3.14f 4 #define SCALE_FACTOR 4.0f/3.0f 5 6 int main(void) 7 { 8 9 /* 聲明變數並對其初始化,r是半徑,volume為計算結果,r_3是r的立方結果 */ 10 float r = 1.0f; 11 float volume = 1.0f; 12 float r_3 = 0.0f; 13 14 /* 輸進球體半徑,註意變數r前面要有&符號 */ 15 printf("Enter number:"); 16 scanf("%f", &r); 17 18 /* 計算半徑為10m的球體體積 */ 19 r_3 = r*r*r; 20 volume = SCALE_FACTOR * PI * r_3; 21 22 printf("Result is:%f\n", volume); 23 24 return 0; 25 }
4.編寫一個程式,要求用戶輸入一個美元數量,然後顯示出增加5%稅率後的相應金額。格式如下所示:
Enter an amount: 100.00
With tax added: $105.00
答:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 /* 聲明變數money和taxed_money並初始化,前者表示金額,後者表示稅後的金額 */ 6 float money = 0.0f; 7 float taxed_money = 0.0f; 8 9 /* 金額錄入 */ 10 printf("Enter an amount:"); 11 scanf("%f", &money); 12 13 /*計算稅後的金額 */ 14 taxed_money = money * 1.05; 15 16 /*顯示結果,使用.2f是因為題目中稅後的金額只保留了兩位小數 */ 17 printf("With tax added: $%.2f\n", taxed_money); 18 19 return 0; 20 }
5.編寫要求用戶輸入x的值,然後顯示如下多項式的值:
3x5+2x4-5x3-x2+7x-6
提示:C語言沒有指數運算符,所以需要對x進行自乘來計算其冪。(例如,x*x*x就是x的三次方。)
答:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 /* 聲明並初始化變數x和計算結果result,選擇float型是因為題目中沒有說用戶不能輸入小數 */ 6 float x = 0.0f; 7 float result = 0.0f; 8 9 /* 用戶輸入x的值,然後將值寫入變數x中 */ 10 printf("Enter the value of x:"); 11 scanf("%f", &x); 12 13 /* 計算公式的結果 */ 14 result = 3 * x * x * x * x * x + 2 * x * x * x * x - 5 * x * x * x -x * x + 7 * x - 6; 15 16 printf("The result is: %f", result); 17 18 return 0; 19 }
6.修改上題,用如下公式對多項式求值:
((((3x+2)x-5)x-1)x+7)x-6
註意,修改後的程式所需的乘法次數減少了。這種多項式求值方法即Horner法則(Horner's Rule)。
答:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 float x = 0.0f; 6 float result = 0.0f; 7 8 printf("Enter the value of x:"); 9 scanf("%f", &x); 10 11 /* 修改後的計算公式 */ 12 result = ((((3 * x + 2)* x - 5)* x - 1)* x + 7)* x - 6; 13 14 printf("The result is: %f", result); 15 16 return 0; 17 }
7.編寫一個程式,要求用戶輸入一個美元數量,然後顯示出如何用最少的20美元、10美元、5美元和1美元來付款:
Enter a dollar amount: 93
$20 bills:4
$10 bills:1
$5 bills:0
$1 bills:3
答:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 /* 聲明並初始化金額總數amount和美元面額變數 */ 6 int amount = 0; 7 int b20 = 0, b10 = 0, b05 = 0, b01 = 0; 8 9 printf("Enter a dollar amount:"); 10 scanf("%d", &amount); 11 12 /* 因為要求是用最少張數付款,所以先用總金額除以20,得到的所需20美元的數量,再將總金額減去所需20美元後除以10,得到所需10美元數量,以此類推求出全部結果 */ 13 b20 = amount / 20; 14 amount = amount - 20 * b20; 15 b10 = amount / 10; 16 amount = amount - 10 * b10; 17 b05 = amount / 5; 18 amount = amount - 5 * b05; 19 b01 = amount / 1; 20 21 /* 顯示結果 */ 22 printf("\n$20 bills:%d\n$10 bills:%d\n $5 bills:%d\n $1 bills:%d\n", b20, b10, b05, b01); 23 24 return 0; 25 }
8.編程計算第一、第二、第三個月還貸後剩餘的貸款金額:
Enter amount of loan: 20000.00
Enter interest rate:6.0
Enter monthly payment:386.66
Balance remaining after first payment:$19713.34
Balance remaining after second payment:$19425.25
Balance remaining after third payment:$19135.71
在顯示每次還款後的餘額時要保留兩位小數。提示:每個月的貸款餘額減去還款金額後,還需要加上貸款餘額與月利率的乘積。月利率的計算方法是把用戶輸入的利率轉換成百分數再除以12。
答:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 /* 聲明並初始化變數,loan是貸款金額,y_inter是年利率,m_inter月利率,m_pay是每月還款金額 */ 6 float loan = 0.0f; 7 float y_inter = 0.0f; 8 float m_inter = 0.0f; 9 float m_pay = 0.0f; 10 11 /* 用戶輸入貸款金額、年利率、月還款數 */ 12 printf("Enter amount of loan: "); 13 scanf("%f", &loan); 14 printf("Enter interest rate: "); 15 scanf("%f", &y_inter); 16 printf("Enter monthly payment: "); 17 scanf("%f", &m_pay); 18 19 /* 計算月利率,加1是因為如果直接是月利率乘以貸款金額得到的是利息,利息還要在加上貸款金額。加1之後可以直接求出貸款金額加利息後的結果 */ 20 m_inter = y_inter / 100 / 12 + 1; 21 22 /* 求出第一個月還款之後的剩餘金額 */ 23 loan = loan * m_inter - m_pay; 24 printf("Balance remaining after first payment: %.2f\n", loan); 25 26 /* 求出第二個月還款之後的剩餘金額 */ 27 loan = loan * m_inter - m_pay; 28 printf("Balance remaining after second payment: %.2f\n", loan); 29 30 /* 求出第三個月還款之後的剩餘金額 */ 31 loan = loan * m_inter - m_pay; 32 printf("Balance remaining after third payment: %.2f\n", loan); 33 34 return 0; 35 } 36 /* 題目中還款是等額本息的方式,貸款20000,年利率6%,一共貸款5年 */