z2x3c4v5bz / Learning--C_intro_4th_ed

書籍「C 語言教學手冊 第四版」練習題我的解答,約於 2016 年左右完成,供同為自學的夥伴參考。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

C 語言教學手冊 第四版(習題個人解答)

discussions forks stars release license

Abstract

Title: C 語言教學手冊 第四版

Auther: 洪維恩

Publisher: 旗標出版股份有限公司

Introduction:

  • 循序漸進從頭打好 C 語言基礎
  • 豐富範例展示語法最容易理解
  • 每章附有自我評量教學最適用
  • 資料結構基本觀念導入最易懂

thumbnail

※ 習題練習的作業系統為 Microsoft Windows 7/10 x64,並採用軟體 Dev-C++ 5.0.0.5 為開發工具。

※ 原諒我題目內不附圖示。

※ 請留意,文中數學公式在瀏覽器頁面中可能無法正確顯示。

※ 圖書封面、圖書資訊、章節內容、習題皆為版權作者、出版商所有,本站所刊內容僅供教育、學習使用。

Table of Contents

Chapter 01 -- 認識 C 語言

  • C 語言概述
  • 程式的規劃與實作
  • 撰寫第一個 C 程式
  • 編譯與執行的過程
  • 本書的編排與慣例

試修改 prog1_1,使得它可以印出 "我愛C語言" 一行中文字。

試修改 prog1_1,使得它可以印出 "我愛C語言" 及 "這是我的第一個C語言程式"兩行中文字。

試撰寫一程式,利用 printf() 函數印出下面的圖案(不須使用迴圈,每一列星號請用一個 printf() 函數來列印):

試以 printf() 函數印出下面的圖案(不需使用迴圈,每一列星號請用一個 printf() 函數來列印):

試撰寫一程式,利用 printf() 函數以星號和空白字元印出下面的圖案:

table_of_contents

Chapter 02 -- C 語言基本概述

  • 簡單的例子
  • 解析 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 重新編排後,再加上適當註解,使得程式碼更具可讀性。

table_of_contents

Chapter 03 -- 基本資料型態

  • 變數與常數
  • 基本資料型態
  • 查詢常數、變數或資料型態所佔位元組
  • 資料型態的轉換

試修改 prog3_1,使得第 9 行與第 10 行可分別印出 num1num2 的平方值。第 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,應如何修改程式碼?

Question 3-15

請參閱下面的程式碼,然後回答接續的問題:

/* 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

假設浮點數變數 num1num2 的值分別為 123.39f3.8e5f,試撰寫一程式,將這兩個變數值轉換成整數。

Question 3-19

請參閱下面的程式碼,然後回答接續的問題:

/* 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

table_of_contents

Chapter 04 -- 格式化的輸出與輸入

  • 輸出函數 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" 字串裡所有的英文字母全部讀出,並列印出來。

Question 4-17

請先執行下面的程式碼,然後回答接續的問題:

/* 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() 函數。

table_of_contents

Chapter 05 -- 運算子、運算式與敘述

  • 運算式與運算子
  • 運算子的優先順序
  • 運算式
  • 運算式的型態轉換

Question 5-1

請寫出下列程式的輸出結果,並撰寫完整的程式碼來驗證之:

(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$,試撰寫一程式,可輸入圓球半徑,經計算後輸出圓球體積。

table_of_contents

Chapter 06 -- 選擇性敘述

  • 我的程式會轉彎--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}$$

試撰寫一程式,由程式中宣告並設定 abc 三個浮點數的初值,代表方程式 $ax^2 + bx + c = 0$ 的係數,然後利用判別式 $b^2 - 4ac$ 的值來計算方程式的根。

【註】

$b^2 - 4ac &gt; 0$ 方程式有二個實根,$x = \frac{-b ± \sqrt{b^2 - 4ac}}{2a}$。

$b^2 - 4ac = 0$ 方程式有兩個相等實根,$x = - \frac{b}{2a}$。

$b^2 - 4ac &lt; 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 敘述來完成)。

table_of_contents

Chapter 07 -- 迴圈

  • 結構化程式設計
  • 使用 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 之間所有整數的平方值,最後再印出這些平方值的總和。

Question 7-18

試依下面的題意作答:

(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");

Question 7-23

試依下面的題意作答:

(a) 試修改習題 19,把 do while 迴圈改以 for 迴圈來撰寫。

(b) 試修改習題 19,把 do while 迴圈改以 while 迴圈來撰寫。

(c) 您覺得習題 19 分別以 forwhiledo while 迴圈來撰寫時,比較起來哪一種迴圈寫起來較方便?為什麼?

Question 7-24

試依下面的題意作答:

(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 等皆為質數)。

試撰寫一程式,可由鍵盤讀入一個正整數,並找出小於此數的最大質數。

老王養了一群兔子,但不知有幾隻。三隻三隻數之,剩餘一隻;五隻五隻數之,剩餘三隻;七隻七隻數之,剩餘二隻;試問最少有幾隻兔子?

table_of_contents

Chapter 08 -- 函數

  • 簡單的函數範例
  • 函數的基本架構
  • 更多的函數應用範例
  • 遞迴函數
  • 區域、全域與靜態變數
  • 引數傳遞的機制
  • 前置處理器--#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 個梅森尼質數,並於主程式裡測試之。

Question 8-11

在《孫子算經》(此書約完成於西元 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

Question 8-12

試依序回答下面的問題:

(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?

Question 8-13

試依序回答下面的問題:

(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?

Question 8-14

試依序回答下面的問題:

(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?

Question 8-15

試依序回答下面的問題:

(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

Question 8-17

數學大師歐勒(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() 函數來求解分母)。

Question 8-18

試依序回答下列問題:

(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 的變數 ab 改以全域變數來撰寫,其他程式碼不更動,則執行結果是否會和 prog8_19 相同?為什麼?

在 prog8_19 中,當我們呼叫 add10() 之後,在 main() 裡變數 ab 的值並不會被加 10。試修改程式碼,使得當 add10() 被呼叫之後,ab 的值會加 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 的絕對值。

Question 8-35

試利用 8.8.2 節所建立的標頭檔 area.h 來計算下列各題:

(a) 半徑為 1.0 的圓面積。

(b) 長為 5.0,寬為 4.6 的長方形面積。

(c) 底為 12.2,高為 9.4 的三角形面積。

Question 8-36

試撰寫一個 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 含括到程式中,由鍵盤輸入兩個浮點數後,計算這兩個數的平均值及乘積。

table_of_contents

Chapter 09 -- 陣列與字串

  • 一維陣列
  • 二維陣列與多維陣列
  • 傳遞陣列給函數
  • 字串
  • 字串的輸入與輸出函數
  • 字串陣列

試撰寫一程式,宣告一個具有 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,然後利用鍵盤輸入數字,將陣列內的三個元素設值,最後於程式裡印出這三個元素。

Question 9-6

設陣列 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 裡的 AB 陣列為 $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 裡所有元素的平均值,其中 ROWCOL 是由前置處理器 #define 所定義的常數,ROW 代表陣列的列數,COL 為行數。

試撰寫一函數

void add(int A[ROW][COL], int B[ROW][COL], int C[ROW][COL])

可用來計算矩陣 AB 的相加,並把相加後的結果放到矩陣 C 裡。ROWCOL 是由前置處理器 #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] 的位址是 10arr[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 的寫法的優缺點。

table_of_contents

Chapter 10 -- 指標

  • 指標概述
  • 使用指標變數
  • 指標與函數
  • 指標與一維陣列
  • 指標與字串
  • 指向指標的指標--雙重指標

假設在程式碼裡宣告了下面的敘述:

float num = 4.2f;
int a1 = 4, a2 = 12;

於程式碼裡印出變數 numa1a2 的位址,並仿照圖 10.1.4 繪出變數於記憶體裡的配置情形。

假設在程式碼裡宣告了下面的敘述:

double b1 = 3.14;
int num = 5;

試於程式碼裡印出變數 b1num 的位址,並仿照圖 10.1.4 繪出變數於記憶體裡的配置情形。

假設在程式碼裡有如下的敘述:

float num = 12.6f, *ptr;
ptr = &num;

試撰寫一程式,列印出變數 num 與指標變數 ptr 的位址,並仿照圖 10.2.1 繪出變數於記憶體的配置情形。

試修改 prog10_5,使得在程式碼 6~18 行中,每執行完一行,便能印出變數 abptr1*ptr1ptr2*ptr2 的值。

於下表中,假設 a 的位址為 1000b 的位址為 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 的位址為 1000b 的位址為 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 = &pi;

試仿照 prog10_7 的做法,將 &piptr 傳入 address() 函數中,用來列印變數 pi 的值與位址,並仿照圖 10.3.1 繪製出記憶體的配置圖。

試撰寫一函數 void count(int *),可接收一個整數變數 num 的位址(num 的初值請設為 0)。每當 count() 函數被呼叫一次,主程式裡的 num 之值也會被加 1,並於主程式裡自行測試之。

試修改第八章 prog8_19,使得當 add10() 函數被呼叫時,傳入 add10() 裡的變數 ab 的值均會被加 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 的算術運算來找尋陣列裡元素的最大值及最小值。

試撰寫一程式,利用指標的算術運算來找出一維整數陣列中,元素最大值的索引值與最小值的索引值(一維整數陣列的元素值請自行設定)。

Question 10-18

設程式碼裡有如下的字串宣告:

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) 小題裡所求得的真實位址。

table_of_contents

Chapter 11 -- 結構與其他資料型態

  • 認識結構
  • 巢狀結構
  • 結構陣列
  • 指向結構的指標
  • 以結構為引數傳遞到函數
  • 列舉型態
  • 使用自訂的型態--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 的格式印出結構 holidayfestival 的值。mm 代表月份,佔有 2 格;dd 代表日期,佔有 2 格;yyyy 代表年份,佔有 4 格,如 06/18/2004。

於習題 2 中,結構 date 型態的變數佔了多少個位元組?試撰寫一程式利用 sizeof() 檢驗之,並仿照圖 11.1.1 繪出結構 date 的資料成員。

試撰寫一程式,使其能夠完成下列功能:

(a) 建立一時間結構 time,其成員包括 hour(小時)、minutes(分)及 second(秒),其中 hourminutes 的型態皆為 int,而 second 的型態則為 double

(b) 宣告一個結構 time 型態的變數 start,並設定初值為 {12, 32, 25.49}

(c) 宣告一個結構 time 型態的變數 end,並設定初值為 {15, 12, 17.53}

(d) 以 hh:mm:ss.ss 的格式印出結構 startend 的值。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,使得它的成員除了包含有原來的 yearmonthday 之外,在加入習題 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() 函數裡,結構 stmath 成員的值加 10,於主函數 main() 裡的結構 s1math 成員之值是否也會被加 10?為什麼?

假設結構 data 的定義為

struct data
{
   char name[10];
   int math;
};

試設計一函數 void add5(struct data *),只要函數 add5() 被呼叫,則傳入之引數的 math 成員之值便會被加 5。

試參考習題 4,請撰寫一函數 void display(struct time),用來列印變數 startendelapse 之值。列印的格式請用 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,並於函數裡將陣列元素排列。分數越高者排列越前面。

Question 11-18

下面的程式碼裡定義了列舉型態 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) 列舉常數 FALSETRUE 的預設值各是多少?

(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。

table_of_contents

Chapter 12 -- 檔案處理

  • 檔案的觀念
  • 有緩衝區的檔案處理函數
  • 無緩衝區的檔案處理函數
  • 二進位檔案的使用

試撰寫一程式,以每 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,使得檔案在拷貝的同時,也可以於螢幕上印出拷貝的內容。

Question 12-11

試依下列的步驟完成程式設計:

(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-16

試依下列的步驟完成程式設計:

(a) 試產生 10 個 1~16 之間的整數亂數,並將它寫入二進位檔 "rand.bin" 內。

(b) 撰寫一程式讀取二進位檔 rand.bin 的內容,並找出這 10 個數值的最大值與平均值。

Question 12-17

試依下列步驟完成程式設計:

(a) 修改 prog12_8,是建立 3 個 struct data 型態之物件陣列 student,並將它寫入二進位檔 "student.bin" 內。

(b) 撰寫一程式讀取 (a) 中所建立之二進位檔的內容,並將結果顯示在螢幕上。

Question 12-18

設程式裡有定義下列的變數:

int arr[] = {11326, 4445, 15589, 23740, 76840};

(a) 試將陣列 arr 的值,以純文字檔的模式儲存在檔案 "hw12_18.txt" 裡。

(b) 試將陣列 arr 的值,以二進位檔的模式儲存在檔案 "hw12_18.bin" 裡。

(c) 試比較檔案 hw12_18.txt 與 hw12_18.bin 的大小,並分析就節省記憶空間而言,採用哪一種方式來儲存數字較為經濟。

table_of_contents

Chapter 13 -- 大型程式的發展

  • 程式的模組化與實作
  • 於不同檔案裡使用全域變數
  • 條件式編譯
  • 命令列引數的使用

在 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

table_of_contents

Chapter 14 -- 動態記憶體配置與鏈結串列

  • 動態記憶體配置
  • 鏈結串列
  • 鏈結串列的操作

試利用 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 行所宣告的變數 numi 都不是利用動態記憶體的方式配置記憶空間給它們。是修改之,使得變數 numi 的記憶空間是由 malloc() 所配置。

試修改 prog14_2, 使得程式的輸出為所有學生成績之平均。

試撰寫一函數 int insertElement(int *arr, int item, int pos, int length),可將整數 item 插入長度為 length 的陣列 arr 中,索引值為 pos 的位置,傳回值為插入後,陣列 arr 的長度。例如,若陣列 arr = {12, 56, 37, 63}item = 10pos = 2length = 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 = 1length = 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 nodeNODE 型態,因此接下來的 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 的後面,其中 first1first2 分別為串列 1 與串列 2 中,第一個節點的位址。撰寫好後,請分別以陣列 arr1[] = {12, 43, 56, 34, 98} 與陣列 arr2[] = {36, 77, 99} 建立兩個鏈結串列,然後利用 combineList() 函數將它們串接起來。

table_of_contents

Chapter 15 -- 位元處理

  • 數字系統與位元、位元組
  • 二進位系統
  • 其他的進位系統
  • 位元運算子
  • 位元欄位

試以 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

請於鍵盤中輸入使用者的各種電腦設備數量,然後於程式內,將整個結構的內容列印出來。

table_of_contents

Chapter 16 -- 邁向 C++ 之路

  • 認識 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) 印出 abc 的值。

參考程式 prog16_8,在類別 CWin 裡,除了保有原來的成員之外,請加入一個具有 50 個字元陣列的資料成員 title,代表視窗的標題,然後定義一 set_title() 函數,用來設定視窗物件的標題,以及 display() 函數,用來顯示視窗的標題,並測試 set_title()display() 函數。

試設計一個 CBox 類別,具有 lengthwidthheight 三個整數的資料成員,並完成下列的程式設計:

(a) 定義 int volume() 函數,用來傳回 CBox 物件的體積。

(b) 定義 int surfactArea() 函數,用來傳回 CBox 物件的表面積。

試設計一長方形類別 CRect,內含 widthheightweight 三個資料成員,並設計 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 類別,可用來表示一個圓球。此類別內含 xyz 三個資料成員,用來表示圓心的位置,另外還有一個 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,將 lengthwidthheight 三個資料成員的存取屬性改為 private,並試設計兩個 CBox() 建構元,第一個 CBox() 建構元不須傳入任何引數,但它可以將 lengthwidthheight 三個資料成員的值均設為 1。第二個 CBox() 建構元則可接收三個整數型態的引數,分別用來設定 lengthwidthheight 三個資料成員的值。

table_of_contents

About

書籍「C 語言教學手冊 第四版」練習題我的解答,約於 2016 年左右完成,供同為自學的夥伴參考。

License:MIT License


Languages

Language:C 96.8%Language:C++ 3.2%