Title: C 語言教學手冊 第四版
Auther: 洪維恩
Publisher: 旗標出版股份有限公司
Introduction:
- 循序漸進從頭打好 C 語言基礎
- 豐富範例展示語法最容易理解
- 每章附有自我評量教學最適用
- 資料結構基本觀念導入最易懂
※ 習題練習的作業系統為 Microsoft Windows 7/10 x64,並採用軟體 Dev-C++ 5.0.0.5 為開發工具。
※ 原諒我題目內不附圖示。
※ 請留意,文中數學公式在瀏覽器頁面中可能無法正確顯示。
※ 圖書封面、圖書資訊、章節內容、習題皆為版權作者、出版商所有,本站所刊內容僅供教育、學習使用。
- C 語言教學手冊 第四版(習題個人解答)
- Abstract
- Table of Contents
- Chapter 01 -- 認識 C 語言
- Chapter 02 -- C 語言基本概述
- Chapter 03 -- 基本資料型態
- Chapter 04 -- 格式化的輸出與輸入
- Chapter 05 -- 運算子、運算式與敘述
- Chapter 06 -- 選擇性敘述
- Chapter 07 -- 迴圈
- Chapter 08 -- 函數
- Chapter 09 -- 陣列與字串
- Chapter 10 -- 指標
- Chapter 11 -- 結構與其他資料型態
- Chapter 12 -- 檔案處理
- Chapter 13 -- 大型程式的發展
- Chapter 14 -- 動態記憶體配置與鏈結串列
- Chapter 15 -- 位元處理
- Chapter 16 -- 邁向 C++ 之路
- C 語言概述
- 程式的規劃與實作
- 撰寫第一個 C 程式
- 編譯與執行的過程
- 本書的編排與慣例
試修改 prog1_1,使得它可以印出 "
我愛C語言
" 一行中文字。
試修改 prog1_1,使得它可以印出 "
我愛C語言
" 及 "這是我的第一個C語言程式
"兩行中文字。
試撰寫一程式,利用
printf()
函數印出下面的圖案(不須使用迴圈,每一列星號請用一個printf()
函數來列印):
試以
printf()
函數印出下面的圖案(不需使用迴圈,每一列星號請用一個printf()
函數來列印):
試撰寫一程式,利用
printf()
函數以星號和空白字元印出下面的圖案:
- 簡單的例子
- 解析 C 語言
- 識別字與關鍵字
- 偵錯
- 提高程式的可讀性
試寫一個程式,可以列印出 "
You are my best friend.
" 字串。
試寫一個程式,可以印出如下的輸出結果:
See you tomorrow. Have a good night.
試寫一程式,可計算
$5 + 12$ 的值,並將結果列印出來。
試寫一程式,可計算
$6 + 7 + 24$ 的值,並將結果列印出來。
試在您所使用的 C 語言開發環境裡找出 stdio.h 與 stdlib.h 這兩個檔案,請將它們的內容分別拷貝起來,然後分別貼在 hw2_1.c 裡的第 2 行與第 3 行的位置,取代掉
#include <stdio.h> #include <stdlib.h>這兩行,最後再編譯之。
以上的動作事實上就是編譯器所做的 "含括" 動作,只是現在是以手動方式將 stdio.h 與 stdlib.h 這兩個檔案含括進來罷了!如果執行本範例,您是否會得到與習題 1 相同的結果?
試仿照習題 7 的步驟,將 prog2_2 重新編譯並執行之。
試修改 prog2_2,使得第 9 行與第 10 行可以合併成一行來撰寫。
試以
printf()
函數印出如下的圖案:
下面是一個簡單的 C 程式碼,但程式的編排方式並不易於閱讀。請重新編排它來提高程式的可讀性:
/* hw2_20.c, 基本程式的練習 */ #include <stdio.h> #include <stdlib.h> int main(void){int i=5; printf("%d+%d=%d\n",i,i,i+i); system("pause");return 0; }
接續習題 20,試將習題 20 重新編排後,再加上適當註解,使得程式碼更具可讀性。
- 變數與常數
- 基本資料型態
- 查詢常數、變數或資料型態所佔位元組
- 資料型態的轉換
試修改 prog3_1,使得第 9 行與第 10 行可分別印出
num1
與num2
的平方值。第 9 行與第 10 行的輸出結果應如下所示:num1 的平方為 153760000 num2 的平方為 27.394756
試寫一程式,利用設定字元變數
ch
為 ASCII 碼的方式讓電腦發出一個警告音(警告音的 ASCII 碼為 7)。
請參閱下面的程式碼,然後回答接續的問題:
/* hw13_14, 數字溢位的練習 */ #include <stdio.h> #include <stdlib.h> int main(void) { unsigned short num=80000; printf("%d\n",num); system("pause"); return 0; }(a) 試說明執行此程式的結果,為什麼是
14464
,而不是80000
這個數字?(b) 如果想讓本題第 7 行的執行結果恰好為
80000
,應如何修改程式碼?
請參閱下面的程式碼,然後回答接續的問題:
/* hw3_15, 數字精度的問題 */ #include <stdio.h> #include <stdlib.h> int main(void) { float num1=30000.1F; float num2=0.0004F; printf("%f\n",num1+num2); system("pause"); return 0; }(a) 試執行此程式碼,您會得到什麼結果?
(b) 於數學上,$30000.1 + 0.0004 = 30000.1004$,試說明執行此程式碼後,為什麼得不到這個結果?
(c) 如果想讓本題的執行結果恰好為
30000.1004
,應如何改進?試撰寫一個完整的程式碼來改進之。
試撰寫一程式,利用
sizeof
關鍵字查詢下列各種資料型態所佔的位元組:(a)
unsigned int
(b)
double
(c)
unsigned short int
試撰寫一程式,利用
sizeof
關鍵字查詢下列各常數所佔的位元組:(a)
578
(b)
784000000
(c)
6.78f
(d)
718.26
(e)
6.42e127
假設浮點數變數
num1
與num2
的值分別為123.39f
與3.8e5f
,試撰寫一程式,將這兩個變數值轉換成整數。
請參閱下面的程式碼,然後回答接續的問題:
/* hw3_19, 型態轉換的練習 */ #include <stdio.h> #include <stdlib.h> int main(void) { int num1=5,num2=8; printf("%d\n",num1/num2); system("pause"); return 0; }(a) 試解釋第 7 行的輸出結果為何是
0
?(b) 試修改程式碼,利用型態轉換的方式,使得第 7 行的輸出結果為
0.625000
。
- 輸出函數
printf()
- 輸入函數
scanf()
- 使用
scanf()
函數應注意的事項- 輸出、輸入字元的函數
試撰寫一程式,利用
printf()
函數列印出如下的字串:I love C language best.
試撰寫一程式,利用
printf()
函數列印出如下的字串(必須包含雙引號):"I love C language best."
試嘗試利用一個
printf()
函數將字串常數"Hello, C"
與"Hello, World"
分別列印在不同一行(必須包含雙引號)。
試撰寫一程式,利用
printf()
函數列印出如下的字串(必須包含雙引號):"10/4=25"
試撰寫一程式,利用
printf()
函數列印出如下的字串(必須包含單引號):'30% 的學生來自中部地區,42% 的學生來自南部地區。'
試撰寫一程式,將浮點數變數
num = 28.47f
以下圖的格式印出(小數點前面有 4 位,小數點後面有 2 位,不滿欄位長度時填入0
):
試撰寫一程式,將浮點數變數
num = 12.34f
以下圖的格式印出(小數點前面有 4 位,小數點後面有 2 位,不滿欄位長度時填入0
,並印出其變數的正負號):
試撰寫一程式,利用
printf()
函數將下列字串印出:There is an old saying, "Love me, love my dog."
試撰寫一程式,利用
scanf()
函數輸入兩個整數,然後以printf()
函數列印出這兩個整數的乘積。
試撰寫一程式,由鍵盤輸入學生的學號(整數型態)及年齡(整數型態),輸入完畢後將剛才所輸入的內容印出在螢幕中。
試撰寫一程式,由使用者先輸入姓氏,再輸入名字,輸出時則先印出名字,再印出姓氏。
試撰寫一程式,輸入一長度最多為 10,且不包括空白的字串,並做下列的處理。
(a) 以雙引號將字串包圍。
(b) 以反斜線
\
將字串包圍,印出時的欄寬為 20。(c) 以反斜線
\
將字串包圍,印出時的欄寬為 20,靠左印出。
試撰寫一程式,由鍵盤輸入一個十進位的整數,然後印出該整數的八進位和十六進位。
試撰寫一程式,由鍵盤輸入一個十六進位的整數,然後印出該整數的八進位和十進位。
試著利用下面的程式,將字串 "
No more goodbye
" 輸入:/* hw4_16, 輸入字串的錯誤 */ #include <stdio.h> #include <stdlib.h> int main(void) { char str[25]; printf("Input a string:"); scanf("%s",str); printf("The string is %s\n",str); system("pause"); return 0; }(a) 根據執行的結果,您發現了什麼?為什麼會有這樣的執行結果?
(b) 試撰寫程式碼,可以將本例中,由鍵盤所輸入的 "
No more goodbye
" 字串裡所有的英文字母全部讀出,並列印出來。
請先執行下面的程式碼,然後回答接續的問題:
/* hw4_17, 輸入字串的錯誤 */ #include <stdio.h> #include <stdlib.h> int main(void) { char ch1,ch2; printf("請輸入第一個字元:"); scanf("%c",&ch1); printf("請輸入第二個字元:"); scanf("%c",&ch2); printf("ch1=%c, ch2=%c\n",ch1,ch2); system("pause"); return 0; }(a) 試說明為什麼第二個字元無法順利輸入?
(b) 試修改第 11 行的格式字串,使得本例中的第二個字元可以順利的輸入。
(c) 試撰寫程式碼,利用
fflush()
函數來清空緩衝區內的資料,使得本例中的第二個字元可以順利的輸入。
試修改 prog4_20 的第 14 行,以
getchar()
函數來取代。
試修改 prog4_22,使得字元的輸出是利用
putchar()
函數,而不是printf()
函數。
- 運算式與運算子
- 運算子的優先順序
- 運算式
- 運算式的型態轉換
請寫出下列程式的輸出結果,並撰寫完整的程式碼來驗證之:
(a)
/* hw5_1a, 運算式的練習 (一) */ int a=8; printf("a=%d\n",++a); printf("a=%d\n",a--);(b)
/* hw5_1b, 運算式的練習 (二) */ int a=10,b=20; a=a%5; b=b/6; printf("a=%d\n",a); printf("b=%d\n",b);(c)
/* hw5_1c, 運算式的練習 (三) */ int a=20,b=5; a=20,b=5; a=a%b; b=b*3; printf("a=%d\n",a); printf("b=%d\n",b);
試計算下列各式,並撰寫程式碼來驗證您計算的結果:
(a)
6%4
(b)
12%6
(c)
12%12
(d)
35%50
(e)
50%35
試計算下列各式,並撰寫程式碼來驗證您計算的結果:
(a)
12-4%6/4
(b)
7*5%12*6/4
(c)
(13%6)/7*8
試撰寫一程式,可由鍵盤輸入攝氏溫度,程式的輸出為華氏溫度,其轉換公式如下:
$$華氏溫度 = (9 ÷ 5) × 攝氏溫度 + 32$$
根據上題所提供的轉換公式,撰寫轉換華氏(由鍵盤輸入)至攝氏溫度的程式。
試撰寫一程式,可由鍵盤輸入英哩,程式的輸出為公里,其轉換公式如下:
$$1 英哩 = 1.6 公里$$
根據上題所提供的資訊,撰寫轉換公里(由鍵盤輸入)至英哩的程式。
試撰寫一程式,可由鍵盤輸入平行四邊形的底和高,然後計算其面積。
已知圓球體積為
$\frac{4}{3} \pi r^3$ ,試撰寫一程式,可輸入圓球半徑,經計算後輸出圓球體積。
- 我的程式會轉彎--
if
敘述- 另外的選擇--
if-else
敘述- 簡潔版的
if-else
敘述--條件運算子- 更好用的多重選擇--
switch
敘述- 使用
goto
敘述
試撰寫一程式,可由鍵盤讀入一個字元。若此字元是數字(即數字 0~9),則印出 "
此字元是數字
" 字串;若此字元是英文大小寫字母(即 a~z, A~Z),則印出 "此字元是英文字母
" 字串。
試修改 prog6_2 的程式碼,使得它也可以判別數字是等於 0 的情況。也就是說,可以判別輸入的整數是大於 0,等於 0,或小於 0 的情況。
試撰寫一程式,可由鍵盤輸入一個整數,然後判斷它是奇數或偶數。
試撰寫一程式,可由鍵盤輸入一整數,然後求此數的絕對值。
試撰寫一程式,可由鍵盤輸入一個整數,(代表某個人的體重),然後判斷體重是不是過重。若體重大於 90 公斤,則印出 "
體重過重
",否則印出 "不會過重
"。
試撰寫一程式,可由鍵盤輸入兩個整數,分別代表某個人的身高與體重,然後判斷他的體重是不是過重。若體重大於 90 公斤,且身高低於 180 公分,則印出 "
體重過重
",否則印出 "不會過重
"。
試撰寫一程式,由程式中宣告並設定三個整數的初值,判斷這三個整數是否能構成三角形的三個邊長(註:三角形兩邊長之和必須大於第三邊)。
接續習題 7,當三個邊長能夠構成三角形時,再判斷該三角形為鈍角、銳角或是直角三角形,其判別方法如下:
直角三角形:其中有兩個邊的平方和等於第三邊的平方
鈍角三角形:其中有兩個邊的平方和小於第三邊的平方
銳角三角形:任兩邊的平方和大於第三邊的平方
試撰寫一程式,讀入 10 個學生的成績,成績在 0~59 分為 C,60~75 分為 B,76~100 分為 A,最後將得到 A、B、C 的人數印出。
試撰寫一程式,輸入
$x$ 、$y$ 座標值,判斷該點位於哪一個象限或是在座標軸上。舉例來說,若輸入的座標值為$(3.0, -2.5)$ ,輸出即為第四象限;若輸入的座標值為$(4.5, 0.0)$ ,則輸出即為$x$ 軸。
假設某便利商店的工讀生的月薪資,可依照下列方式計算:
60 個小時之內,每小時 75 元
61 ~ 75 個小時,以 1.25 倍計算
76 個小時以後以 1.75 倍計算
例如,如果工作時數為 80 小時,則薪資為
$60 × 75 + 15 × 75 × 1.25 + 5 × 75 × 1.75 = 6562.5$ 元。試撰寫一程式,於程式中設定某工讀生該月的工作時數(為一整數),然後計算實領的薪資。
試利用 if-else-if 敘述設計一程式,程式的輸入為學生成績,輸出為成績的等級。學生成績依下列的分類方式分級:
80 ~ 100:A 級
60 ~ 79:B 級
0 ~ 59:C 級
試撰寫一程式,可輸入月份,然後判斷其所屬的季節(3~5 月為春季,6~8 月為夏季,9~11 月為秋季,12~2 月為冬季)。
試撰寫一程式,可由鍵盤讀入一個 4 個位數的整數,代表西洋的年份,然後判別這個年份是否為閏年(每四年一閏,每百年不閏,每四百年一閏,每四千年不閏,例如西元 1900 雖為 4 的倍數,但可被 100 整除,所以不是閏年,同理,2000 年是閏年,因可被 400 整除,而 2004 當然也是閏年,因可以被 4 整除)。
假設在某商店中購物,輸入所應付款的金額及實際交給店員的金額,輸入則為應找回最少的鈔票數與錢幣數,如果交給店員的金額少於應付金額,則印出 "
金額不夠
" 字串。舉例來說,我們買了 33 元(所應付款的金額)的東西,而交給店員的錢為 1000 元(實際交給店員的金額),店員應找回一張 500 元,四張 100 元,一個 50 元硬幣,一個 10 元硬幣,一個 5 元硬幣及二個 1 元硬幣(假設幣值只有 1000、500、100、50、10、5 與 1 元)。
已知一元二次方程式
$ax^2 + bx + c = 0$ 的解為
$$x = \frac{-b ± \sqrt{b^2 - 4ac}}{2a}$$ 試撰寫一程式,由程式中宣告並設定
a
、b
、c
三個浮點數的初值,代表方程式$ax^2 + bx + c = 0$ 的係數,然後利用判別式$b^2 - 4ac$ 的值來計算方程式的根。【註】
當
$b^2 - 4ac > 0$ 方程式有二個實根,$x = \frac{-b ± \sqrt{b^2 - 4ac}}{2a}$。當
$b^2 - 4ac = 0$ 方程式有兩個相等實根,$x = - \frac{b}{2a}$。當
$b^2 - 4ac < 0$ 則沒有實根,印出 "沒有實根
" 字串。(開根號請用
sqrt()
函數,注意sqrt()
的引數型態為double
,傳回值也是double
。使用sqrt()
函數時必須含括入math.h
標頭檔)
試將習題 5 改用條件運算子來撰寫。
試將習題 6 改用條件運算子來撰寫。
如果編譯下面的程式碼,則會有錯誤訊息發生。試指出錯誤之所在,並試著訂正之:
/* hw6_19, 條件運算子的練習 */ #include <stdio.h> #include <stdlib.h> int main(void) { int a = 4, b = 6, larger; a > b ? larger = a : larger = b; /* 條件運算子 */ printf("%d 數值較大\n", larger); system("pause"); return 0;
試由鍵盤輸入數值 1~4,並加以判斷輸入值是否在 1~4 之間,如果超出此範圍,則輸出 "
輸入錯誤
",否則利用switch
印出相對應的季節:1:春天
2:夏天
3:秋天
4:冬天
試由鍵盤輸入一個字元,然後加以判斷輸入的字元是小寫的 a 還是小寫的 b。若是小寫的 a,則印出 "
您輸入 a
",若是小寫的 b,則印出 "您輸入 b
",若輸入的字元不是 a 或 b,則印出 "您輸入的不是 a 或 b
"。
試修改習題 21,使得輸入的不論是 a 或 A,都印出 "
您輸入的是 A
",而不論是 b 或 B,都印出 "您輸入的是 B
",否則印出 "您輸入的不是 A 或 B
"。
試由鍵盤輸入一個 1~7 之間的整數,代表星期一到星期日。若輸入的是 1~5,則印出 "
今天要上班
",若輸入的是 6~7,則印出 "今天休息
",若輸入的不是 1~7,則印出 "輸入錯誤
"。
試利用
goto
敘述撰寫一程式,可以計算 1~100 之間,所有奇數的總和。
試利用
goto
敘述撰寫一程式,找出 1900~2000 之間,所有的閏年。關於閏年的判別,請參考習題 14。
試修改習題 20,使得當輸入的數值不是在 1~4 之間,則會要求重新輸入(請利用
goto
敘述來完成)。
- 結構化程式設計
- 使用
for
迴圈- 使用
while
迴圈- 使用
do while
迴圈- 空迴圈
- 我要使用哪一種迴圈?
- 巢狀迴圈
- 迴圈的跳離
試利用
for
迴圈計算$1 + 3 + 5 + ... + n$ 的總和,其中$n$ 為奇數,可由使用者自行輸入。
試撰寫一程式,利用
for
迴圈列印 ASCII 碼為 41~64 之間的字元。
試撰寫一程式,求整數 1~100 中,可以同時被 3 與 8 整除之所有整數的總和。
試撰寫一程式,由鍵盤輸入一個正整數,然後求其所有的因數,例如輸入 24,則印出 24 的所有因數 1、2、3、4、6、8、12 與 24。
試撰寫一程式,利用
for
迴圈印出從 1 到 100 之間,所有可以被 6 整除的數值。
試撰寫一程式,利用
for
迴圈印出從 1 到 100 之間,所有可以被 7 整除,又可以被 3 整除的數值。
試撰寫一程式,利用
for
迴圈計算$1^2 - 2^2 + 3^2 - 4^2 + ... + 47^2 - 48^2 + 49^2 - 50^2$ 的值。
試撰寫一程式,利用
for
迴圈計算$1 + \frac{1}{2} + \frac{1}{3} + ... + \frac{1}{n}$ 的總和,其中$n$ 值可自行輸入。
一個數如果恰好等於它的因數之和,這個數就稱為 "完美數"(perfect number)。例如
$6 = 1 + 2 + 3$ ,因 1、2 與 3 都是 6 的因數,因而 6 是完美數。試撰寫一程式,找出 1000 以內的所有完美數。
所謂 "Armstrong 數" 是指一個三位數的整數,其各位數字之立方和等於該數本身。例如:153 是一個 Armstrong 數,因為
$153 = 1^3 + 5^3 + 3^3$ 。試撰寫一程式,找出所有的 Armstrong 數。
試利用
while
迴圈計算$2 + 4 + 6 + ... + n$ 的總和,其中$n$ 為正的偶數,可由使用者自行輸入。若輸入的值不是正偶數,則程式會要求使用者再次輸入,直到輸入的數是正偶數為止。
假設有一條繩子長 3000 公尺,每天剪去一半的長度,請問需要花費幾天的時間,繩子的長度會短於 5 公尺?
試修改 prog7_5 中,使得無論按下 Ctrl+Q(ASCII 的值為 17)或 Ctrl+C(ASCII 的值為 3),皆可跳離程式的執行。
試撰寫一程式,利用
while
迴圈印出 1~10 之間所有整數的平方值,最後再印出這些平方值的總和。
試依下面的題意作答:
(a) 試利用
do while
迴圈,計算$2 + 4 + 6 + ... + n$ 的總和,其中$n$ 為正的偶數,可由鍵盤自行輸入。若輸入的不是正偶數,則程式會要求使用者再次輸入,直到輸入的數是正偶數為止。(b) 和習題 13 相比,您覺得哪一種迴圈較適合用來計算
$2 + 4 + 6 + ... + n$ 的總和?為什麼?
試利用
do while
迴圈找出最小的$n$ 值,使得$1 + 2 + 3 + ... + n$ 的總和大於等於 1000。
試撰寫一程式,由鍵盤分三次讀取 1 個整數,範圍在 1~50 之間;每讀取一個整數
$n$ ,就會列印出$n$ 個*
號。例如輸入 5,即印出*****
。
於下面的程式碼片段中,原本預期會印出 3 行星號,但實際上卻只印出了一行。試說明程式錯誤之處,並修正之:
/* hw7_21, 空迴圈的練習 */ int i; for (i = 1; i <= 3; i++); printf("*********\n");
於下面的程式碼片段中,第 4 行的敘述是否會被執行?為什麼?
/* hw7_22, 空迴圈的練習 */ int i = 0; while(i); printf("Have a nice day!\n");
試依下面的題意作答:
(a) 試修改習題 19,把
do while
迴圈改以for
迴圈來撰寫。(b) 試修改習題 19,把
do while
迴圈改以while
迴圈來撰寫。(c) 您覺得習題 19 分別以
for
、while
和do while
迴圈來撰寫時,比較起來哪一種迴圈寫起來較方便?為什麼?
試依下面的題意作答:
(a) 試修改習題 20,把
do while
迴圈改以while
迴圈來撰寫。(b) 您覺得習題 20 較適合用哪一種迴圈來撰寫?為什麼?
試利用巢狀迴圈撰寫出一個能產生如下圖結果的程式。請先繪製出流程圖後,根據流程圖撰寫程式:
1 22 333 4444 55555
試利用巢狀迴圈撰寫出一個能產生如下圖結果的程式:
1 12 123 1234 12345
試利用巢狀迴圈撰寫出一個能產生如下圖結果的程式:
1 12 123 1234 12345
試撰寫一程式,利用
do while
迴圈完成九九乘法表。
試撰寫一程式,利用
break
敘述來撰寫 4 個數字之密碼輸入的過程。使用者有三次輸入的機會,並須滿足下列的條件:(a) 如果密碼輸入不對,則會再次的出現 "
請輸入密碼:
" 字串。(b) 如果三次的輸入都不對,則程式會印出 "
密碼輸入超過三次!!
" 字串,然後結束程式的執行。(c) 如果輸入正確,則印出 "
密碼輸入正確,歡迎使用本系統!!
" 字串。本習題的部分程式碼如下,請將它補上該有的程式,以完成本題的需求:
/* hw7_29, break 敘述的練習 */ #include <stdio.h> #include <stdlib.h> int main(void) { int input; /* 用來儲存使用者輸入的密碼的變數 */ int cnt = 0; /* 用來計數密碼輸入的次數的變數 */ int passwd = 6128 /* 預設正確的密碼為 6128 */ while(1) { printf("請輸入密碼: "); scanf("%d", &input); /* 請在此輸入程式碼,以完成本題的要求 */ } system("pause"); return 0; }
試修改習題 29,把 10~15 行的
while
迴圈改以for
迴圈來撰寫。
試利用
continue
敘述,找出小於 100 的整數裡,所有可以被 2 與 3 整除,但不能被 12 整除的整數。
試撰寫一程式,由鍵盤輸入一個整數,然後判別此數是否為質數(prime)。若是,則印出 "
此數是質數
" 字串,若不是,則印出 "此數不是質數
" 字串(質數是指除了 1 和它本身之外,沒有其它的數可以整除它的數,例如,2, 3, 5, 7 與 11 等皆為質數)。
試撰寫一程式,可由鍵盤讀入一個正整數,並找出小於此數的最大質數。
老王養了一群兔子,但不知有幾隻。三隻三隻數之,剩餘一隻;五隻五隻數之,剩餘三隻;七隻七隻數之,剩餘二隻;試問最少有幾隻兔子?
- 簡單的函數範例
- 函數的基本架構
- 更多的函數應用範例
- 遞迴函數
- 區域、全域與靜態變數
- 引數傳遞的機制
- 前置處理器--
#define
- 再來看看
#include
前置處理器
試寫一函數
void kitty(void)
,當主程式呼叫kitty()
時,螢幕上會顯示 "Hello Kitty
" 之字串。
試撰寫
void kitty(int k)
函數,當主程式呼叫kitty(k)
時,螢幕上會顯示出$k$ 行的 "Hello Kitty
"。
試撰寫
int cub(int x)
函數,可用來傳回$x$ 的 3 次方,並利用此函數來計算cub(2)
,即計算$2^3$ 。
試撰寫
double square(double x)
函數,可用來傳回$x$ 的平方,並利用此函數來計算square(4.0)
,即計算$4.0^2$ 。
試撰寫
int mod(int x, int y)
函數,計算$x / y$ 的餘數。並利用此函數來計算mod(17, 5)
,即計算$\frac{17}{5}$ 的餘數。
試撰寫函數
int power(int x, int n)
,用來計算$x$ 的$n$ 次方,並於主程式裡計算power(5, 3)
,即計算$5^3$ 。
試撰寫函數
int prime(int n)
,可用來找出第$n$ 個質數(第一個質數為 2,第二個質數為 3,以此類推),並以此函數找出第 100 個質數。
設
$f(x) = 3x^3 + 2x - 1$ ,試寫一函數double f(double x)
,用來傳回$f(x)$ 的值,並於主程式裡分別計算$f(-3.2)$ 、$f(-2.1)$、$f(0)$ 與$f(2.1)$ 。
試修改 prog8_7,使得當
$n = 1$ 時,is_prime(n)
會傳回0
(即判別 1 不是質數)。
如果質數滿足
$2^p - 1$ ($p$ 為正整數)的話,則該質數稱為梅森尼質數(Mersenne primes)。例如,7 是梅森尼質數,因$p = 3$ 時,$2^3 - 1 = 7$。另外,11 就不是梅森尼質數,因為我們找不到一個整數$p$ ,使得$2^p - 1 = 11$ 。目前數學家搜尋更大質數的方法,許多都是利用電腦來檢驗梅森尼質數,在西元 1999 年六月,數學家用這這種方法發現了第 38 個梅森尼質數
$2^{26972593} - 1$ ,此數是當時所發現的最大質數!它是一個 2098960 位數,如果一張 A4 的紙可以印 5000 個數字,則這個質數必須印掉 420 張紙!現在請您撰寫程式碼,找出前 8 個梅森尼質數,並於主程式裡測試之。
在《孫子算經》(此書約完成於西元 400 年左右)裡有個著名的「孫子問題」:
"今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二,問物幾何?"
若把它翻譯成白話,便是:有一堆東西不知道有幾個;三個三個數它,剩餘二個;五個五個數它,剩餘三個;七個七個數它,剩餘二個;問這堆東西有幾個?
(a) 試找出滿足孫子問題裡的最小整數。
(b) 試撰寫一函數
int find(int n)
,可以回傳滿足孫子問題裡的第$n$ 個整數,然後利用此函數找出滿足孫子問題的第 5 個與第 7 個整數。(c) 試利用 (b) 所定義的函數找出前 12 個滿足孫子問題的整數。
ps. 如果您對《孫子算經》的數學探討有興趣,可參考台大數學系蔡聰明教授所撰寫的「談韓信點兵問題」:http://episte.math.ntu.edu.tw/articles/sm/sm_29_09_1
試依序回答下面的問題:
(a) 撰寫一函數
double my_fun(int n)
,可用來計算下面的數學式:
$$my_fun(n) = \sum_{k=1}^n \frac{1}{2^k} = \frac{1}{2} + \frac{1}{2^2} + \frac{1}{2^3} + ... + \frac{1}{2^n}$$ 並於主程式裡計算
my_fun(3)
、my_fun(4)
、my_fun(5)
與my_fun(6)
的值。(b) 如果將
$n$ 值加大,my_fun(n)
的結果會趨近一個定值,試問此定值是多少?(c) 試問
$n$ 值最少要多大時,my_fun(n)
的結果才會大於 0.99999?
試依序回答下面的問題:
(a) 撰寫一函數
double my_fun(int n)
,可用來計算下面的數學式(提示,您可以利用 prog8_8 所定義的fac(n)
函數來計算分母):
$$my_fun(n) = \sum_{k=1}^n \frac{1}{k!} = \frac{1}{1!} + \frac{1}{2!} + \frac{1}{3!} + ... + \frac{1}{n!}$$ 並於主程式計算
my_fun(5)
、my_fun(8)
與my_fun(10)
的值。(b) 試問
$n$ 值最少要多大時,my_fun(n-1)
與my_fun(n)
的差值才會小於 0.00001?
試依序回答下面的問題:
(a) 撰寫一函數
double my_fun(double x, int n)
,可用來計算下面的數學式(提示,您可以利用 prog8_6 所定義的power(x, n)
與 prog8_8 所定義的fac(n)
來計算分子與分母):
$$my_fun(n) = \sum_{k=1}^n \frac{x^k}{k!} = \frac{x^1}{1!} + \frac{x^2}{2!} + \frac{x^3}{3!} + ... + \frac{x^n}{n!}$$ 並於主程式計算
my_fun(0.1, 5)
、my_fun(0.1, 8)
與my_fun(0.2, 8)
的值。(b) 試問
$n$ 值最少要多大時,my_fun(0.1, n-1)
與my_fun(0.1, n)
的差值才會小於 0.00001?
試依序回答下面的問題:
(a) 撰寫一函數
double my_fun(double x, int n)
,可用來計算下面的數學式(提示,您可以利用 prog8_6 所定義的power(x, n)
與 prog8_8 所定義的fac(n)
來計算分子與分母):
$$my_fun(n) = \sum_{k=1}^n \frac{(-1)^k x^{2k + 1}}{(2k + 1)!}$$ 並於主程式計算
my_fun(2.2, 3)
與my_fun(2.2, 5)
的值。(b) 試問
$n$ 值最少要多大時,my_fun(2.2, n-1)
與my_fun(2.2, n)
的差值才會小於 0.00001?
試撰寫一函數
int find_k(int n)
,它可用來找出一個$k$ 值($k$ 為整數),使得$4k + 2$ 的值最接近$n$ 。例如,設$n = 19$ ,若$k = 4$ ,則$4k + 2 = 18$ ;若$k = 5$ ,則$4k + 2 = 22$ ,因 18 離 19 較近,所以find_k(19)
會傳回4
。
數學大師歐勒(Euler,1707 - 1783),找到了一個計算圓周率的無窮乘積:
$$\frac{\pi}{2} = \frac{3}{2} × \frac{5}{6} × \frac{7}{6} × \frac{11}{10} × \frac{13}{14} × \frac{17}{18} × \frac{19}{18} × \frac{23}{22} × ...$$ 有趣的是,這個公式裡,所有的分子都是大於 2 的質數,分母則是不能被 4 整除,且最靠近分子的偶數。
試撰寫一函數
double Euler(int n)
,用來估算圓周率的值到第$n$ 項,並計算Euler(10)
、Euler(100)
、Euler(1000)
與Euler(10000)
的結果(提示,利用習題 16 的find_k()
函數來求解分母)。
試依序回答下列問題:
(a) 試將 prog8_12 計算費氏數列的函數
int fib(n)
,改以非遞迴的方式來撰寫(提示:利用for
迴圈)。(b) 就效率而言,以
for
迴圈撰寫的fib()
函數的執行速度較快,還是以遞迴的方式來撰寫的fib()
函數較快,為什麼?
試撰寫遞迴函數
double rpower(double b, int n)
,用來計算$b$ 的$n$ 次方,並利用此函數來計算$2.0^3$ 。
試以遞迴的方式撰寫函數
int sum(int n)
,利用遞迴公式
$$sum(n) = n + sum(n - 1), sum(1) = 1$$ 用來計算
$1 + 2 + 3 + ... + n$ 的值。
試利用下面的公式
$$sum2(n) = sum2(n - 1) + 2 × n, sum2(1) = 2$$ 撰寫遞迴函數
int sum2(int n)
,用來計算$2 + 4 + 6 + ... + 2n$ 之和。
試撰寫遞迴函數
int rsum(int n)
來求算$1 × 2 + 2 × 3 + 3 × 4 + ... + (n - 1) × n$ 之和。
若
$f(n) = 2f(n - 1) - 5; f(0) = 3$ ,試求解$f(5)$ 的值。
試完成下面的程式碼,使得每呼叫
counter()
函數一次,便會印出 "counter() 已被呼叫 n 次了
" 字串,其中$n$ 為counter()
被呼叫的次數(counter()
函數裡計數的變數請用靜態變數來撰寫)。/*hw8_24, 靜態變數的練習 */ #include <stdio.h> #include <stdlib.h> void counter(void); int main(void); { counter(); counter(); system("pause"); return 0; } void counter(void) { /* 試在此處填上程式碼,使得 counter() 可以印出它被呼叫的次數 */ }本習題的執行結果應如下所示:
counter()已被呼叫1次了... counter()已被呼叫2次了...
利用 24 題的
counter()
函數來追蹤 prog8_12 所定義的遞迴函數fib()
,在遞迴的過程中一共被呼叫幾次。例如,若計算fib(5)
,則程式碼的輸出為counter()已被呼叫1次了... counter()已被呼叫2次了... counter()已被呼叫3次了... counter()已被呼叫4次了... counter()已被呼叫5次了... counter()已被呼叫6次了... counter()已被呼叫7次了... counter()已被呼叫8次了... counter()已被呼叫9次了...
代表
fib()
函數一共被呼叫 9 次。
試利用 24 題的
counter()
函數來追蹤習題 19 裡的rpower()
函數,在計算rpower(2.0, 9)
的過程中,rpower()
函數一共被呼叫幾次。
試撰寫一程式,用來比較計算
fib(n)
函數時,遞迴版本和for
迴圈版本執行fib()
的總次數(關於fib()
函數的定義,請參考 8.4 節)。$n$ 值取 1~30,執行結果應如下所示:n = 1, for 迴圈 1次, 遞迴1次 n = 2, for 迴圈 1次, 遞迴1次 n = 3, for 迴圈 3次, 遞迴3次 n = 4, for 迴圈 4次, 遞迴5次 ... n = 30, for 迴圈30次, 遞迴1664079次
試修改習題 24,把
counter()
函數裡計數的變數改以全域變數來撰寫。
如果把 prog8_19 的變數
a
與b
改以全域變數來撰寫,其他程式碼不更動,則執行結果是否會和 prog8_19 相同?為什麼?
在 prog8_19 中,當我們呼叫
add10()
之後,在main()
裡變數a
與b
的值並不會被加 10。試修改程式碼,使得當add10()
被呼叫之後,a
與b
的值會加 10。
試利用
#define
定義巨集函數$f(x) = 4x^2 + 6x - 5$ ,並於主程式中計算f(1.0)
、f(2.2)
與f(3.14)
的值。
試利用
#define
定義一巨集函數CUBIC(X)
,可用來計算$X$ 的 3 次方,並利用此巨集計算$5^3$ 和$2.4^3$ 。
試利用巨集定義
AVERAGE(X, Y)
函數,用來計算$X$ 與$Y$ 的平均值,並利用此巨集計算$12.6$ 和$4.2$ 的平均值。
試利用條件運算子「
?:
」定義巨集ABS(X)
,用來計算$X$ 的絕對值,並利用此巨集計算 -13.6 的絕對值。
試利用 8.8.2 節所建立的標頭檔
area.h
來計算下列各題:(a) 半徑為 1.0 的圓面積。
(b) 長為 5.0,寬為 4.6 的長方形面積。
(c) 底為 12.2,高為 9.4 的三角形面積。
試撰寫一個
my_math.h
的自訂標頭檔,裡面定義了下面的巨集。(1)
SQUARE(X)
,可計算$X$ 的平方值。(2)
CUBIC(X)
,可計算$X$ 的三次方值。(3)
ABS(X)
,可計算$X$ 的絕對值。(4)
AVERAGE(X, Y)
,可計算$X$ 與$Y$ 的平均值。(5)
PRODUCT(X, Y)
,可計算$X$ 與$Y$ 的乘積。(a) 利用
#include
將標頭檔my_math.h
含括到程式中,由鍵盤輸入一個整數後,計算它的平方值、三次方值及絕對值。(b) 試利用
#include
將標頭檔my_math.h
含括到程式中,由鍵盤輸入兩個浮點數後,計算這兩個數的平均值及乘積。
- 一維陣列
- 二維陣列與多維陣列
- 傳遞陣列給函數
- 字串
- 字串的輸入與輸出函數
- 字串陣列
試撰寫一程式,宣告一個具有 5 個元素的整數陣列
arr
,然後利用for
迴圈設值給這個陣列,arr[0]
~arr[4]
分別設值為 1~5,最後列印出陣列arr
的每一個元素值。
試撰寫一程式,宣告一個具有 5 個元素的整數陣列
arr
,並利用陣列設定初值的方式,將arr[0]
~arr[4]
分別設值為 2, 3, 1, 7 與 9,最後列印出陣列arr
的每一個元素值。
試利用
sizeof
關鍵字查詢習題 2 裡的陣列arr
共佔了多少個位元組。
試撰寫一程式,宣告一個具有 3 個元素的整數陣列
arr
,然後利用鍵盤輸入數字,將陣列內的三個元素設值,最後於程式裡印出這三個元素。
設陣列
array
宣告為int array[] - {3, 5, 0, 3, 2, 4, 1, 6, 8, 5, 4, 3, 2};(a) 試撰寫一程式,利用
sizeof
關鍵字計算陣列array
內元素的個數。(b) 接續 (a),試找出陣列
array
內元素的值介於 3~6 之間(包含 3 和 6)的元素共有幾個。
試撰寫一程式,由鍵盤輸入 5 個浮點數,並存放到一陣列,再計算這 5 個數的平均值。
試撰寫一程式,找出一維整數陣列元素最大值的索引值與最小值的索引值。
試修改 prog9_9,使得程式的輸出是每一季裡,業務員 1 與業務員 2 銷售業績的總和。
試修改 prog9_9,使得程式的輸出分別是業務員 1 於 2004 年的總銷售業績,和業務員 2 的總銷售業績。
試修改 prog9_10 裡的
A
與B
陣列為$4 × 3$ 的陣列,然後計算$A + B$ 之後的結果。陣列內的元素請自訂。
試撰寫一程式,找出二維陣列中最小值的索引值。陣列的大小與元素的值請自行設定。
假設某一公司有五種產品 A、B、C、D 與 E,其單價分別為 12、16、10、14 與 15 元;而該公司共有三位銷售員,他們在某月份的銷售量如下所示:
銷售員 產品 A 產品 B 產品 C 產品 D 產品 E 1 33 32 56 45 33 2 77 33 68 45 23 3 43 55 43 67 65 試寫一程式印出上表的內容,並計算:
(a) 每一個銷售員的銷售總金額。
(b) 每一項產品的銷售總金額。
(c) 有最好業績(銷售總金額為最多者)的銷售員。
(d) 銷售總金額為最多的產品。
下表為某地星期一至星期四的時段一、時段二與時段三的氣溫:
星期一 星期二 星期三 星期四 時段一 18.2 17.3 15.0 13.4 時段二 23.8 25.1 20.6 17.8 時段三 20.6 21.5 18.4 15.7 請將上表的內容直接於程式中以陣列初值方式設定,並依序完成下列各題:
(a) 印出陣列內容。
(b) 每日的平均溫度。
(c) 時段一、時段二與時段三的平均溫度。
(d) 溫度最高的日子與時段。
(e) 溫度最低的日子與時段。
設陣列
A
的維度為$4 × 2 × 3$ ,試在程式碼裡宣告此一陣列,並在宣告同時設定初值,然後計算陣列A
內所有元素的總和。
在數位彩色照片裡,每一個畫素(pixel)的顏色是由紅、綠與藍(red、green 與 blue,即 rgb)三個顏色混合而成的。通常 rgb 的強度可用 0~255 的數值來表示。數值越大代表該顏色的強度越強。照片的維度是二維,因此恰可用一個二維的矩陣來表示它,每一個矩陣的元素即代表了一個畫素。但因每一個畫素必須是由紅、綠與藍三個顏色組成,於是要正確的表示一張數位彩色照片的資料,最方便的方式是利用三維矩陣。下面是一個三維矩陣的示意圖,它代表了一個
$4 × 5$ 畫素的彩色影像:🔽 紅色
$$ \begin{pmatrix} 247 & 67 & 32 & 187 & 240\\ 122 & 41 & 21 & 16 & 154\\ 52 & 35 & 79 & 21 & 93\\ 27 & 22 & 35 & 154 & 75\\ \end{pmatrix} $$ 🔽 綠色
$$ \begin{pmatrix} 14 & 145 & 132 & 25 & 40\\ 212 & 221 & 121 & 54 & 14\\ 132 & 235 & 178 & 19 & 14\\ 122 & 122 & 133 & 54 & 47\\ \end{pmatrix} $$ 🔽 藍色
$$ \begin{pmatrix} 17 & 44 & 32 & 127 & 240\\ 22 & 231 & 21 & 156 & 124\\ 32 & 35 & 78 & 21 & 194\\ 127 & 22 & 33 & 54 & 45\\ \end{pmatrix} $$ (a) 試以一個三維的陣列來描述此一影像。
(b) 試將每一個畫素中的
$r$ 值加 30。若加 30 之後的值超過 255,則以 255 取代之。(c) 試將每一個畫素中的
$g$ 值減 30。若減 30 之後的值小於 0,則以 0 取代之。
試撰寫一函數
int min(int arr[])
,可傳回一維陣列arr
裡所有元素的最小值,並測試之。
試撰寫一函數
int idx(int arr[])
,可傳回一維陣列arr
裡最小值的索引值,並測試之。
試撰寫一函數
void square(int arr[])
,在呼叫square()
函數後,一維陣列arr
裡的每一個元素皆會被平方。
試撰寫一函數
void count(int arr[])
,它可接收一個一維整數陣列arr
,並於函數內計算陣列arr
裡奇數與偶數的個數,然後將它們列印出來。
試撰寫一函數
double average(int arr[ROW][COL])
,可用來傳回二維陣列arr
裡所有元素的平均值,其中ROW
與COL
是由前置處理器#define
所定義的常數,ROW
代表陣列的列數,COL
為行數。
試撰寫一函數
void add(int A[ROW][COL], int B[ROW][COL], int C[ROW][COL])可用來計算矩陣
A
與B
的相加,並把相加後的結果放到矩陣C
裡。ROW
與COL
是由前置處理器#define
所定義的常數,ROW
代表陣列的列數,COL
為行數。
若宣告了下面的字元陣列
char str[] = "Hello C language";則字元陣列
str
共佔了幾個 bytes?試撰寫一程式來驗證您的結果。
試撰寫一程式,由鍵盤輸入一字串後,分別計算該字串出現 a、e、i、o、u 的次數。
試設計一程式,將字串中所有的大寫字母轉換成小寫字母。
試撰寫一函數
int length(char str[])
,可用來計算字串變數str
的字元數(不包含字串結束字元「\0
」)。
試撰寫一函數
void reverse(char str[])
,它可將字串str
反序印出來。舉例來說,輸入的字串為 "Hello
",輸出即為 "olleH
"。字串的輸入請用gets()
函數,輸出請用puts()
函數。
試撰寫一函數,
void toLower(char str[])
,它可將字串str
的大寫字母改成小寫印出。字串的輸入請用gets()
函數,輸出請用puts()
函數。
設字串陣列
arr
宣告為char arr[][11]={"C language", "C++", "Java"};試回答下面的問題:
(a) 下面是陣列
arr
的記憶體配置圖,裡面已填入了部分的字元,但尚未全部完成。請試著將它們填滿(未使用到的空間請用斜線來填滿):(b) 陣列
arr
共佔了多少個位元組?(c) 陣列
arr
裡,有幾個位元組的記憶空間浪費掉了?(d) 假設
arr[0][0]
的位址是10
,arr[0][1]
的位址是11
,以此類推(每一個元素都佔了一個位元組),試接續 (a) 的圖,將每一個陣列元素的位址都填上。(e) 接續 (d),若以
for(i = 0; i < 3; i++) printf("arr[%d] = %p\n, i, arr[i]);來列印,您將會得到什麼答案?這些答案各代表什麼意義?
(f) 試撰寫一程式,可列印出字串陣列
arr
裡所有的字串。
試改寫 prog9_24,使得拷貝字串陣列的動作是在函數
string_cpy()
裡進行。string_cpy()
函數的原形請宣告為void string_cpy(char arr1[MAX][LENGTH], char arr2[MAX][LENGTH]);當函數
string_cpy()
呼叫時,可將字串陣列arr1
的內容拷貝到字串陣列arr2
。
如果把 prog9_24 裡,12~20 行的
for
迴圈改成只有下面三行for(i = 0; i < MAX; i++) for(j = 0; j < LENGTH; j++) arr2[i][j] = arr1[i][j];則程式執行的結果是否會相同?試比較上述的寫法與 prog9_24 的寫法的優缺點。
- 指標概述
- 使用指標變數
- 指標與函數
- 指標與一維陣列
- 指標與字串
- 指向指標的指標--雙重指標
假設在程式碼裡宣告了下面的敘述:
float num = 4.2f; int a1 = 4, a2 = 12;於程式碼裡印出變數
num
、a1
與a2
的位址,並仿照圖 10.1.4 繪出變數於記憶體裡的配置情形。
假設在程式碼裡宣告了下面的敘述:
double b1 = 3.14; int num = 5;試於程式碼裡印出變數
b1
與num
的位址,並仿照圖 10.1.4 繪出變數於記憶體裡的配置情形。
假設在程式碼裡有如下的敘述:
float num = 12.6f, *ptr; ptr = #試撰寫一程式,列印出變數
num
與指標變數ptr
的位址,並仿照圖 10.2.1 繪出變數於記憶體的配置情形。
試修改 prog10_5,使得在程式碼 6~18 行中,每執行完一行,便能印出變數
a
、b
、ptr1
、*ptr1
、ptr2
與*ptr2
的值。
於下表中,假設
a
的位址為1000
,b
的位址為2000
,試仿照 prog10_5,依序將下列的空格填滿,並撰寫一程式,印出表格裡相關的數據,用以驗證您所填入的數值。
程式碼 a b ptr *ptr 1 int a = 12, b = 7;
12 7 -- -- 2 int *ptr;
3 ptr = &a;
4 *ptr = 19;
5 ptr = &b;
6 b = 16;
7 *ptr = 12;
8 a = 17;
9 ptr = &a;
10 a = b;
11 *ptr = 63;
於下表中,假設
a
的位址為1000
,b
的位址為2000
,試仿照 prog10_5,依序將下列的空格填滿,並撰寫一程式,印出表格裡相關的數據,用以驗證您所填入的數值。
程式碼 a b ptr1 *ptr1 ptr2 *ptr2 1 int a = 28, b = 16;
12 7 -- -- -- -- 2 int *ptr1, *ptr2;
3 ptr1 = &b;
4 ptr2 = &a;
5 *ptr1 = 4;
6 a = 16;
7 *ptr2 = 12;
8 ptr2 = ptr1;
9 *ptr = 19;
10 ptr1 = &a;
11 a = 7;
12 *ptr2 = *ptr1;
假設於程式碼裡有如下的宣告:
float pi = 3.14f; float *ptr = π試仿照 prog10_7 的做法,將
&pi
與ptr
傳入address()
函數中,用來列印變數pi
的值與位址,並仿照圖 10.3.1 繪製出記憶體的配置圖。
試撰寫一函數
void count(int *)
,可接收一個整數變數num
的位址(num
的初值請設為 0)。每當count()
函數被呼叫一次,主程式裡的num
之值也會被加 1,並於主程式裡自行測試之。
試修改第八章 prog8_19,使得當
add10()
函數被呼叫時,傳入add10()
裡的變數a
與b
的值均會被加 10。
試撰寫一程式
void square(int *arr)
,在呼叫square()
函數後,一維陣列arr
裡的每一個元素皆會被平方。
試閱讀下列的程式碼,然後回答接續的問題:
/* hw10_13, 「*」與「++」運算子優先次序的比較 */ #include <stdio.h> #include <stdlib.h> int main(void) { int num[] = {14, 23, 32, 62, 19}; int *p1, *p2; p1 = p2 = num; *p1++; printf("*p1 = %d\n", *p1); (*p2)++; printf("*p2 = %d\n", *p2); system("pause"); return 0; }(a) 如果執行此程式,則第 11 行與第 14 行的輸出為何?
(b) 試解釋第 11 行與第 14 行的輸出為何不同。
假設整數陣列
arr
宣告為int arr[5] = {34, 76, 33, 42, 76};試利用指標常數
arr
的算術運算,將陣列裡每一個元素的值加上 10,並列印出結果。
假設整數陣列
arr
宣告為int arr[5] = {31, 17, 33, 22, 16};試宣告一個指向整數的指標
ptr
指向陣列arr
,然後利用指標的算術運算,將陣列arr
裡每一個元素的值加上 10,並列印出結果。
試修改第九章的範例 prog9_5,利用指標常數
A
的算術運算來找尋陣列裡元素的最大值及最小值。
試撰寫一程式,利用指標的算術運算來找出一維整數陣列中,元素最大值的索引值與最小值的索引值(一維整數陣列的元素值請自行設定)。
設程式碼裡有如下的字串宣告:
char *ptr = "We are best friends.";(a) 試撰寫一程式,計算
ptr
所指向的字串裡,共有多少個字元(不含字串結束字元)。(b) 試撰寫一程式,計算小寫字母的字元數。
試撰寫一函數
int length(char *ptr)
,可用來計算由指標變數ptr
所指向的字串裡,所有的字元數(不包含字串結束字元「\0
」)。
試撰寫一程式,計算 prog10_20 中,由指標陣列
ptr
所指向的三個字串供佔了多少個位元組(包含字串結束字元「\0
」)。
試撰寫一函數
void display(char *ptr, int n)
,它可以接收一個指向字串的指標變數ptr
,以及一個整數n
,並於函數內印出ptr
所指向的字串中,從第$n$ 個字元開始,到字串結束。
假設在程式碼裡宣告有如下的字串陣列:
char str[2][20] = {"Time is money", "Have a good time"}試利用指標常數
str
,配合puts()
函數,將字串陣列裡的每一個字串印出來。
試修改第 9 章的範例 prog9_10,使得第 16 行矩陣相加的運算是以指標的方式來撰寫。
試修改第 9 章的範例 prog9_19,將
search()
函數內,陣列arr
的元素改以指標的方式來撰寫。
如果在程式裡有如下的宣告:
int arr[2][4] = {{2, 3, 4, 5}, {6, 7, 8, 9}};假設
arr[0][0]
的位址為1200
,試回答下列各題:(a)
arr
的值為何?(b)
arr[0]
與arr[1]
的值各是多少?(c)
arr + 1
的值為何?(d)
*(arr + 0)
與*(arr + 1)
的值為何?(e)
*(arr + 1) + 0
、*(arr + 1) + 1
、*(arr + 1) + 2
與*(arr + 1) + 3
的值各是多少?(f)
*(*(arr + 1) + 0)
、*(*(arr + 1) + 1)
、*(*(arr + 1) + 2)
與*(*(arr + 1) + 3)
的值各是多少?(g) 試撰寫一程式碼,用來驗證 (a)~(f) 小題裡每一項的數據。
(h) 試仿照圖 10.6.4,繪出本例中,陣列
arr
元素於記憶體內的配置圖。記憶體位址請用 (g) 小題裡所求得的真實位址。
- 認識結構
- 巢狀結構
- 結構陣列
- 指向結構的指標
- 以結構為引數傳遞到函數
- 列舉型態
- 使用自訂的型態--
typedef
假設有一結構
data
的定義與結構變數aaa
的宣告如下:struct data { int num; char ch; double dist; }aaa;(a) 試問結構變數
aaa
共佔了多少個位元組?(b) 試撰寫一程式,利用
sizeof()
列印出結構變數aaa
的大小,用來驗證 (a) 的推論是否正確。
試依下列題目作答:
(a) 試撰寫一程式,建立一日期結構
date
,其成員包括year
(年份)、month
(月份)即day
(日期),型態皆為整數。(b) 宣告一結構
date
型態的變數holiday
,並設定初值為{2004, 4, 26}
。(c) 宣告一結構
date
型態的變數festival
,並可由鍵盤輸入數值來設定變數festival
的成員year
成員為 2005、month
的成員為 12 與day
的成員為 25。(d) 以 mm/dd/yyyy 的格式印出結構
holiday
與festival
的值。mm 代表月份,佔有 2 格;dd 代表日期,佔有 2 格;yyyy 代表年份,佔有 4 格,如 06/18/2004。
於習題 2 中,結構
date
型態的變數佔了多少個位元組?試撰寫一程式利用sizeof()
檢驗之,並仿照圖 11.1.1 繪出結構date
的資料成員。
試撰寫一程式,使其能夠完成下列功能:
(a) 建立一時間結構
time
,其成員包括hour
(小時)、minutes
(分)及second
(秒),其中hour
與minutes
的型態皆為int
,而second
的型態則為double
。(b) 宣告一個結構
time
型態的變數start
,並設定初值為{12, 32, 25.49}
。(c) 宣告一個結構
time
型態的變數end
,並設定初值為{15, 12, 17.53}
。(d) 以 hh:mm:ss.ss 的格式印出結構
start
與end
的值。hh 代表小時,佔有 2 格;mm 代表分,佔有 2 格;ss.ss 代表秒,其中秒數部分,整數與小數部分均取兩位。例如 05:19:20.43 代表了 5 小時 19 分 20.43 秒。(e) 試計算從
start
開始,到end
結束為止,總共經歷了多少時間,請把經歷的時間用另一個結構變數elapse
來儲存,並以 hh:mm:ss.ss 的格式列印出來。
於習題 4 中,結構
time
型態的變數佔了多少個位元組?試撰寫一程式利用sizeof()
檢驗之,並仿照圖 11.1.1 繪出結構time
的資料成員。
試修改 prog11_5,使得結構變數
s1
的成員之值是以鍵盤來輸入。
於 prog11_5 中,試分析結構變數
s1
共佔了多少個位元組,並撰寫一程式,利用sizeof()
來檢驗您的分析結果。
試依下列的題目來作答:
(a) 試參考習題 2 與習題 4,請重新定義習題 2 的結構
date
,使得它的成員除了包含有原來的year
、month
與day
之外,在加入習題 4 所定義的time
結構,使得結構date
共有 4 個成員,而成為一個巢狀結構。(b) 宣告一個結構
date
型態的變數now
,並設定初值為今天的日期,與目前的時間。(c) 請撰寫一程式,列印變數
now
的值,列印格式請用mm/dd/yyyy hh:mm:ss.ss
的格式來列印(yyyy 與 hh 之間請空兩個空格)。
(d) 試分析結構變數
now
共佔了多少個位元組,並撰寫一程式,利用sizeof()
來檢驗您的分析結果。
試修改 prog11_7,宣告一個具有 5 個元素的結構陣列
student
,並於程式碼裡設定初值給陣列元素,然後撰寫相關的程式碼來尋找下列各項:(a) 成績最高分的學生姓名與分數。
(b) 所有成績不及格的學生姓名與分數(60 分為及格)。
(c) 成績的平均值。
試將習題 9 裡,結構陣列元素之設值改成可由鍵盤輸入。
試修改習題 9,先宣告好結構陣列,然後再逐一設定結構陣列內每一個元素的值(也就是把結構陣列的宣告和設值寫在不同的敘述),再完成 (a)~(c) 小題。
試修改 prog11_7,使得程式碼裡所有關於結構陣列
student
之元素的存取,皆是以指標的算術運算來完成。
假設於習題 9 裡,我們利用一個指向結構
data
型態的指標,來指向結構陣列student
,如下面的敘述:struct data *ptr; /* 宣告指向結構 data 型態的指標 ptr */ ptr = student; /* 將 ptr 指向陣列 student 的位址 */試以指標
ptr
的算術運算來完成習題 9 的程式設計。
於 prog11_10 中,如果將
display()
函數裡,結構st
的math
成員的值加 10,於主函數main()
裡的結構s1
的math
成員之值是否也會被加 10?為什麼?
假設結構
data
的定義為struct data { char name[10]; int math; };試設計一函數
void add5(struct data *)
,只要函數add5()
被呼叫,則傳入之引數的math
成員之值便會被加 5。
試參考習題 4,請撰寫一函數
void display(struct time)
,用來列印變數start
、end
及elapse
之值。列印的格式請用 hh:mm:ss.ss。
試修改 prog11_7,宣告一個具有 5 個元素的結構陣列
student
,並於程式碼裡設定初值給陣列元素,並依下列的敘述進行程式設計:(a) 試撰寫一函數
struct data best(struct data student[])
,可接收結構陣列student
,傳回值則為成績最高分的結構陣列元素。(b) 試撰寫一函數
void failed(struct data student[])
,可接收結構陣列student
,並於函數裡列印出所有成績不及格之學生姓名與分數(60 分為及格)。(c) 試撰寫一函數
double average(struct data student[])
,可接收結構陣列student
,傳回值則為成績的平均值。(d) 試撰寫一函數
void sort(struct data student[])
,可接收結構陣列student
,並於函數裡將陣列元素排列。分數越高者排列越前面。
下面的程式碼裡定義了列舉型態
boolean
,請先閱讀它,並試著回答接續的問題:/* hw11_18.c, 列舉型態的練習 */ #include <stdio.h> #include <stdlib.h> int main(void) { enum boolean; { FALSE, TRUE }test; test = 5 < 20; if(test == TRUE) printf("5 < 20 成立\n"); else printf("5 >= 20 不成立\n"); system("pause"); return 0; }(a) 列舉常數
FALSE
與TRUE
的預設值各是多少?(b) 變數
test
佔了多少個位元組?(c) 程式的執行結果為何?試解釋為何會有這個執行結果。
(d) 如果把 12~15 行修改成
if(test) printf("5 < 20 成立\n"); else printf("5 >= 20 不成立\n");則程式是否依然可以正確執行?為什麼?
試修改 prog11_14,使得不論按下大寫或小寫的英文字母 r、g 或 b,程式的執行結果均能列印出相對應的顏色。
如果將 prog11_15 的第 9 行
SCORE
型態的定義移到main()
函數內,在編譯時您會得到什麼樣的錯誤訊息?試解釋錯誤發生的原因。
試以格式 11.7.2 的定義方式改寫 prog11_15。
- 檔案的觀念
- 有緩衝區的檔案處理函數
- 無緩衝區的檔案處理函數
- 二進位檔案的使用
試撰寫一程式,以每 5 個字元為單位的方式,讀取 prog12_1 中所使用的資料檔 welcome.txt(提示:可利用
fgets()
函數來撰寫)。
試修改 prog12_2,使得檔案在拷貝時,也能夠計算出共有多少個字元被拷貝了(含換行字元)。
試修改 prog12_2,使得檔案在拷貝時,試以
fgets()
函數來讀取檔案,且以fputs()
函數來寫入資料到 output.txt 中。
試修改 prog12_3,加入檢查開檔是否成功的程式碼,以確定檔案是正常的開啟。
試修改 prog12_4 的第 17 行,將
printf()
函數改成利用puts()
函數來輸出字串。
試撰寫一程式,將文字檔 aa.txt 與 bb.txt 的內容合併成 cc.txt。
如果把 prog12_5 裡,第 7 行
SIZE
的定義修改為 16,程式是否可以正確執行?為什麼?
試修改 prog12_5,使得檔案在拷貝的同時,也可以於螢幕上印出拷貝的內容。
試依下列的步驟完成程式設計:
(a) 試產生 10 個 1~64 之間的整數亂數,並將它寫入純文字檔 "rand.txt" 內。
(b) 撰寫一程式讀取純文字檔 rand.txt 的內容,並計算這 10 個數值的平均值。
設程式裡有定義下列的變數:
int arr[] = {12, 4, 5, 6}; int a = 12, b = 16;試利用
write()
函數將這些變數的值以二進位的模式寫入檔案 hw12_12.bin 中。
接續習題 12,是利用
read()
函數將 hw12_12.bin 檔案中的內容取出,並顯示在螢幕上。
試修改習題 12,請使用
fwrite()
函數,將變數的值改以二進位檔案的格式寫入檔案 hw12_14.bin 中。
接續習題 14,請使用
fread()
函數將檔案 hw12_14.bin 的內容取出,並顯示在螢幕上。
- Question 12-16a (with buffer)
- Question 12-16b (with buffer)
- Question 12-16a (without buffer)
- Question 12-16b (without buffer)
試依下列的步驟完成程式設計:
(a) 試產生 10 個 1~16 之間的整數亂數,並將它寫入二進位檔 "rand.bin" 內。
(b) 撰寫一程式讀取二進位檔 rand.bin 的內容,並找出這 10 個數值的最大值與平均值。
試依下列步驟完成程式設計:
(a) 修改 prog12_8,是建立 3 個
struct data
型態之物件陣列student
,並將它寫入二進位檔 "student.bin" 內。(b) 撰寫一程式讀取 (a) 中所建立之二進位檔的內容,並將結果顯示在螢幕上。
- Question 12-18a (with buffer)
- Question 12-18b (with buffer)
- Question 12-18a (without buffer)
- Question 12-18b (without buffer)
設程式裡有定義下列的變數:
int arr[] = {11326, 4445, 15589, 23740, 76840};(a) 試將陣列
arr
的值,以純文字檔的模式儲存在檔案 "hw12_18.txt" 裡。(b) 試將陣列
arr
的值,以二進位檔的模式儲存在檔案 "hw12_18.bin" 裡。(c) 試比較檔案 hw12_18.txt 與 hw12_18.bin 的大小,並分析就節省記憶空間而言,採用哪一種方式來儲存數字較為經濟。
- 程式的模組化與實作
- 於不同檔案裡使用全域變數
- 條件式編譯
- 命令列引數的使用
在 13.1 節所建立的專案 my_prj 中,於檔案 area.c 裡,如果沒有第二行的
PI
的定義,則在編譯時會有什麼情況產生?試解釋這種情況發生的原因。
試修改 13.1 節所建立的專案 my_prj,使得函數
area()
、peri()
、與show()
是在同一個檔案內(檔案名稱請取為 function.c,專案名稱請用 prj13_5)。
試修改第八章的 prog8_1,使得主程式
main()
與star()
是分存於兩個不同的檔案來編譯(包含主程式的檔案請存成 hw13_6.c,包含star()
函數的檔案請存成 star.c)。
如果於 prog13_3 中,把函數模組 count.c 裡第 5 行的
extern
關鍵字拿掉,然後重新編譯,您會得到什麼樣的結果?試解釋為何會有這種結果的產生?
試修改第八章的 prog8_15,使得主程式
main()
與func()
是分存於兩個不同的檔案來編譯(包含主程式的檔案請存成 hw13_8.c,包含func()
函數的檔案請存成 func.c)。
試修改第八章的 prog8_17,把主程式
main()
,以及area()
和peri()
分存於三個不同的檔案來編譯(包含主程式的檔案請存成 hw13_9.c,包含area()
函數的檔案請存成 area.c,包含peri()
函數的檔案請存成 peri.c)。
試修改 prog13_4,將第 7 行的
#ifdef
改寫成利用#ifndef
來判斷STR
是否沒有被定義過,若沒有,則印出 "STR 沒有定義
" 字串,否則印出 "Hello C language
" 字串。
試修改 prog13_5,加入一個
#elif
敘述,用來判別SIZE
的值如果介於 10~20 之間,則印出 "Welcome
" 字串。
試修改 prog13_7 中所探討的問題,也就是修改 area.h,成為 area2.h,使得把 prog13_7 裡的第 4 與第 5 行對調,程式依然可以正確編譯執行。
試撰寫一程式,可利用命令列引數的方式接收一個字元,程式的輸出則是印出該字元相對應的 ASCII 碼。
試撰寫一程式,可利用命令列引數的方式接收一個整數
$n$ 。程式的輸出則可列出$n$ 的 "Hello kitty!
" 字串,如下所示(提示:可利用字串轉換整數函數atoi()
完成):C:\prog> hw13_15 3 Hello kitty! Hello kitty! Hello kitty!
試著模仿 Dos 指令 type 的功能,在命令列中輸入執行檔名稱(執行檔名稱請用 hw13_16)與欲顯示的檔案名稱(為一文字檔)後,即可將該檔案的內容顯示在螢幕中,如下面的範例:
C:\prog> hw13_16 welcome.txt Welcome to the world of C language
- 動態記憶體配置
- 鏈結串列
- 鏈結串列的操作
試利用
malloc()
配置可存放一個整數的記憶空間,並讓指標變數ptr
指向它,然後把ptr
指向的整數設值為 12,接著將它平方,最後把所得的結果列印出來。
於 prog14_1 中,第 6 行所宣告的變數
i
並不是用動態記憶體的方式配置記憶空間給它。試修改它,使得變數i
的記憶空間是由malloc()
所配置。
試以
malloc()
配置 3 個可存放double
型態的變數(即利用malloc(3 * sizeof(double))
的語法)之記憶空間,然後在for
迴圈裡,分別以scanf()
函數輸入 1.4、2.8 和 1.9 這三個浮點數,最後再計算他們的總和與平均值。
試修改習題 3,使得
malloc()
函數是寫在for
迴圈裡。也就是說,習題 3 是一次配置 3 個記憶空間,而本習題則是在for
迴圈裡一次配置一個可存放double
型態之變數的記憶空間,然後分別以scanf()
函數輸入 1.4、2.8 和 1.9 這三個浮點數,最後再計算他們的總和與平均值。
在 prog14_2 中,第 6 行所宣告的變數
num
與i
都不是利用動態記憶體的方式配置記憶空間給它們。是修改之,使得變數num
與i
的記憶空間是由malloc()
所配置。
試修改 prog14_2, 使得程式的輸出為所有學生成績之平均。
試撰寫一函數
int insertElement(int *arr, int item, int pos, int length)
,可將整數item
插入長度為length
的陣列arr
中,索引值為pos
的位置,傳回值為插入後,陣列arr
的長度。例如,若陣列arr = {12, 56, 37, 63}
。item = 10
,pos = 2
,length = 4
,則插入後,陣列的內容會變成{12, 56, 10, 37, 63}
,length
則變成 5。
試撰寫一函數
int deleteElement(int *arr, int pos, int length)
,可將長度為length
的陣列arr
中,索引值為pos
的位置的元素刪除,傳回值為插入後,陣列arr
的長度。例如,若陣列arr = {12, 56, 37, 63}
,pos = 1
,length = 4
,則刪除索引值為 1 的元素後,陣列的內容會變成{12, 37, 63}
,length
則變成 3。
試參考 prog14_3 的寫法,請建立具有 4 個節點的鏈結串接,節點的資料依序為 12, 38, 64, 37,建好之後,請將整個鏈結串列列印出來。
接續習題 9,請在第 2 個節點之後插入一個資料值為 92 的新節點,並印出插入後的鏈結串列。
接續習題 9,請將第二個節點(資料值為 38 的節點)刪除,並印出刪除後的鏈結串列。
試修改習題 9,使得 4 個節點均是以動態記憶體配置來完成。
接續習題 12,請在第 3 個節點之後插入一個資料值為 47 的新節點,並印出插入後的鏈結串列。
接續習題 12,請將第 2 與第 3 個節點(資料值為 38 與 64 的節點)刪除,並印出刪除後的鏈結串列。
於 prog14_4 中,在程式結束之前,我們並沒有釋放被
malloc()
所佔去的記憶空間。請修改它,使得儲存串列的記憶空間可以被釋放。
於 prog14_4 的第 9 行中,我們已經把型態
struct node
定義成NODE
型態。但在許多場合,我們會使用到指向NODE
型態的指標,如 prog14_4 的第 14 行即是。事實上,我們可以再把指向NODE
型態的指標利用typedef
關鍵字定義成一個新的形態:typedef struct node NODE; /* 定義型態 NODE */ typedef struct node* NODEp; /* 定義新的形態 NODEp */在上面的兩行敘述中,由於第一行已經定義了
struct node
為NODE
型態,因此接下來的struct node*
就可以寫成NODE*
,所以可以把上面兩行改寫成如下的敘述:typedef struct node NODE; /* 定義型態 NODE */ typedef NODE* NODEp; /* 定義新的形態 NODEp */試利用這個新的形態
NODEp
改寫 prog14_4,使得程式碼裡,所有指向NODE
型態的指標都是使用NODEp
來宣告。
試以陣列
arr[] = {12, 43, 56, 34, 98, 76, 43, 24}
建立一個鏈結串列,然後將它列印出來。
接續習題 17,試在節點 56 之後插入一個新的節點 88,並測試之。
接續習題 17,試刪除節點 12、34 與 24,並測試之。
試撰寫一函數
NODE *insertFirstNode(NODE *first, int item)
,可在串列的第一個位置插入資料值為item
的節點,傳回值為指向此串列第一個節點(即新插入之節點)的指標。撰寫好後,請以陣列arr[] = {12, 43, 56, 34}
建立一個鏈結串列,然後在此串列的第一個位置插入資料值為 53 的節點。
試撰寫一函數
int listLength(NODE *first)
,可用來計算鏈結串列中,共有多少個節點。撰寫好後,請以陣列arr[] = {12, 43, 56, 34, 98}
建立一個鏈結串列,然後以listLength()
測試此串列的長度。
試撰寫一函數
void combineList(NODE *first1, NODE *first2)
,可將串列 2 鏈接在串列 1 的後面,其中first1
與first2
分別為串列 1 與串列 2 中,第一個節點的位址。撰寫好後,請分別以陣列arr1[] = {12, 43, 56, 34, 98}
與陣列arr2[] = {36, 77, 99}
建立兩個鏈結串列,然後利用combineList()
函數將它們串接起來。
- 數字系統與位元、位元組
- 二進位系統
- 其他的進位系統
- 位元運算子
- 位元欄位
試以 prog15_1 的
show_binary()
函數來驗證習題 5 的計算結果。
試撰寫一函數
void show_decimal(char *arr, int n)
,可接收$n$ 個位數的二進位數值,並於函數內印出此二進位數值的十進位。
若於程式裡宣告了下列的整數:
int a = 159; int b = 0147; int c = 0x618A;試完成下面的程式設計:
(a) 將變數
a
的值分別以八進位與十六進位列印出來。(b) 將變數
b
的值分別以十進位與十六進位列印出來。(c) 將變數
c
的值分別以八進位與十進位列印出來。
試撰寫一程式,可由鍵盤輸入一個八進位的整數,於程式內將此八進位數值轉換成十進位與十六進位,然後將它們列印出來。
設
$a = 154$ ,$b = 67$,試撰寫程式碼求算下列各式,並請以手算繪圖的方式來驗證程式執行的結果:(a) a & b
(b) a | b
(c) a ^ b
試修改 prog15_3,使得整數是向右移兩個位元,並仿照圖 15.4.5 的方式,繪出右移兩個位元的過程,並指出右移後整數值的改變。
試修改 prog15_4,使得結構變數
tom
中,每一個位元欄位的值是可以由鍵盤來輸入。
試依下列題意作答:
(a) 修改 prog15_4,於結構
status
內加入身高height
與體重weight
兩個欄位,height
佔了 8 個位元,單位為公分,weight
也佔了 8 個位元,單位為公斤。(b) 利用 (a) 的結構宣告一個結構變數
maruco
,並設定初值給它。maruco
的基本資料為女生、未婚、9 歲、162 公分與 50 公斤。(c) 試撰寫程式碼,印出變數
maruco
的相關資料。(d) 試問變數
maruco
佔了多少個位元組?請以sizeof()
來驗證。
試著利用位元欄位定義出如下的電腦設備結構,結構名稱為
computer
:軟碟數目:佔 3 個位元,欄位名稱為
folppy
硬碟數目:佔 6 個位元,欄位名稱為
hard_disk
光碟機數目:佔 6 個位元,欄位名稱為
cd_rom
印表機數目:佔 5 個位元,欄位名稱為
printer
請於鍵盤中輸入使用者的各種電腦設備數量,然後於程式內,將整個結構的內容列印出來。
- 認識 C++
- 簡單的例子
- 函數的多載
- 認識類別
- 公有成員與私有成員
- 建構元
試將第二章的範例 prog2_1 改成以 C++ 的語法來撰寫。
試將第四章的範例 prog4_9 改成以 C++ 的語法來撰寫。
試將第七章的範例 prog7_6 改成以 C++ 的語法來撰寫。
試將第八章的範例 prog8_2 改成以 C++ 的語法來撰寫。
試修改習題 6,使得傳入
add()
的函數引數,可同為整數或是同為浮點數。add()
的傳回型態必須與引數的型態相同。
試將絕對值函數
my_abs()
多載,使得my_abs()
的引數型態可為整數,或是浮點數。my_abs()
的傳回型態必須與引數的型態相同。
試撰寫
max()
函數的多載,其中max
引數的型態為int
,且可以有兩個或三個引數,函數的傳回值為這些引數的最大值,傳回值的型態也試int
。
設類別
Caaa
的定義為:class Caaa { public: int a; int b; int c; };試在程式碼裡完成下列各敘述:
(a) 試在主函數
main()
裡建立一個Caaa
類別型態的變數obj
。(b) 將
obj
資料成員a
的值設為 1,b
的值設為 3。(c) 計算
$a + b$ 之後設給成員c
。(d) 印出
a
、b
與c
的值。
參考程式 prog16_8,在類別
CWin
裡,除了保有原來的成員之外,請加入一個具有 50 個字元陣列的資料成員title
,代表視窗的標題,然後定義一set_title()
函數,用來設定視窗物件的標題,以及display()
函數,用來顯示視窗的標題,並測試set_title()
與display()
函數。
試設計一個
CBox
類別,具有length
、width
與height
三個整數的資料成員,並完成下列的程式設計:(a) 定義
int volume()
函數,用來傳回CBox
物件的體積。(b) 定義
int surfactArea()
函數,用來傳回CBox
物件的表面積。
試設計一長方形類別
CRect
,內含width
、height
與weight
三個資料成員,並設計set()
函數的多載,使其具有下面的功能:void set(double wg) // 可設定長方形的重量 void set(int w, int h) // 可設定長方形的寬和高 void set(double wg, int w, int h) // 可設定長方形的重量、寬和高同時也請撰寫
show()
函數,用來顯示資料成員的值,並以實例測試之。
在 prog16_13 中,如果把函數
area()
的存取屬性改為private
,則程式是否還能正確執行?試撰寫一程式,將area()
的存取屬性改為private
,用以驗證您的想法是否正確。
設有一
CSphere
類別,可用來表示一個圓球。此類別內含x
、y
與z
三個資料成員,用來表示圓心的位置,另外還有一個radius
資料成員,代表圓球的半徑。其部分程式碼的撰寫如下:class CSphere { private: int x; // 圓心的 x 座標 int y; // 圓心的 y 座標 int z; // 圓心的 z 座標 int radius; // 圓球的半徑 }(a) 試在
CSphere
類別裡加入void setLocation()
函數,用來設定圓球之圓心位置。(b) 試在
CSphere
類別裡加入void setRadius()
函數,用來設定圓球之半徑。(c) 試在
CSphere
類別裡加入double volume()
函數,用來傳回CSphere
物件的體積(圓球的體積為$\frac{4}{3} \pi r^3$ )。(d) 試在
CSphere
類別裡加入void showCenter()
函數,用來顯示CSphere
物件之圓心座標。
假設
CRectangle
類別的定義如下:class CRectangle { private; int width; int height; }(a) 試設計一個建構元
CRectangle(int w, int h)
,當此建構元呼叫時,便會自動設定$width = w$ ,$height = h$。(b) 請接續 (a) 的部分,請再設計一個沒有引數的建構元
CRectangle()
,使得當此建構元被呼叫時,便會自動設定$width = 10$ ,$height = 8$。
請參考習題 12,將
length
、width
與height
三個資料成員的存取屬性改為private
,並試設計兩個CBox()
建構元,第一個CBox()
建構元不須傳入任何引數,但它可以將length
、width
與height
三個資料成員的值均設為 1。第二個CBox()
建構元則可接收三個整數型態的引數,分別用來設定length
、width
與height
三個資料成員的值。