You are on page 1of 117

最新C++程式語言習題解答

第1章
第2章
第3章
第4章
第5章
第6章
第7章
第8章
第9章
第10章
第11章
第12章
第13章
第14章
第15章
第16章
第1章

[學習評量]

1.(a)

2.(b)

3.(c)

4.(c)

5.(b)

6.(d)

7.(a)

8.(c)

9.(d)

10.(c)
第2章

[學習評量]

1.(b)

2.(b)

3.(c)

4.(a)

5.(b)

6.(c)

7.(b)

8.(d)

9.cpp

10.main()函式

[程式練習]

1.

#程
#include<iostream>

int main()
{
std::cout << "春眠不覺曉, 處處聞啼鳥" << endl
<< "夜來風雨聲, 花落知多少";
}
###

2.
(1)程式第 5 行:
std::cout << //我要列印的訊息"測試一下"
修正方式一,將註解移到要輸出的字串後:
std::cout << "測試一下" //我要列印的訊息
修正方式二,將註解改用區塊式註解:
std::cout << /*我要列印的訊息*/"測試一下"
(2)第6行:endl之前要加std::。

3.
#程
#include<iostream>

int main()
{
std::cout << "* " << endl
<< "* * " << endl
<< "* * * " << endl
<< "* * * * " << endl
<< "* * * * *";
}
###

4.
(1)第3行:main()函式名稱不可大寫。
(2)第5行:endl之前要加std::。
(3)第5行:敘述之後要加分號。

5.
第二行的 use 要改成 using。
第3章

[學習評量]

1.(c)

2.(c)

3.可以;不可

4.typedef

5.2;1;8

6.(d)

7.(b)

8.(d)

9.(d)

10.(a)

[程式練習]

1.

#include<iostream>
#define SIZE 100

int main()
{
std::cout << "SIZE = " << SIZE << std::endl;
}

2.
#include<iostream>
using namespace std;

int main()
{
int a = 10;
float b = 101.7;
char c = 'c';
std::cout << "a = " << a << endl
<< "b = " << b << endl
<< "c = " << c;
}
3.

#include<iostream>

int main()
{
const int width = 12;
const int height= 35;

std::cout << "寬為 " << width << " 高為 " << height
<< " 的矩形面積為 " << width * height;
}

4.
#include<iostream>

int main()
{
std::cout << "3 + 2 = " << 3 + 2;
}

5.
#include<iostream>

int main()
{
std::cout << "若 f = 1*2*3*4*5, 則 f = "
<< 1*2*3*4*5;
}

6.
#include<iostream>
using namespace std;

int main()
{
int x;
cout << "計算 y=2*x" << endl
<< "請輸入 x 的值:";
cin >> x;
cout << "y = " << 2*x;
}

7.
#include<iostream>

int main()
{
char c = '\'';
int i = c; // 將 c 所存的字碼值指定給整數變數 i
std::cout << c << " 的 ASCII 碼為 " << i;
}

8.
#include<iostream>

int main()
{
std::cout << "我正在學習 \"C++\" 程式語言";
}

9.
#include <iostream>
using namespace std;

int main()
{
int a=10, b=20, c = 30; // 宣告三個 int 變數
int temp; // 宣告暫存整數變數 temp

cout << "交換前 a = " << a << "\tb = " << b


<< "\tc = " << c << ';' << endl;

temp = c; // 將變數 c 的值指定給暫存變數


c = b; // 把變數 b 的值指定給 c
b = a; // 把變數 a 的值指定給 b
a = temp; // 將暫存變數所存的 c 值指定給 a

cout << "交換後 a = " << a << "\tb = " << b


<< "\tc = " << c << ';' << endl;
}

10.
#include <iostream>
using namespace std;

int main()
{
char upper, lower = 'z'; // 宣告兩個字元變數

upper = lower - 32;


cout << lower << " 的大寫是 " << upper << endl;
}
第4章

[學習評量]

1.(b)

2.(c)

3.(b)

4.5

5.(a)

6.(b)

7.
(1)0
(2)1
(3)0
(4)1

8.
(1)1
(2)1
(3)1
(4)0

9.
(1)1
(2)2

10.
(1)0
(2)0
(3)0
(4)0

[程式練習]

1.

#include<iostream>

int main()
{
std::cout << "277/13 = " << 277/13 << "..." << 277%13;
}

2.
#include<iostream>
using namespace std;

int main()
{
double c;
cout << "請輸入攝氏溫度:";
cin >> c;
cout << "攝氏 " << c << " 度等於華氏 " << c*9/5+32 << " 度";
}

3.

#include<iostream>
using namespace std;

int main()
{
int ticketprice = 137, coin;

cout << "票價為 " << ticketprice << " 元時,至少需投入\n";

cout << "50元硬幣 " << (coin = ticketprice / 50) << " 個\n";

ticketprice -= coin*50;
cout << "10元硬幣 " << (coin = ticketprice / 10) << " 個\n";

ticketprice -= coin*10;
cout << "5元硬幣 " << (coin = ticketprice / 5) << " 個\n";

ticketprice -= coin*5;
cout << "1元硬幣 " << (coin = ticketprice) << " 個\n";
}

4.
#include<iostream>
using namespace std;

int main()
{
double weight;
cout << "請輸入重量(公斤):";
cin >> weight;
cout << weight << " 公斤等於 " << weight*2.2 << " 英磅";
}

5.
#include<iostream>
using namespace std;
int main()
{
int a,b;
cout << "請輸入兩個整數(用空白隔開):";
cin >> a >> b;
cout << a << " 和 " << b << " 的平方和等於 " << (a*a+b*b);
}

6.
#include<iostream>
using namespace std;

int main()
{
int l,w,h;
cout << "請輸入長方體的長:";
cin >> l;
cout << "請輸入長方體的寬:";
cin >> w;
cout << "請輸入長方體的高:";
cin >> h;

cout << "長寬高為 " << l << "," << w << "," << h
<< " 的長方體體積為 " << (l*w*h);
}

7.
#include<iostream>
using namespace std;

int main()
{
double stepA = 1, stepB = 0.75;
cout << "經過 " << 200 /(stepA + stepB) << " 秒後會相遇";
}

8.
#include<iostream>
using namespace std;

int main()
{
double r;
const double pi = 3.1415926;
cout << "請輸入球體半徑:";
cin >> r;
cout << "球體體積為 " << (pi*r*r*r*4/3);
}
9.
#include <iostream>
using namespace std;

int main()
{
int x=2;

cout << "2 的 1 次方等於 " << (x << 0)


<< "\n2 的 2 次方等於 " << (x << 1)
<< "\n2 的 3 次方等於 " << (x << 2)
<< "\n2 的 4 次方等於 " << (x << 3)
<< "\n2 的 5 次方等於 " << (x << 4)
<< "\n2 的 6 次方等於 " << (x << 5)
<< "\n2 的 7 次方等於 " << (x << 6)
<< "\n2 的 8 次方等於 " << (x << 7);
}

10.
#include <iostream>
using namespace std;

int main()
{
// 因尚未學習流程控制,故假設已算出停車時數為 5 小時
int parking_hour = 5, fee;

// 計算第 5 小時的停車費
fee = (parking_hour - 4) * 2 * 60;

// 加上第 3、4 小時的停車費


fee += 2 * 2 * 40;

// 加上第 1、2 小時的停車費


fee += 2 * 2 * 30;

std::cout << "停車費為 " << fee << " 元";


}
第5章

[學習評量]

1.(a)

2.(d)

3.
(a) if (x > y)
x = y;
else
y = x;

(b) if (x > y && x < z)


x = y + z;
else
z = x - y;

4.(a)

5.(c)

6.(a)

7.
(a) while(...) 後要加分號
(b) for() 應用分號分隔出初始、條件、控制算式
(c)
(d)
(e) else 及 if 是兩個關鍵字,不可連在一起

8.
(a)10
(b)1
(c)45
(d)0

9.(a)

10.各 case 段落的最後面應加上 break;

[程式練習]

1.
#include<iostream>
using namespace std;

int main()
{
int x;
cout << "請輸入一個整數:";
cin >> x;
if (x%2 == 0)
cout << "你輸入的是偶數。";
else
cout << "你輸入的是奇數。";
}

2.
#include<iostream>
using namespace std;

int main()
{
int score;
cout << "請輸入學生成績:";
cin >> score;

if (score >= 90 && score <= 100)


cout << "等第為 A。";
else if (score >= 80 && score <= 89)
cout << "等第為 B。";
else if (score >= 70 && score <= 79)
cout << "等第為 C。";
else if (score >= 60 && score <= 69)
cout << "等第為 D。";
else if (score >= 0 && score <= 59)
cout << "等第為 E。";
else
cout << "輸入錯誤。";
}

3.
#include<iostream>
using namespace std;

int main()
{
int choice;
cout << "請問要計算(1)三角形、(2)矩形、或(3)梯形的面積:"
cin >> choice;

int x,y,z;
switch (choice) {
case 1: // 三角形
cout << "請輸入三角形的底:";
cin >> x;
cout << "請輸入三角形的高:";
cin >> y;
cout << "此三角形的面積為 " << x * y / 2;
break;
case 2: // 矩形
cout << "請輸入矩形的長:";
cin >> x;
cout << "請輸入矩形的寬:";
cin >> y;
cout << "此矩形的面積為 " << x * y;
break;
case 3: // 梯形
cout << "請輸入梯形的上底:";
cin >> x;
cout << "請輸入梯形的下底:";
cin >> y;
cout << "請輸入梯的高:";
cin >> z;
cout << "此梯形的面積為 " << (x + y) * z / 2;
break;
default:
cout << "輸入錯誤。";
}
}

4.
#include<iostream>
using namespace std;

int main()
{
int min;
cout << "請輸入通話分鐘數:";
cin >> min;

if (min >= 1500)


cout << "電話費為 " << min * 0.9 * 0.8 << " 元";
else if (min >= 800)
cout << "電話費為 " << min * 0.9 * 0.9 << " 元";
else if (min >= 0)
cout << "電話費為 " << min * 0.9 << " 元";
else
cout << "輸入錯誤。";
}

5.
#include<iostream>
using namespace std;
int main()
{
int sex;
double height;
cout << "請輸入性別(1)男(2)女:";
cin >> sex;
cout << "請輸入身高(公分):";
cin >> height;

switch (sex) {
case 1: // 男性
cout << "男性身高 " << height << " 公分者的標準體重為 "
<< (height - 80) * 0.7 << " 公斤";
break;
case 2: // 女性
cout << "女性身高 " << height << " 公分者的標準體重為 "
<< (height - 70) * 0.6 << " 公斤";
break;
default:
cout << "輸入錯誤。";
}
}

6.
#include<iostream>
using namespace std;

int main()
{
int x,again;
cout << "計算 1 到指定數值間的 3 的倍數總和。\n";

do {
cout << "請輸入指定數值:";
cin >> x;
double sum = 0;

for (int i=1; i<=x; i++) // 計算範圍內


if (i%3 == 0) // 可被 3 整除的
sum += i; // 所有數值的總和

cout << "1 到 " << x << " 間的所有 3 的倍數總和為 "
<< sum << endl;
cout << "\n還要再算一次嗎?(輸入0表示要再算一次)";
cin >> again;
} while (again == 0);
}

7.
#include<iostream>
using namespace std;

int main()
{
int h;
cout << "請輸入要繪製的三角形高度(最大 40):";
cin >> h;
if (h > 40)
h = 40;

for (int i=1; i<=h; i++) { // 控制畫第幾行的迴圈


for (int j=1; j<=(h-i); j++) // 畫每行開頭空白的迴圈
cout << ' ';
for (int k=1; k<=(2*i-1); k++) // 畫每行 * 的迴圈
cout << '*';
cout << '\n';
}
}

8.
#include<iostream>
using namespace std;

int main()
{
int h;
cout << "請輸入要繪製的菱形高度(最大 79):";
cin >> h;
if (h > 79)
h = 79;
else if (h%2 == 0)
h--;

// 先畫上半部
h = (h+1) / 2;
for (int i=1; i<=h; i++) { // 控制畫第幾行的迴圈
for (int j=1; j<=(h-i); j++) // 畫每行開頭空白的迴圈
cout << ' ';
for (int k=1; k<=(2*i-1); k++) // 畫每行 * 的迴圈
cout << '*';
cout << '\n';
}

// 再畫下半部
h--;
for (int i=h; i>1; i--) { // 控制畫第幾行的迴圈
for (int j=1; j<=(h-i+1); j++) // 畫每行開頭空白的迴圈
cout << ' ';
for (int k=1; k<=(2*i-1); k++) // 畫每行 * 的迴圈
cout << '*';
cout << '\n';
}
}

9.
#include<iostream>
using namespace std;

int main()
{
int password;
cout << "請輸入密碼(4位整數):";
cin >> password;

int confirm;
cout << "請再輸入一次:";
cin >> confirm;

if (password == confirm)
cout << "正確。";
else
cout << "兩次輸入的密碼不同。";
}

10.
#include<iostream>
using namespace std;

int main()
{
int jackpot1 = 1;
int jackpot2 = 2;
int jackpot3 = 3;
int jackpot4 = 4;

int input1,input2,input3,input4;
cout << "請輸入4個個位數字(以空白隔開):";
cin >> input1 >> input2 >> input3 >> input4;

if (jackpot1 == input1 && jackpot2 == input2 &&


jackpot3 == input3 && jackpot4 == input4)
cout << "你中獎了!";
else
cout << "謝謝惠顧!";
}
第6章

[學習評量]

1.一個

2.傳回值型別、函式名稱、參數型別

3.(c)

4.(b)

5.(b)

6.(b)

7.return

8.void

9.
(1) double meanvalue(int,int,int);
(2) void sum(int,int);
(3) void sum();

10.(a)

[程式練習]

1.

#include<iostream>
using namespace std;

void printMessage(int line)


{
for(int i=1;i<=line;i++)
cout << "HELLO C++\n";
}

int main()
{
int line;
cout << "要輸出幾行訊息?";
cin >> line;
printMessage(line);
}

2.
#include<iostream>
using namespace std;

double getMax(double a, double b)


{
if (a>=b)
return a;
else if (b>a)
return b;
}

int main()
{
double a,b;
cout << "請輸入兩個數值(用空白隔開):";
cin >> a >> b;
cout << "最大值為 " << getMax(a,b);
}

3.

#include<iostream>
using namespace std;

double calc(int i);


{
if (i>1)
return i+calc(i-1);
else
return i;
}

int main()
{
cout << "1 加到 100 等於 " << calc(100);
}

4.
#include<iostream>
using namespace std;

double calc(int n)
{
double sum=0;
for(int i=1;i<=n;i++)
sum += 1.0/i;
return sum;
}

int main()
{
int n;
cout << "請輸入 n 的值:";
cin >> n;
cout << "1 到 " << n << " 所有數值的倒數和為 " << calc(n);
}

5.
#include<iostream>
using namespace std;

double calc(int n)
{
double sum=0;
for(int i=1;i<=n;i++)
sum += i;
return sum;
}

int main()
{
int n;
cout << "請輸入 n 的值:";
cin >> n;
cout << "1 到 " << n << " 所有數值的總和為 " << calc(n);
}

6.
#include<iostream>
using namespace std;

void thirteen(int n)
{
int i=13;
while(i<=n) {
cout << i << ' ';
i+=13;
}
}

int main()
{
int n;
cout << "請輸入 n 的值:";
cin >> n;
cout << "1 到 " << n << " 間所有 13 的倍數有: ";
thirteen(n);
}

7.
#include<iostream>
#include<time>
using namespace std;

double mypow(double x, int n)


{
if (n>=1) {
return x*mypow(x,n-1)
else
return 1;
}
}

int main()
{
int x,n;
cout << "計算 x 的 n 次方";
cout << "請輸入 x 及 n 的值(以空白隔開)";
cin >> x >> n;
clock_t start,end;
start = clock();
double result = mypow(x,n);
end = clock();
cout << x << " 的 " << n << " 次方等於 " << result;
<< "\計算耗時 " << (end - start)/CLK_TCK << " 秒";
}

8.
#include<iostream>
using namespace std;

void fun(char a,char b)


{
cout << a << " & " << b << endl;
}

void fun(char a,int x)


{
for(int i=1;i<=x;i++)
cout << a;
cout << endl;
}

void fun(int x,int y)


{
cout << x << '*' << y << '=' << x*y << endl;
}

int main()
{
fun('A','Z');
fun('s',10);
fun(123,456);
}

9.
#include<iostream>
using namespace std;

int gcd(int a,int b)


{
int c;

do {
c = a % b;
a = b;
b = c;
} while ( c!= 0);
return a;
}

int main()
{
cout << "計算兩整數的最大公因數,";
cout << "請輸入兩整數(以空白隔開):";
int x,y;
cin >> x >> y;
cout << "最大公因數為 " << gcd(x,y);
}

10.
#include<iostream>
using namespace std;

void change(int input,int coin,int number)


{
if (input < coin * number)
number = input / coin;

cout << "換 " << number << " 個 " << coin << " 元硬幣\n";

input -= coin * number;

cout << "剩下的錢自動換成 50元硬幣 " << (number = input / 50) << " 個\n";

input -= number * 50;


cout << " 10元硬幣 " << (number = input / 10) << " 個\n";
input -= number * 10;
cout << " 5元硬幣 " << (number = input / 5) << " 個\n";

input -= number * 5;
cout << " 1元硬幣 " << (number = input) << " 個\n";
}

int main()
{
int x,y,z;
cout << "自動兌幣機,請問要換(1)50(2)10(3)5(4)1的硬幣:";
cin >> x;
cout << "要換幾個:";
cin >> y;
cout << "要用幾元的紙鈔換?(1)1000(2)500(3)200(4)100:";
cin >> z;
if (x > 4 || z>> 4)
cout << "輸入錯誤。";

else {
switch(x) { // 將選項換成硬幣面額
case 1:
x = 50;
case 2:
x = 10;
break;
case 3:
x = 5;
break;
case 4:
x = 1;
break;
}
switch(z) {
case 1:
change(1000,x,y);
break;
case 2:
change(500,x,y);
break;
case 3:
change(2000,x,y);
break;
case 4:
change(100,x,y);
break;
}
}
}
第7章

[學習評量]

1.(a)

2.(b)

3.(c)

4.'\0'

5.0

6.(b)

7.(b)

8.(b)

9.4

10.傳值、傳址、傳參考

[程式練習]

1.
#include<iostream>
using namespace std;

int main()
{
int x[10] = { 12, 24, 48, 239, 576,
816,1632,1024,3264,6428};

for(int i=0;i<10;i++)
cout << x[i] << "的平方等於 " << x[i]*x[i] << '\n';
}

2.
#include<iostream>
using namespace std;

int main()
{
char c[] = { 't','o','d','a','y','g','r','u','p','e',
'l','n','i','w','m','s','h','x','z','b',
'j','q','f','v','k','c'};

// 先排序
for(int i=0;i<25;i++)
for (int j=i+1;j<26;j++)
if (c[i] > c[j]) {
char tmp;
tmp = c[i];
c[i] = c[j];
c[j] = tmp;
}

// 再輸出
for(int i=0;i<26;i++)
cout << c[i] << ' ';
}

3.
#include<iostream>
using namespace std;

int main()
{
int one[] = {4,701,36,295,82};
int two[5];

for(int i=0;i<5;i++)
two[i] = one[i];

// 複製後輸出複製結果
for(int i=0;i<5;i++)
cout << two[i] << '\t';
}

4.
#include<iostream>
using namespace std;

bool check(char pass[])


{
char secret[6] = {'s','e','c','r','e','t'};

int i;
for(i=0;i<6;i++)
if (secret[i] != pass[i]) // 不相符即跳出迴圈
break;

if(i==6)
return true;
else
return false;
}
int main()
{
char pass[7];
cout << "請輸入6個字的密碼:";
cin >> pass;

if (check(pass))
cout << "密碼符合!";
else
cout << "密碼不符!";
}

5.
#include<iostream>
using namespace std;

int main()
{
int i=5;
int* ptr =&i;

cout << "i 的值為 " << *ptr;


}

6.
#include<iostream>
using namespace std;

int main()
{
int a,b,c,d;

cout << "變數 a 的位址:" << &a << '\n'


<< "變數 b 的位址:" << &b << '\n'
<< "變數 c 的位址:" << &c << '\n'
<< "變數 d 的位址:" << &d;
}

7.
#include<iostream>
using namespace std;

int main()
{
int a=9,b=99,c=999,d=9999;
int *e,*f,*g,*h;
e = &a; f=&b, g =&c; h=&d;

cout << "e 的位址:" << e << "\t*e 的值:" << *e << '\n'
<< "f 的位址:" << f << "\t*f 的值:" << *f << '\n'
<< "g 的位址:" << g << "\t*g 的值:" << *g << '\n'
<< "h 的位址:" << h << "\t*h 的值:" << *h;
}

8.
#include<iostream>
using namespace std;

int main()
{
int array[5]={2,3,4,5,6};
for(int i=0;i<5;i++)
cout << *(array+i) << '\t';
}

9.
#include<iostream>
using namespace std;
#define SIZE 10

void sort(int a[])


{
for(int i=0;i<SIZE-1;i++)
for(int j=i+1;j<SIZE;j++)
if(a[i]>a[j]) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}

long total(int a[])


{
long sum=0;
for(int i=0;i<SIZE;i++)
sum += a[i];
return sum;
}

int getMax(int a[])


{
int max = a[0];
for(int i=1;i<SIZE-1;i++)
if(a[i]>max)
max = a[i];
return max;
}

int main()
{
int array[SIZE] = {45,65,24,49,68,78,45,12,32,40};

cout << "陣列中最大值為:" << getMax(array);


cout << "陣列元素值總和:" << total(array);

sort(array);
cout << "陣列排序後的內容為:";
for(int i=0;i<SIZE;i++)
cout << array[i] << ' ';
}

10.
#include<iostream>
using namespace std;
#define SIZE 10

int total(int a[])


{
int sum=0;
for(int i=0;i<3;i++)
sum += a[i];
return sum;
}

double avg(int a[])


{
return total(a)/3.0;
}

int main()
{
int scores[SIZE][3];

for(int i=0;i<SIZE;i++) {
cout << "請輸入第 " << (i+1) << " 位學生的國文成績:";
cin >> scores[i][0];
cout << "請輸入第 " << (i+1) << " 位學生的英文成績:";
cin >> scores[i][1];
cout << "請輸入第 " << (i+1) << " 位學生的數學成績:";
cin >> scores[i][2];
}

for(int i=0;i<SIZE;i++)
cout << "第 " << (i+1) << " 位學生的總分:" << total(scores[i])
<< "\t平均為:" << avg(scores[i]) << '\n';
}
第8章

[學習評量]

1.(a)

2.(b)

3.(c)

4.(b)

5.資料成員、成員函式

6.(b)

7.(c)

8.(d)

9.::

10.(a)

[程式練習]

1.
#include<iostream>
using namespace std;

class Triangle {
public:
bool set(int,int,int);
private:
int side1,side2,side3;
};

bool Triangle::set(int i, int j, int k)


{
if((i+j) > k &&
(j+k) > i &&
(k+i) > j) {
side1 = i;
side2 = j;
side3 = k;
return true;
}
else
return false;
}
int main()
{
Triangle t;
cout << boolalpha << t.set(3,4,5) << '\n';
cout << t.set(3,4,15);
}

2.
#include<iostream>
using namespace std;

class Car { // 定義類別


public: // 成員函式設為公開
void init(double,double); // 初始化函式
double getEff() { return eff;} // 傳回燃油效率
double checkGas() { return gas;} // 檢查油量, 傳回剩餘油量
void addGas(double liter) { gas += liter; } // 加油函式
double go(double); // 行走參數指定里程, 傳回實際行走里程
private: // 讓資料成員為私有
double gas; // 載油量
double eff; // 每公升可行駛公里數
};

double Car::go(double kilo)


{
if (gas >= (kilo/eff)) { // 若油量夠
gas -= kilo/eff; // 減掉所耗掉的油量
cout << "油箱還有 " << checkGas() << " 公升油" << endl;
if (gas == 0) // 油用完了
cout << "沒油了!";
} else {
cout << "油量不夠,目前的油只夠跑 "
<< (kilo = gas * eff) << " 公里";
gas = 0;
}
return kilo;
}

void Car::init(double G,double E)


{
gas = G; // 初始化油量
eff= E; // 初始化燃油效率
}

int main()
{
Car super; // 宣告物件
super.init(20,30); // 初始化物件
cout << "超級省油車1公升跑 " << super.getEff()
<< " 公里" << endl;
cout << "現在油箱有 " << super.checkGas() << " 公升油" << endl;

// 加十公升油
super.addGas(10);
cout << "現在油箱有 " << super.checkGas() << " 公升油" << endl;

while (super.checkGas() > 0) {


double kilo;
cout << "現在要開幾公里:";
cin >> kilo;
super.go(kilo); // 行走指定里程
}
}

3.
#include<iostream>
using namespace std;

class Car { // 定義類別


friend void addGas(Car&,double);
public: // 成員函式設為公開
void init(double,double); // 初始化函式
double getEff() { return eff;} // 傳回燃油效率
double checkGas() { return gas;} // 檢查油量, 傳回剩餘油量
double go(double); // 行走參數指定里程, 傳回實際行走里程
private: // 讓資料成員為私有
double gas; // 載油量
double eff; // 每公升可行駛公里數
};

double Car::go(double kilo)


{
if (gas >= (kilo/eff)) { // 若油量夠
gas -= kilo/eff; // 減掉所耗掉的油量
cout << "油箱還有 " << checkGas() << " 公升油" << endl;
if (gas == 0) // 油用完了
cout << "沒油了!";
} else {
cout << "油量不夠,目前的油只夠跑 "
<< (kilo = gas * eff) << " 公里";
gas = 0;
}
return kilo;
}

void Car::init(double G,double E)


{
gas = G; // 初始化油量
eff= E; // 初始化燃油效率
}

void addGas(Car &c,double liter) // 加油函式


{
c.gas += liter;
}

int main()
{
Car super; // 宣告物件
super.init(20,30); // 初始化物件
cout << "超級省油車1公升跑 " << super.getEff()
<< " 公里" << endl;
cout << "現在油箱有 " << super.checkGas() << " 公升油" << endl;

// 加七公升油
addGas(super,7);
cout << "現在油箱有 " << super.checkGas() << " 公升油" << endl;

while (super.checkGas() > 0) {


double kilo;
cout << "現在要開幾公里:";
cin >> kilo;
super.go(kilo); // 行走指定里程
}
}

4.
#include<iostream>
using namespace std;

class Student {
public:
void set(char*,char*);
void show();
private:
char* id;
char* name;
};

void Student::set(char* id,char* name)


{
this->id = id;
this->name = name;
}
void Student::show()
{
cout << "學號:" << id << "\t姓名:" << name << endl;
}

int main()
{
Student st;
st.set("20061234","林雨珊");
st.show();
}

5.
#include<iostream>
using namespace std;

class Student {
public:
void set(char*,char*);
void show();
void setScores(float,float,float);
double getAvg();
private:
char* id;
char* name;
float eng; // 英文分數
float mat; // 數學分數
float cpp; // C++ 分數
};

void Student::set(char* id,char* name)


{
this->id = id;
this->name = name;
}

void Student::show()
{
cout << "學號:" << id << "\t姓名:" << name << endl;
}

void Student::setScores(float eng,float mat, float cpp)


{
this->eng = eng;
this->mat = mat;
this->cpp = cpp;
}

double Student::getAvg()
{
return (eng + mat + cpp) /3;
}

int main()
{
Student st;
st.set("20061234","林雨珊");
st.show();

st.setScores(80.5,86,82.5);
cout << "\n三科平均分數:" << st.getAvg();
}

6.
#include<iostream>
using namespace std;

class Student {
public:
void set(char*,char*);
void show();
void setScores(float,float,float);
double getAvg();
private:
char* id;
char* name;
float eng; // 英文分數
float mat; // 數學分數
float cpp; // C++ 分數
};

void Student::set(char* id,char* name)


{
this->id = id;
this->name = name;
}

void Student::show()
{
cout << "學號:" << id << "\t姓名:" << name << endl;
}

void Student::setScores(float eng,float mat, float cpp)


{
this->eng = eng;
this->mat = mat;
this->cpp = cpp;
}

double Student::getAvg()
{
return (eng + mat + cpp) /3;
}

int main()
{
Student* st[5];

// 配置 5 個 Student 物件的空間
for(int i =0;i<5;i++)
st[i] = new Student();

// 設定各物件的學號及姓名
st[0]->set("20061234","林雨珊");
st[1]->set("20061235","陳明通");
st[2]->set("20061236","楊文銘");
st[3]->set("20061237","秦蓓香");
st[4]->set("20061238","鍾振緯");

// 設定各物件的分數
st[0]->setScores(80.5,86,82.5);
st[1]->setScores(83,98,90);
st[2]->setScores(88.5,90,95);
st[3]->setScores(92,82,85);
st[4]->setScores(79.5,84,87.5);

for(int i=0;i<4;i++)
for(int j=i+1;j<5;j++)
if(st[i]->getAvg() > st[j]->getAvg()) { // 若前者的平均分數大於後者
Student *temp = st[j]; // 就交換位置
st[j] = st[i];
st[i] = temp;
}

for(int i =0;i<5;i++) { // 依序顯示各物件的內容


st[i]->show();
cout << "\t三科平均分數:" << st[i]->getAvg() << '\n';
}
}

7.
#include<iostream>
#include<cstring>
using namespace std;

class Str { // 陽春的字串類別


friend int strcmp(Str&, Str&); // 宣告夥伴函式
public:
void show() { cout << data; }
void set(char * ptr) { data = ptr; length = strlen(data); }
int getlen() { return length; }// 傳回字串長度
private:
char * data; // 指向字串的指標
int length; // 字串長度
};

int strcmp(Str& s1, Str& s2) // 定義夥伴函式


{
return strcmp(s1.data, s2.data);
} // 以標準函式庫中的 strcmp() 進行比較

int main()
{
Str hello, world;
hello.set("HELLO WORLD!");
world.set("hello world!");
if (hello.getlen() == world.getlen())
cout << "兩字串的長度相同";
else
cout << "兩字串的長度不同";
}

8.
#include<iostream>
#include<cstring>
using namespace std;

class Str { // 陽春的字串類別


friend int strcmp(Str&, Str&); // 宣告夥伴函式
public:
void show() { cout << data; }
void set(char * ptr) { data = ptr; length = strlen(data); }
int getlen() { return length; }// 傳回字串長度
int compare(Str&);
private:
char * data; // 指向字串的指標
int length; // 字串長度
};

int Str::compare(Str& str)


{
return strcmp(this->data, str.data);
}

int strcmp(Str& s1, Str& s2) // 定義夥伴函式


{
return strcmp(s1.data, s2.data);
} // 以標準函式庫中的 strcmp() 進行比較

int main()
{
Str hello, world;
hello.set("HELLO WORLD!");
world.set("hello world!");
if (hello.compare(world)!=0)
cout << "兩字串不同";
else
cout << "兩字串相同";
}

9.
#include<iostream>
using namespace std;

class Complex {
public:
void set(double r,double i) {real = r; image = i;}
void show()
{ cout << '(' << real << ',' << image << "i)"; }
Complex& add(Complex a) // 加法
{real += a.real; image += a.image; return *this;}
Complex& minus(Complex a) // 減法
{real -= a.real; image -= a.image; return *this;}
Complex& multiplex(Complex a);// 乘法
Complex& divide(Complex a); // 除法
private:
double real; // 實部
double image; // 虛部
};

Complex& Complex::multiplex(Complex a) // 乘法
{
double tempR = real * a.real - image * a.image;
double tempI = image * a.real + real * a.image;
real = tempR;
image = tempI;
return *this;
}

Complex& Complex::divide(Complex a) // 除法
{
double tempR = (real * a.real + image * a.image) /
(a.real * a.real + a.image * a.image);
double tempI = (-real * a.image + image * a.real) /
(a.real * a.real + a.image * a.image);
real = tempR;
image = tempI;
return *this;
}

int main()
{
Complex c1,c2;
c1.set(3, 4);
c2.set(2, 1);

c1.show(); cout << " 乘 "; c2.show();


cout << " 等於 "; c1.multiplex(c2).show();
cout << endl;
c2.show(); cout << " 除 "; c1.show();
cout << " 等於 "; c2.divide(c1).show();
}

10.
#include<iostream>
using namespace std;

class Complex {
public:
void set(double r,double i) {real = r; image = i;}
void show()
{ cout << '(' << real << ',' << image << "i)"; }
Complex& add(Complex a) // 加法
{real += a.real; image += a.image; return *this;}
Complex& minus(Complex a) // 減法
{real -= a.real; image -= a.image; return *this;}
Complex& multiplex(Complex a);// 乘法
Complex& divide(Complex a); // 除法

// 以下為多載的版本
Complex& add(double d) {real += d; return *this;}
Complex& minus(double d) {real -= d; return *this;}
Complex& multiplex(double);
Complex& divide(double);
private:
double real; // 實部
double image; // 虛部
};

Complex& Complex::multiplex(Complex a) // 乘法
{
double tempR = real * a.real - image * a.image;
double tempI = image * a.real + real * a.image;
real = tempR;
image = tempI;
return *this;
}

Complex& Complex::divide(Complex a) // 除法
{
double tempR = (real * a.real + image * a.image) /
(a.real * a.real + a.image * a.image);
double tempI = (-real * a.image + image * a.real) /
(a.real * a.real + a.image * a.image);
real = tempR;
image = tempI;
return *this;
}

Complex& Complex::multiplex(double d) // 乘上浮點數


{
real *= d;
image *= d;
return *this;
}

Complex& Complex::divide(double d) // 除以浮點數


{
real /= d;
image /= d;
return *this;
}

int main()
{
Complex c1,c2;
c1.set(8, 9);
c2.set(7, 6);

c1.show(); cout << " 乘 3.2";


cout << " 等於 "; c1.multiplex(3.2).show();
cout << endl;
c2.show(); cout << " 除以 0.6";
cout << " 等於 "; c2.divide(0.6).show();
}
第9章

[學習評量]

1.(c)

2.(a)

3.main() 函式的兩行敘述可用一行代表:Test t = Test(3,3);


若要用 new 運算子,也應寫成:Test *t = new Test(3,3);

4.(c)

5.(b)

6.(d)

7.(b)

8.(b)

9.(d)

10.(b)

[程式練習]

1.
#include<iostream>
using namespace std;

class Car {
public: // 成員函式設為公開
Car (double, double);
void show() { cout << "愛車重量為 " << weight << " 公斤,目前油量為 " << gas << " 公升。\n";}
private: // 讓資料成員為私有
double gas; // 載油量
double weight; // 車重
};

Car::Car(double g, double w)
{
if (g > 100) {
g = 100;
cout << "設定的油量初始值太大,重設為 100 公升\n";
}
gas = g;

if (w > 3000) {
w = 3000;
cout << "設定的車重初始值太大,重設為 3000 公斤\n";
}
weight = w;
}

int main()
{
Car babycar(35,1200);
babycar.show();

Car bigcar(120,4000);
babycar.show();
}

2.
#include<iostream>
using namespace std;

class Car {
public: // 成員函式設為公開
Car (double, double);
~Car ();
int howmany() { return counter; }
void show() { cout << "愛車重量為 " << weight << " 公斤,目前油量為 " << gas << " 公升。\n";}
private: // 讓資料成員為私有
double gas; // 載油量
double weight; // 車重
static int counter;
};
int Car::counter = 0;

Car::Car(double g, double w)
{
if (g > 100) {
g = 100;
cout << "設定的油量初始值太大,重設為 100 公升\n";
}
gas = g;

if (w > 3000) {
w = 3000;
cout << "設定的車重初始值太大,重設為 3000 公斤\n";
}
weight = w;
counter++;
}

Car::~Car ()
{
counter--;
}

int main()
{
Car babycar(35,1200);
cout << "現在有 " << babycar.howmany() << " 輛車\n";

Car *mid = new Car (40,1300);


Car *suv = new Car (90,2700);
cout << "現在有 " << babycar.howmany() << " 輛車\n";

delete mid;
delete suv;
cout << "現在有 " << babycar.howmany() << " 輛車\n";
}

3.
#include<iostream>
using namespace std;

class Dates {
public: // 成員函式設為公開
Dates();
char* askDate(int);
private: // 讓資料成員為私有
char* name[7];
int step;
};

Dates::Dates()
{
name[0] = "Mon";
name[1] = "Tue";
name[2] = "Wed";
name[3] = "Thu";
name[4] = "Fri";
name[5] = "Sat";
name[6] = "Sun";
}

char* Dates::askDate(int i)
{
if (i>7) // 檢查參數 i 是否超出 1 至 7 的範圍
i=7;
else if (i<1)
i=1;

return name[i-1];
}
int main()
{
Dates date;
cout << "星期一到星期天的英文縮寫是:\n";
for(int i =1;i<=7;i++)
cout << date.askDate(i) << '\t';
}

4.
#include<iostream>
#include<cstring>
using namespace std;

class Dates {
public:
Dates();
char* askDate(int);
char* toChinese(char *);
private:
char* name[7];
int step;
};

Dates::Dates()
{
name[0] = "Mon";
name[1] = "Tue";
name[2] = "Wed";
name[3] = "Thu";
name[4] = "Fri";
name[5] = "Sat";
name[6] = "Sun";
}

char* Dates::askDate(int i)
{
if (i>7) // 檢查參數 i 是否超出 1 至 7 的範圍
i=7;
else if (i<1)
i=1;

return name[i-1];
}

char* Dates::toChinese(char * ename)


{
static char cname[][7] = {"星期一","星期二","星期三","星期四",
"星期五","星期六","星期日"};
for (int i=0;i<7;i++)
if(strcmp(ename,name[i])==0)
return cname[i];
}

int main()
{
Dates date;
for(int i =1;i<=7;i++)
cout << date.askDate(i) << '\t' << date.toChinese(date.askDate(i)) << '\n';
}

5.
#include<iostream>
using namespace std;

class Time {
public:
Time(int h=12, int m=0, int s=0) {hour=h; min=m; sec=s;}
void set(int h, int m, int s) {hour=h; min=m; sec=s;}
void show();
private:
int hour, min, sec; // 代表時分秒的成員
};

void Time::show()
{
cout << hour << ':' << min << ':' << sec << endl;
}

class Clock {
public:
Clock(int h, int m, int s=0): clock_time(h,m,s) {};
void setAlarm(int h, int m, int s=0) { alarm_time.set(h,m,s); }
void show();
private:
Time clock_time; // 時鐘時間
Time alarm_time; // 鬧鐘時間
};

void Clock::show()
{
cout << "目前時間為 ";
clock_time.show();
cout << "鬧鐘設定在 ";
alarm_time.show();
}

int main()
{
Clock old_clock(12,34,56);
old_clock.setAlarm(8,30);
old_clock.show();
}

6.
#include<iostream>
using namespace std;

struct Point {
double x;
double y;
};

double abs(double d) { return (d>0?d:d*-1); }

class Rectangle {
public:
Rectangle(Point, double, double);
Rectangle(Point, Point);
double area();
private:
Point p1;
Point p2;
};

Rectangle::Rectangle(Point o1, double w, double h)


{
p1 = o1;
p2.x = p1.x + w;
p2.y = p1.y + h;
}

Rectangle::Rectangle(Point o1, Point o2)


{
p1 = o1;
p2 = o2;
}

double Rectangle::area()
{
return abs(p2.x-p1.x) * abs(p2.y - p1.y);
}

int main()
{
Point p1 = {0,0}, p2 = {5, 8.5};

Rectangle r1(p1,3.5,2);
cout << "r1 的面積:" << r1.area() << endl;

Rectangle r2(p1,p2);
cout << "r2 的面積:" << r2.area();
}

7.
#include<iostream>
using namespace std;

struct Point {
double x;
double y;
};

double abs(double d) { return (d>0?d:d*-1); }

class Rectangle {
public:
Rectangle(Point, double, double);
Rectangle(Point, Point);
double area();
bool isSquare();
private:
Point p1;
Point p2;
};

Rectangle::Rectangle(Point o1, double w, double h)


{
p1 = o1;
p2.x = p1.x + w;
p2.y = p1.y + h;
}

Rectangle::Rectangle(Point o1, Point o2)


{
p1 = o1;
p2 = o2;
}

double Rectangle::area()
{
return abs(p2.x-p1.x) * abs(p2.y - p1.y);
}

bool Rectangle::isSquare()
{
if(abs(p2.x-p1.x) == abs(p2.y - p1.y))
return true;
else
return false;
}

int main()
{
Point p1 = {0,0}, p2 = {5, 8.5};
Rectangle r1(p1,3,3);
Rectangle r2(p1,p2);

cout << "r1 " << (r1.isSquare()?"是":"不是") << "正方形。\n";


cout << "r2 " << (r2.isSquare()?"是":"不是") << "正方形。\n";
}

8.
#include<iostream>
using namespace std;

struct Point {
double x;
double y;
};

double abs(double d) { return (d>0?d:d*-1); }

class Rectangle {
public:
Rectangle(Point, double, double);
Rectangle(Point, Point);
double area();
bool isSquare();
Point getP1() { return p1; }
Point getP2() { return p2; }
private:
Point p1;
Point p2;
};

Rectangle::Rectangle(Point o1, double w, double h)


{
p1 = o1;
p2.x = p1.x + w;
p2.y = p1.y + h;
}

Rectangle::Rectangle(Point o1, Point o2)


{
p1 = o1;
p2 = o2;
}
double Rectangle::area()
{
return abs(p2.x-p1.x) * abs(p2.y - p1.y);
}

bool Rectangle::isSquare()
{
if(abs(p2.x-p1.x) == abs(p2.y - p1.y))
return true;
else
return false;
}

class Circle {
public:
Circle(double,double,double);
Circle(double,double,double,double);
Circle(Rectangle); // 以外切矩形物件建構圓形物件
double area() { return 3.1415926 * r * r; } // 計算圓面積
double circum() { return 3.1415926 * 2 * r; }// 計算圓週長
private:
double x,y; // 圓心座標
double r; // 半徑
};

Circle::Circle(double x0,double y0,double r0 = 1)


{
x = x0; y = y0; r = r0;
}

Circle::Circle(double x0,double y0,double x1, double y1)


{
double w = min( (x1>x0)? (x1-x0):(x0-x1), // 計算正方形邊長
(y1>y0)? (y1-y0):(y0-y1) );
r = w/2; // 半徑為寬或高的一半
x = x0 + r; // 算出圓心的 x 座標
y = y0 + r; // 算出圓心的 y 座標
}

Circle::Circle(Rectangle rec)
{
x = (rec.getP1().x + rec.getP2().x) /2;
y = (rec.getP1().y + rec.getP2().y) /2;

if(rec.isSquare()) // 若矩形是正方形
r = abs(rec.getP1().x - rec.getP2().x)/2;
else // 若矩形不是正方形
r = 0; // 就將半徑設為 0
}

int main()
{
Point p1 = {0,0}, p2 = {5, 8.5};
Rectangle r1(p1,3,3);
Rectangle r2(p1,p2);

Circle c1(r1),c2(r2);
cout << "c1 的面積為 " << c1.area() << endl;
cout << "c2 的圓周長為 " << c2.circum() << endl;
}

9.
#include<iostream>
using namespace std;

class Student {
public:
Student(char*,float,float);
void show();
private:
static int counter;
int id;
char* name;
float eng; // 英文分數
float mat; // 數學分數
};
int Student::counter = 0;

Student::Student(char* name, float eng, float mat)


{
counter++;
id = 20060000 + counter;
this->name = name;
this->eng = eng;
this->mat = mat;
}

void Student::show()
{
cout << "學號:" << id << "\t姓名:" << name
<< "\t英文分數:" << eng << "\t數學分數:" << mat << endl;
}

int main()
{
Student* st[5] = { new Student("林雨珊",80,86),
new Student("陳明通",83,90),
new Student("楊文銘",88.5,90.5),
new Student("秦蓓香",98,85),
new Student("鍾振緯",82.5,84) };

for(int i =0;i<5;i++) // 依序顯示各物件的內容


st[i]->show();
}

10.
#include<iostream>
using namespace std;

class Student {
public:
Student(char*,float,float);
Student(Student&); // 複製建構函式
void show();
private:
static int counter;
int id;
char* name;
float eng; // 英文分數
float mat; // 數學分數
};
int Student::counter = 0;

Student::Student(char* name, float eng, float mat)


{
counter++;
id = 20060000 + counter;
this->name = name;
this->eng = eng;
this->mat = mat;
}

Student::Student(Student& st)
{
counter++;
id = 20060000 + counter;
name = st.name;
eng = 0; // 暫將分數設為 0 分
mat = 0;
}

void Student::show()
{
cout << "學號:" << id << "\t姓名:" << name
<< "\t英文分數:" << eng << "\t數學分數:" << mat << endl;
}

int main()
{
Student* st[6] = { new Student("林雨珊",80,86),
new Student("陳明通",83,90),
new Student("楊文銘",88.5,90.5),
new Student("秦蓓香",98,85),
new Student("鍾振緯",82.5,84) };
Student sameName = *st[0];

st[0]->show();
sameName.show();
}
第10章

[學習評量]

1.(d)

2.:: . sizeof .* ?:

3.operator

4.(c)

5.int型別的參數

6.this指標

7.(a)

8.(d)

9.(a)

10.(b)

[程式練習]

1.
#include<iostream>
using namespace std;

class Calendard {
public:
Calendard(int,int,int); // 只有一個建構函式
void today()
{
cout << year << "年" << month << "月" << day << "日" << endl;
}
Calendard& operator++();
Calendard& operator--();
private:
int year, month, day; // 代表年月日的成員
static int monthdays[12]; // 記錄每月有幾天的陣列
};
int Calendard::monthdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};

Calendard::Calendard(int y = 2008 ,int m=1 , int d=1)


{
year = y;
month = (m>=1 && m<=12) ? m:1; // 檢查 m 是否在 1 至 12 間
day = (d>=1 && d<=monthdays[m-1]) ? d:1; // 檢查 d 是否在日期範圍內
}

Calendard& Calendard::operator++()
{
if (++day > monthdays[month-1]) { // 若超過該月日期範圍
day = 1; // 則設為 1 日,月份也加 1 分
if (++month == 13) { // 若變成 13 月
month = 1; // 則設為 1 月並加 1 年
year++;
}
}
return *this;
}

Calendard& Calendard::operator--()
{
if (--day == 0) // 若變成 0 日
if (--month == 0) { // 若變成 0 月
month = 12; // 則設為 12 月並減 1 年
year--;
}
day = monthdays[month-1];
return *this;
}

int main()
{
Calendard c1(1999,12,31);
Calendard c2(2000);

(++c1).today();
(--c2).today();
}

2.
#include<iostream>
using namespace std;

class Calendard {
public:
Calendard(int,int,int); // 只有一個建構函式
void today()
{
cout << year << "年" << month << "月" << day << "日" << endl;
}
Calendard& operator++();
Calendard& operator--();
int operator-(Calendard c);
private:
int year, month, day; // 代表年月日的成員
static int monthdays[12]; // 記錄每月有幾天的陣列
};
int Calendard::monthdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};

Calendard::Calendard(int y = 2008 ,int m=1 , int d=1)


{
year = y;
month = (m>=1 && m<=12) ? m:1; // 檢查 m 是否在 1 至 12 間
day = (d>=1 && d<=monthdays[m-1]) ? d:1; // 檢查 d 是否在日期範圍內
}

Calendard& Calendard::operator++()
{
if (++day > monthdays[month-1]) { // 若超過該月日期範圍
day = 1; // 則設為 1 日,月份也加 1 分
if (++month == 13) { // 若變成 13 月
month = 1; // 則設為 1 月並加 1 年
year++;
}
}
return *this;
}

Calendard& Calendard::operator--()
{
if (--day == 0) // 若變成 0 日
if (--month == 0) { // 若變成 0 月
month = 12; // 則設為 12 月並減 1 年
year--;
}
day = monthdays[month-1];
return *this;
}

int Calendard::operator-(Calendard c)
{
// 將日期都換算成從零年零月零日起算的總日數,再計算差
int days1 = 365 * year;
if(month > 1)
for(int i=1;i<month;i++)
days1 += monthdays[i-1];
days1 += day;

int days2 = 365 * c.year;


if(c.month > 1)
for(int i=1;i<c.month;i++)
days2 += monthdays[i-1];
days2 += c.day;
return (days1>days2)?(days1-days2):(days2-days1);
}

int main()
{
Calendard c1(1999,9,19);
Calendard c2(2000,1,23);

c1.today();
c2.today();
cout << "之間相差 " << c2 - c1 << " 天";
}

3.
#include<iostream>
using namespace std;

class Calendard {
public:
Calendard(int,int,int); // 只有一個建構函式
void today()
{
cout << year << "年" << month << "月" << day << "日" << endl;
}
Calendard& operator++();
Calendard& operator--();
operator int();
private:
int year, month, day; // 代表年月日的成員
static int monthdays[12]; // 記錄每月有幾天的陣列
};
int Calendard::monthdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};

Calendard::Calendard(int y = 2008 ,int m=1 , int d=1)


{
year = y;
month = (m>=1 && m<=12) ? m:1; // 檢查 m 是否在 1 至 12 間
day = (d>=1 && d<=monthdays[m-1]) ? d:1; // 檢查 d 是否在日期範圍內
}

Calendard& Calendard::operator++()
{
if (++day > monthdays[month-1]) { // 若超過該月日期範圍
day = 1; // 則設為 1 日,月份也加 1 分
if (++month == 13) { // 若變成 13 月
month = 1; // 則設為 1 月並加 1 年
year++;
}
}
return *this;
}

Calendard& Calendard::operator--()
{
if (--day == 0) // 若變成 0 日
if (--month == 0) { // 若變成 0 月
month = 12; // 則設為 12 月並減 1 年
year--;
}
day = monthdays[month-1];
return *this;
}

Calendard::operator int()
{
int days = 365 * year;
if(month > 1)
for(int i=1;i<month;i++)
days += monthdays[i-1];
days += day;

return days;
}

int main()
{
Calendard c1(1999,9,19);
Calendard c2(2000,1,23);

c1.today();
c2.today();
cout << "之間相差 " << c2 - c1 << " 天";
}

4.
#include<iostream>
using namespace std;

class Numbers {
public:
Numbers(int,int,int,int,int,int,int,int,int,int);
bool operator()(int);
private:
int ten[10];
};

Numbers::Numbers(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j)
{
ten[0] = a; ten[1] = b;
ten[2] = c; ten[3] = d;
ten[4] = e; ten[5] = f;
ten[6] = g; ten[7] = h;
ten[8] = i; ten[9] = j;
}

bool Numbers::operator()(int x)
{
for(int i=0;i<10;i++) // 將參數與陣列中所有元素逐一比對
if (ten[i]==x)
return true;

return false;
}

int main()
{
Numbers n1(9,7,1,5,3,11,13,15,17,19);
Numbers n2(4,8,2,6,10,18,12,16,20,14);

cout << "n1 中" << (n1(8)? "含有 ":"不含 ") << 8 << endl;
cout << "n2 中" << (n2(8)? "含有 ":"不含 ") << 8 << endl;
}

5.
#include<iostream>
using namespace std;

class Numbers {
public:
Numbers(int,int,int,int,int,int,int,int,int,int);
bool operator()(int);
void operator>>(int);
void operator<<(int);
void show();
private:
int ten[10];
};

void swap(int& a, int& b) // 排序時會用到的交換函式


{
int temp = a;
a = b;
b = temp;
}

Numbers::Numbers(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j)
{
ten[0] = a; ten[1] = b;
ten[2] = c; ten[3] = d;
ten[4] = e; ten[5] = f;
ten[6] = g; ten[7] = h;
ten[8] = i; ten[9] = j;
}

bool Numbers::operator()(int x)
{
for(int i=0;i<10;i++) // 將參數與陣列中所有元素逐一比對
if (ten[i]==x)
return true;

return false;
}

void Numbers::operator>>(int x) // 表示將物件中的前 x 個數字由大到小排列


{
if(x <= 1) // 若 x 小於等於 1,等於不用排序
return;
else if (x > 10) // 若 x 大於 10,則重設為 10
x = 10;

for(int i=0;i<x-1;i++) // 排序的迴圈


for(int j=i+1;j<x;j++)
if (ten[i]<ten[j])
swap(ten[i],ten[j]);
}

void Numbers::operator<<(int x) // 表示將物件中的前 x 個數字由小到大排列


{
if(x <= 1) // 若 x 小於等於 1,等於不用排序
return;
else if (x > 10) // 若 x 大於 10,則重設為 10
x = 10;

for(int i=0;i<x-1;i++) // 排序的迴圈


for(int j=i+1;j<x;j++)
if (ten[i]>ten[j])
swap(ten[i],ten[j]);
}

void Numbers::show()
{
for(int i=0;i<10;i++)
cout << ten[i] << ' ';
}

int main()
{
Numbers n1(9,7,1,5,3,11,13,15,17,19);
Numbers n2(4,8,2,6,10,18,12,16,20,14);

cout << "將 n1 前 7 個數字由大到小排序:" ;


n1>>7;
n1.show();

cout << "\n將 n2 全部數字由小到大排序:" ;


n2<<100;
n2.show();
}

6.
#include<iostream>
using namespace std;

class Circle {
public:
Circle(double, double, double);
Circle& operator++();
Circle& operator--();
void show();
private:
double x,y,r;
};

Circle::Circle(double x, double y, double r)


{
this->x = x;
this->y = y;
this->r = r;
}

Circle& Circle::operator++()
{
r += 1;
return *this;
}

Circle& Circle::operator--()
{
if (r>=1)
r -= 1;
else
r = 0; // 半徑最小為 0

return *this;
}
void Circle::show()
{
cout << "圓座標為 (" << x << ',' << y << "), 半徑為 " << r << endl;
}

int main()
{
Circle r1(2.5,3,7);
(++r1).show();

Circle r2(4,1.6,0.5);
(--r2).show();
}

7.
#include<iostream>
using namespace std;

class Circle {
public:
Circle(double, double, double);
Circle& operator++();
Circle& operator--();
Circle& operator>>(double);
Circle& operator<<(double);
void show();
private:
double x,y,r;
};

Circle::Circle(double x, double y, double r)


{
this->x = x;
this->y = y;
this->r = r;
}

Circle& Circle::operator++()
{
r += 1;
return *this;
}

Circle& Circle::operator--()
{
if (r>=1)
r -= 1;
else
r = 0; // 半徑最小為 0
return *this;
}

Circle& Circle::operator>>(double shift)


{
x += shift;
return *this;
}

Circle& Circle::operator<<(double shift)


{
x -= shift;
return *this;
}

void Circle::show()
{
cout << "圓座標為 (" << x << ',' << y << "), 半徑為 " << r << endl;
}

int main()
{
Circle r1(2.5,3,7);
(r1>>0.5).show();

Circle r2(4,1.6,0.5);
(r2<<4).show();
}

8.
#include <iostream>
using namespace std;

class ByteInt {
public:
ByteInt(int i) { c = (char) i; } // 建構函式
void show() { cout << (int) c << endl; }
ByteInt &operator++(); // 前置遞增函式
ByteInt operator++(int); // 後置遞增函式
ByteInt &operator--(); // 前置遞減函式
ByteInt operator--(int); // 後置遞減函式
private:
char c; // 用來存放數值的資料成員
};

ByteInt& ByteInt::operator++() // 前置遞增函式


{
c++;
cout << "前置 ++" << endl; // 此行可刪除
return *this;
}

ByteInt ByteInt::operator++(int) // 後置遞增函式


{
ByteInt tmp = *this; // 保存遞增前的值
c++;
cout << "後置 ++" << endl; // 此行可刪除
return tmp; // 傳回遞增前的值
}

ByteInt& ByteInt::operator--() // 前置遞減函式


{
c--;
return *this;
}

ByteInt ByteInt::operator--(int) // 後置遞減函式


{
ByteInt tmp = *this; // 保存遞減前的值
c--;
return tmp; // 傳回遞減前的值
}

void main()
{
ByteInt b(5);
(--b).show(); // 減 1 後顯示其值
(b--).show(); // 再減 1, 但顯示減 1 之前的值
b.show(); // 顯示最後結果
}

9.
#include <iostream>
#define MaxSize 20
using namespace std;

class Stack {
public:
void init() { sp = 0; } // 初始化的成員函式
Stack& operator<<(int);
int operator>>(int&);
private:
int sp; // 用來記錄目前堆疊中已存幾筆資料
int buffer[MaxSize]; // 代表堆疊的陣列
static void Error() { cout << "\nStack Error\n"; }
};
Stack& Stack::operator<<(int data) // 將一個整數存入堆疊
{
if(sp == MaxSize) // 若已達最大值, 則不能再放資料進來
Error();
else
buffer[sp++] = data; // 將資料存入 sp 所指元素, 並將 sp 加 1
// 表示所存的資料多了一筆
return *this;
}

int Stack::operator>>(int& data) // 從堆疊中取出一個整數


{
if(sp == 0) { // 若已經到底了表示堆疊中應無資料
Error();
return 0;
}
data = buffer[--sp]; // 將 sp 減 1 表示所存的資料少了一筆
return data;
}

int main()
{
Stack st1, st2; // 定義二個堆疊物件
st1.init();
st2.init();

// 將資料存入第一個堆疊中
st1 << 1 << 2 << 3;

// 將資料存入第二個堆疊中
st2 << 7 << 8 << 9;

int i;
cout << (st1>>i);
cout << (st2>>i);
cout << (st1>>i);
cout << (st2>>i);
cout << (st1>>i);
cout << (st2>>i);
}

10.
#include <iostream>
#define MaxSize 20
using namespace std;

class Stack {
friend ostream& operator<<(ostream&, Stack&);
friend istream& operator>>(istream&, Stack&);
public:
void init() { sp = 0; } // 初始化的成員函式
Stack& operator<<(int);
int operator>>(int&);
private:
int sp; // 用來記錄目前堆疊中已存幾筆資料
int buffer[MaxSize]; // 代表堆疊的陣列
static void Error() { cout << "\nStack Error\n"; }
};

Stack& Stack::operator<<(int data) // 將一個整數存入堆疊


{
if(sp == MaxSize) // 若已達最大值, 則不能再放資料進來
Error();
else
buffer[sp++] = data; // 將資料存入 sp 所指元素, 並將 sp 加 1
// 表示所存的資料多了一筆
return *this;
}

int Stack::operator>>(int& data) // 從堆疊中取出一個整數


{
if(sp == 0) { // 若已經到底了表示堆疊中應無資料
Error();
return 0;
}
data = buffer[--sp]; // 將 sp 減 1 表示所存的資料少了一筆
return data;
}

ostream& operator<<(ostream& o, Stack& s)


{
if(s.sp==0)
o << "Stack Empty!\n";
else {
for(int i=0;i<s.sp;i++)
o << s.buffer[i] << ' ';
o << endl;
}
return o;
}

istream& operator>>(istream& i, Stack& s)


{
if(s.sp < MaxSize)
i >> s.buffer[s.sp++];
return i;
}
int main()
{
Stack stk;
stk.init();

// 將資料存入堆疊中
cout << "請輸入五個要存入堆疊的整數\n";

for(int i=0;i<5;i++)
cin >> stk;

cout << "目前堆疊中所存的數字是:" << stk;


}
第11章

[學習評量]

1.(b)

2.(b)

3.(c)

4.(a)

5.(b)

6.(a)、(c)

7.(b)

8.(d)

9.(d)

10.abc

[程式練習]

1.
#include<iostream>
#include<string>
using namespace std;

int main()
{
cout << "本程式會將輸入字串中的 a 都換成 A,請輸入一字串:";
string str;
cin >> str;

int i, pos = 0;
string olds = "a"; // 定義要搜尋旳字串
string news = "A"; // 定義要替換成的字串

while ((i = str.find_first_of(olds,pos))!=string::npos) {


str.replace(i,1,news);
pos = i + news.size();
}

cout << "新字串:" << str;


}
2.
#include<iostream>
#include<string>
using namespace std;

int main()
{
cout << "本程式會將輸入字串中的英文字母首字成大寫,請輸入一字串:";
string str;
getline(cin,str);

bool first = true; // 判斷是否為首字的布林變數

for(int i=0;i<str.size();i++) {
if(first) {
str[i] = toupper(str[i]);
first = false; // 已將首字變成大寫,故下一字元不是首字
}
else if (str[i] == ' ' || str[i] == '\t')
first = true; // 若遇到空白及 TAB 字元,表示下一英文字是首字
}

cout << "新字串:" << str;


}

3.
#include<iostream>
#include<string>
using namespace std;

int main()
{
cout << "本程式會將將輸入的字串排序。\n";

string str[10];
for (int i=0;i<10;i++) {
cout << "請輸入第 " << i+1 << " 個字串:";
getline(cin,str[i]);
}

for(int i=0;i<9;i++) // 排序的迴圈


for(int j =i+1;j<10;j++)
if(str[i]>str[j]) {
string tmp = str[i];
str[i] = str[j];
str[j] = tmp;
}

cout << "排序後:\n";


for(int i=0;i<10;i++) // 輸出所有字串
cout << str[i] << '\n';
}

4.
#include<iostream>
#include<string>
using namespace std;

int checknumber(string str) // 計算字串中有幾個數字的函式


{
int counter = 0;
for(int i =0;i<str.size();i++)
if(isdigit(str[i]))
counter++;
return counter;
}

int main()
{
string tel = "test";

while (tel != "0" ) {


cout << "請輸入電話號碼(輸入0結束):";
getline(cin,tel);

// 將所有的空白去除
string::size_type pos=0, i;
while((i=tel.find_first_of(" \t",pos)) != string::npos) {
tel.erase(i,1);
pos = i;
}

if(tel != "0") {
if((tel.find_first_not_of("01234567890 -") == string::npos) && // 不含不合法字元
(tel.find_first_of("01234567890") == 0) && // 首字為數字
(tel.find_last_of("01234567890") == (tel.size()-1)) && // 末字為數字
(checknumber(tel) >= 3)) // 至少 3 碼
cout << "格式正確\n";
else
cout << "格式錯誤\n";
}
}
}

5.
#include<iostream>
#include<string>
using namespace std;
string specials = "()<>@,;:\\\"[]"; // 特殊字元

bool checkname(string str) // 檢查名稱的函式


{
if(str.find_first_of(specials)!=string::npos)
return false;

for(int i=0;i<(int)str.size();i++)
if(str[i] < 32 || str[i] >=127)
return false;

return true;
}

bool checkserver(string str) // 檢查伺服器位址的函式


{
if(str.find_first_of(specials)!=string::npos)
return false;

int dot=0; // 計算有幾個 '.'


for(int i=0;i<(int)str.size();i++) {
if(str[i] == '.')
if((i==0) || (str[i+i] == '.')) // 如果第 1 個字是 '.'
return false; // 或連續出現兩個 '.'
else
dot++;
else if(str[i] < 32 || str[i] >=127)
return false;
}

if(dot>0) // 位址中至少要有一個 '.'


return true;
else
return false;
}

int main()
{
string email = "test";

while (email != "0" ) {


cout << "請輸入電子郵件地址(輸入0結束):";
getline(cin,email);

// 將所有的空白去除
string::size_type pos=0, i;
while((i=email.find_first_of(" \t",pos)) != string::npos) {
email.erase(i,1);
pos = i;
}
// 將字串從 @ 分成前後兩部份 name@server
pos = email.find_first_of("@");

if(pos == string::npos || // 如果沒有 @


pos == 0 || pos == email.size()) { // 或 @ 是第 1 個字或最後 1 字
cout << "格式錯誤\n";
continue;
}

if(checkname(email.substr(0,pos)) &&
checkserver(email.substr(pos+1)))
cout << "格式正確\n";
else
cout << "格式錯誤\n";
}
}

6.
#include<iostream>
#include<string>
using namespace std;

bool check(string str) // 檢查日期格式的函式


{ // 檢查是否含數字以外的字元
string legal = "0123456789";
if(str.find_first_not_of(legal) == string::npos && (str.size() != 0))
return true;
else
return false;
}

int main()
{
string dates = "test";
string yy,mm,dd;

while (dates != "0" ) {


cout << "請輸入日期字串(格式為 YYYY/MM/DD,輸入0結束):";
cin >> dates;
if (dates == "0")
break;

// 分別取得年、月、日三個子字串
string::size_type pos1, pos2;

if ((pos1 = dates.find_first_of("/"))== string::npos) {


break; // 如果找不到 /
cout << "輸入的日期格式錯誤\n";
}
else
yy = dates.substr(0,pos1);

pos2 = dates.find_first_of("/",pos1+1);
mm = dates.substr(pos1+1,pos2-pos1-1);

pos1 = dates.find_first_of("/",pos2+1);
dd = dates.substr(pos2+1);

if(check(yy) && check(mm) && check (dd))


cout << yy << "年"
<< mm << "月"
<< dd << "日" << '\n';
else
cout << "輸入的日期格式錯誤\n";
}
}

7.
#include<iostream>
#include<string>
using namespace std;

string& trim(string& str) // 去除字串中空白的函式


{
string::size_type pos=0, i;
while((i=str.find_first_of(" \t",pos)) != string::npos) {
str.erase(i,1);
pos = i;
}

return str;
}

int main()
{
string test;

cout << "請輸入一測試字串:";


getline(cin,test);

cout << trim(test);


}

8.
#include<iostream>
#include<string>
#include<cctype>
using namespace std;

string& change(string& str) // 改變大小寫的函式


{
for(string::size_type i=0;i<str.size();i++)
if(isupper(str[i]))
str[i] = tolower(str[i]);
else if(islower(str[i]))
str[i] = toupper(str[i]);

return str;
}

int main()
{
string test;

cout << "請輸入一測試字串:";


getline(cin,test);

cout << change(test);


}

9.
#include<iostream>
#include<string>
#include<cctype>
using namespace std;

int main()
{
string filename;

cout << "請輸入一檔案名稱:";


cin >> filename;

// 長檔名中可能有多個 .
// 以最後一個點之後的子字串為副檔名
string::size_type dot = filename.find_last_of(".");
string mainfilename = filename.substr(0,dot);
string subfilename = filename.substr(dot+1);

if(mainfilename.size() != 0) {
cout << "主檔名為:" << mainfilename << '\n';
if(subfilename.size() != 0)
cout << "副檔名為:" << subfilename << '\n';
else
cout << "沒有副檔名";
}
else // 主檔名為空字串
cout << "無主檔名,格式錯誤";
}

10.
#include<iostream>
#include<string>
#include<cctype>
using namespace std;

string::size_type diff(string str1, string str2)


{
string::size_type offset;
for (offset = 1;offset<str1.size() || offset<str2.size();offset++)
if(str1[offset] != str2[offset])
break;
return offset+1;
}

int main()
{
string str1,str2;

cout << "請輸入兩個字串以進行比對。\n";


cout << "字串1:";
getline(cin,str1);
cout << "字串2:";
getline(cin,str2);

if(str1 == str2)
cout << "兩字串內容相同。\n";
else
cout << "兩字串從第 " << diff(str1,str2) << " 個字開始不同。\n";
}
第12章

[學習評量]

1.(a)

2.(c)

3.(b)

4.(d)

5.(d)

6.(b)

7.(b)

8.(b)

9.(d)

10.(d)

[程式練習]

1.
#include<iostream>
using namespace std;

class Shape {
public:
double x, y; // 代表圖形的起點
};

class Eclipse : public Shape { // 繼承自 Shape 類別


double w; // 代表外切矩形的寬
double h; // 代表外切矩形的高
};

int main()
{
Shape s;
Eclipse e;
cout << "s 的大小:" << sizeof(s) << endl;
cout << "e 的大小:" << sizeof(e) << endl;
}
2.
#include<iostream>
using namespace std;

class Shape {
protected:
double x, y; // 代表圖形的起點 (左上角)
};

class Eclipse : public Shape { // 繼承自 Shape 類別


public:
Eclipse(double,double,double,double);
protected:
double w; // 代表外切矩形的寬
double h; // 代表外切矩形的高
};

class Circle : public Eclipse { // 繼承自 Eclipse 類別


friend ostream& operator<<(ostream&,Circle);
public:
Circle(double,double,double);
protected:
double r; // 代表圓半徑
};

Eclipse::Eclipse(double x,double y,double w,double h)


{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
}

Circle::Circle(double x,double y,double r):Eclipse(x,y,2*r,2*r)


{
this->r = r;
}

ostream& operator<<(ostream& o,Circle c)


{
return o << "圓心座標為 (" << c.x+c.r << ',' << c.y+c.r << "),半徑為 " << c.r;
}

int main()
{
Circle c(3,4,5);
cout << c;
}
3.
#include<iostream>
using namespace std;
#define PI 3.1415926 // 定義圓周率常數

class Shape {
protected:
double x, y; // 代表圖形的起點 (左上角)
};

class Eclipse : public Shape { // 繼承自 Shape 類別


public:
Eclipse(double,double,double,double);
double area() { return (w/2) * (h/2) * PI;}
protected:
double w; // 代表外切矩形的寬
double h; // 代表外切矩形的高
};

class Circle : public Eclipse { // 繼承自 Eclipse 類別


friend ostream& operator<<(ostream&,Circle);
public:
Circle(double,double,double);
double area() { return r * r * PI;}
protected:
double r; // 代表圓半徑
};

Eclipse::Eclipse(double x,double y,double w,double h)


{
this->x = x;
this->y = y;
this->w = w;
this->h = h;
}

Circle::Circle(double x,double y,double r):Eclipse(x,y,2*r,2*r)


{
this->r = r;
}

ostream& operator<<(ostream& o,Circle c)


{
return o << "圓心座標為 (" << c.x+c.r << ',' << c.y+c.r << "),半徑為 " << c.r;
}

int main()
{
Circle c(3,4,5);
Eclipse e(3,4,10,12);

cout << "c 的面積為 " << c.area() << '\n'


<< "e 的面積為 " << e.area() << '\n';
}

4.
#include<iostream>
#include<string>
using namespace std;

class Publication {
public:
Publication(string n, int p) { name = n; price = p; }
protected:
string name;
int price;
};

class Book : public Publication { // 繼承自 Publication 類別


friend ostream& operator<<(ostream&,Book);
public:
Book(string,int,string);
protected:
string isbn; //書籍的 ISBN 編號
};

Book::Book(string n, int p, string i) : Publication(n,p)


{
isbn = i;
}

ostream& operator<<(ostream& o,Book b)


{
return o << b.name << '/' << b.price << "元/ISBN碼:" << b.isbn;
}

enum periods {weekly,monthly,quarterly}; // 出刊週期

class Magazine : public Publication { // 繼承自 Publication 類別


friend ostream& operator<<(ostream&,Magazine);
public:
Magazine(string,int,periods);
protected:
periods period; // 代表出刊週期
};
Magazine::Magazine(string n, int p, periods s) : Publication(n,p)
{
period = s;
}

ostream& operator<<(ostream& o,Magazine m)


{
string p;
if(m.period == weekly) p = "週刊";
else if(m.period == monthly) p = "月刊";
else p = "季刊";

return o << m.name << "/每期" << m.price << "元/" << p;
}

int main()
{
Book b("C++ 寶典",1000,"1234567890");
Magazine m("C++ 新聞",120,weekly);

cout << b << '\n'


<< m << '\n';
}

5.
#include<iostream>
#include<string>
using namespace std;

class Publication {
public:
Publication(string n, int p) { name = n; price = p; }
bool operator>(Publication);
protected:
string name;
int price;
};

bool Publication::operator>(Publication pub)


{
if(price>pub.price)
return true;
else
return false;
}

class Book : public Publication { // 繼承自 Publication 類別


friend ostream& operator<<(ostream&,Book);
public:
Book(string,int,string);
protected:
string isbn; //書籍的 ISBN 編號
};

Book::Book(string n, int p, string i) : Publication(n,p)


{
isbn = i;
}

ostream& operator<<(ostream& o,Book b)


{
return o << b.name << '/' << b.price << "元/ISBN碼:" << b.isbn;
}

enum periods {weekly,monthly,quarterly}; // 出刊週期

class Magazine : public Publication { // 繼承自 Publication 類別


friend ostream& operator<<(ostream&,Magazine);
public:
Magazine(string,int,periods);
protected:
periods period; // 代表出刊週期
};

Magazine::Magazine(string n, int p, periods s) : Publication(n,p)


{
period = s;
}

ostream& operator<<(ostream& o,Magazine m)


{
string p;
if(m.period == weekly) p = "週刊";
else if(m.period == monthly) p = "月刊";
else p = "季刊";

return o << m.name << "/每期" << m.price << "元/" << p;
}

int main()
{
Book b("C++ 寶典",1000,"1234567890");
Magazine m("C++ 新聞",120,weekly);

cout << b << '\n'


<< m << '\n';

if(b>m)
cout << "書比較貴\n";
else
cout << "雜誌比較貴\n";
}

6.
#include<iostream>
#include<string>
using namespace std;

class Person { // 人員類別


public:
Person(string, int); // 建構函式
Person() {}
protected:
string name; // 姓名
int birthyear;// 出生年
};

Person::Person(string n, int a) : name(n)


{
birthyear = a;
}

class Student : public Person { // 學生類別


public:
Student(string n, int a, string i, int g):Person(n,a)
{
id = i;
grade = g;
}
private:
string id; // 學號
int grade; // 年級
};

enum teach {chi,eng,mat}; // 代表科目

class Teacher : public Person { // 教師類別


public:
Teacher(string n, int a, teach t):Person(n,a)
{
course = t;
}
private:
teach course; // 科目
};

int main()
{
Student ss[3]={Student("楊其文", 13, "06000302",1),
Student("李家怡", 14, "05000208",2),
Student("王松山", 15, "04000105",3)};

cout << sizeof(ss) << '\n';

Teacher tt = Teacher("洪伯芳",40,eng);
cout << sizeof(tt) << '\n';
}

7.
#include<iostream>
#include<string>
using namespace std;

class Person { // 人員類別


public:
Person(string, int); // 建構函式
Person() {}
protected:
string name; // 姓名
int birthyear;// 出生年
};

Person::Person(string n, int a) : name(n)


{
birthyear = a;
}

class Student : public Person { // 學生類別


friend ostream& operator<<(ostream&, Student&);
public:
Student(string n, int a, string i, int g):Person(n,a)
{
id = i;
grade = g;
}
private:
string id; // 學號
int grade; // 年級
};

ostream& operator<<(ostream& o, Student & s)


{
return o << s.id << '/' << s.name << '/' << s.grade << " 年級" << '\n';
}
enum teach {chi,eng,mat}; // 代表科目

class Teacher : public Person { // 教師類別


friend ostream& operator<<(ostream&, Teacher &);
public:
Teacher(string n, int a, teach t):Person(n,a)
{
course = t;
}
private:
teach course; // 科目
};

ostream& operator<<(ostream& o, Teacher& t)


{
string c;
if(t.course == chi) c = "國文";
else if(t.course == eng) c = "英文";
else c = "數學";

return o << t.name << "老師教" << c << '\n';


}

int main()
{
Student ss[3]={Student("楊其文", 13, "06000302",1),
Student("李家怡", 14, "05000208",2),
Student("王松山", 15, "04000105",3)};

for(int i=0;i<3;i++) // 依序輸出各物件


cout << ss[i];

Teacher tt = Teacher("洪伯芳",40,eng);
cout << tt;
}

8.
#include<iostream>
#include<string>
using namespace std;

class Person { // 人員類別


friend ostream& operator<<(ostream&, Person &);
public:
Person(string, int); // 建構函式
bool operator>(Person&);
protected:
string name; // 姓名
int birthyear;// 出生年
};

Person::Person(string n, int a) : name(n)


{
birthyear = a;
}

ostream& operator<<(ostream& o, Person & p)


{
return o << p.name << ",生於 " << p.birthyear << " 年\n";
}

bool Person::operator>(Person& p) // 用名稱比較大小的函式


{ // 可用以將物件排序
if(name > p.name)
return true;
else
return false;
}

class Student : public Person { // 學生類別


friend ostream& operator<<(ostream&, Student&);
public:
Student(string n, int a, string i, int g):Person(n,a)
{
id = i;
grade = g;
}
private:
string id; // 學號
int grade; // 年級
};

ostream& operator<<(ostream& o, Student & s)


{
return o << s.id << '/' << s.name << '/' << s.grade << " 年級" << '\n';
}

enum teach {chi,eng,mat}; // 代表科目

class Teacher : public Person { // 教師類別


friend ostream& operator<<(ostream&, Teacher &);
public:
Teacher(string n, int a, teach t):Person(n,a)
{
course = t;
}
private:
teach course; // 科目
};

ostream& operator<<(ostream& o, Teacher& t)


{
string c;
if(t.course == chi) c = "國文";
else if(t.course == eng) c = "英文";
else c = "數學";

return o << t.name << "老師教" << c << '\n';


}

int main()
{
Person *pp[4]={new Student("楊其文", 1992, "06000302",1),
new Teacher("洪伯芳", 1960, eng),
new Student("李家怡", 1991, "05000208",2),
new Student("王松山", 1990, "04000105",3)};

for(int i=0;i<3;i++) // 排序輸出各物件


for(int j=i+1;j<4;j++)
if(*pp[i]>*pp[j]) {
Person *tmp;
tmp = pp[i];
pp[i] = pp[j];
pp[j] = tmp;
}

for(int i=0;i<4;i++) // 排序輸出各物件


cout << *pp[i];
}

9.
#include<iostream>
#include<string>
using namespace std;

class Person { // 人員類別


friend ostream& operator<<(ostream&, Person &);
public:
Person(string, int); // 建構函式
bool operator>(Person&);
bool older(Person&);
protected:
string name; // 姓名
int birthyear;// 出生年
};

Person::Person(string n, int a) : name(n)


{
birthyear = a;
}

ostream& operator<<(ostream& o, Person & p)


{
return o << p.name << ",生於 " << p.birthyear << " 年\n";
}

bool Person::operator>(Person& p) // 用名稱比較大小的函式


{ // 可用以將物件排序
if(name > p.name)
return true;
else
return false;
}

bool Person::older(Person& p) // 用年齡比較大小


{
if(birthyear < p.birthyear) // 出生年較小表示較年長
return true;
else
return false;
}

class Student : public Person { // 學生類別


friend ostream& operator<<(ostream&, Student&);
public:
Student(string n, int a, string i, int g):Person(n,a)
{
id = i;
grade = g;
}
bool operator<(Student&);
private:
string id; // 學號
int grade; // 年級
};

ostream& operator<<(ostream& o, Student & s)


{
return o << s.id << '/' << s.name << '/' << s.grade << " 年級" << '\n';
}

enum teach {chi,eng,mat}; // 代表科目

class Teacher : public Person { // 教師類別


friend ostream& operator<<(ostream&, Teacher &);
public:
Teacher(string n, int a, teach t):Person(n,a)
{
course = t;
}
private:
teach course; // 科目
};

ostream& operator<<(ostream& o, Teacher& t)


{
string c;
if(t.course == chi) c = "國文";
else if(t.course == eng) c = "英文";
else c = "數學";

return o << t.name << "老師教" << c << '\n';


}

int main()
{
Person *pp[4]={new Student("楊其文", 1992, "06000302",1),
new Teacher("洪伯芳", 1960, eng),
new Student("李家怡", 1991, "05000208",2),
new Student("王松山", 1990, "04000105",3)};

for(int i=0;i<3;i++) // 排序輸出各物件


for(int j=i+1;j<4;j++)
if(pp[i]->older(*pp[j])) {
Person *tmp;
tmp = pp[i];
pp[i] = pp[j];
pp[j] = tmp;
}

for(int i=0;i<4;i++) // 排序輸出各物件


cout << *pp[i];
}

10.
#include<iostream>
#include<string>
using namespace std;

class Person { // 人員類別


friend ostream& operator<<(ostream&, Person &);
public:
Person(string, int); // 建構函式
bool operator>(Person&);
bool older(Person&);
protected:
string name; // 姓名
int birthyear;// 出生年
};

Person::Person(string n, int a) : name(n)


{
birthyear = a;
}

ostream& operator<<(ostream& o, Person & p)


{
return o << p.name << ",生於 " << p.birthyear << " 年\n";
}

bool Person::operator>(Person& p) // 用名稱比較大小的函式


{ // 可用以將物件排序
if(name > p.name)
return true;
else
return false;
}

bool Person::older(Person& p) // 用年齡比較大小


{
if(birthyear < p.birthyear) // 出生年較小表示較年長
return true;
else
return false;
}

class Student : public Person { // 學生類別


friend ostream& operator<<(ostream&, Student&);
public:
Student(string n, int a, string i, int g):Person(n,a)
{
id = i;
grade = g;
}
bool operator<(Student&);
private:
string id; // 學號
int grade; // 年級
};

ostream& operator<<(ostream& o, Student & s)


{
return o << s.id << '/' << s.name << '/' << s.grade << " 年級" << '\n';
}

bool Student::operator<(Student& s) // 依學號排序


{
if(id < s.id)
return true;
else
return false;
}

enum teach {chi,eng,mat}; // 代表科目

class Teacher : public Person { // 教師類別


friend ostream& operator<<(ostream&, Teacher &);
public:
Teacher(string n, int a, teach t):Person(n,a)
{
course = t;
}
private:
teach course; // 科目
};

ostream& operator<<(ostream& o, Teacher& t)


{
string c;
if(t.course == chi) c = "國文";
else if(t.course == eng) c = "英文";
else c = "數學";

return o << t.name << "老師教" << c << '\n';


}

int main()
{
Student *ss[3]={new Student("王松山", 1990, "04000105",3),
new Student("楊其文", 1992, "06000302",1),
new Student("李家怡", 1991, "05000208",2)};

for(int i=0;i<2;i++) // 依學號由大到小排序


for(int j=i+1;j<3;j++)
if(*ss[i]<*ss[j]) {
Student *tmp = ss[i];
ss[i] = ss[j];
ss[j] = tmp;
}
for(int i=0;i<3;i++) // 輸出各物件
cout << *ss[i];
}
第13章

[學習評量]

1.(b)

2.(d)

3.(c)

4.(c)

5.GrandChild是以私有繼承的方式繼承ChildB,所以不能存取ChildB::i

6.(a)

7.Child中的test()函式應改成有int型別的傳回值,否則將因沒有實作純虛擬函式int test(),而無法建立
物件。

8.(d)

9.(c)

10.(c)

[程式練習]

1.
#include<iostream>
using namespace std;

class Ox { // 牛類別
public:
Ox(double w = 100) { weight = w; }
void turn(int);
protected:
double weight; // 重量
};

void Ox::turn(int degree)


{
cout << "轉 " << degree % 360 << " 度\n";
}

class Cart { // 車類別


public:
Cart(double w = 100) { weight = w; }
void parking() { cout << "停車"; }
protected:
double weight; // 重量
};

class Oxcart: public Cart, public Ox { // 多重繼承


public:
Oxcart(double l = 500):Car(250),Ox(450) { load = l; }
private:
double load; // 載重量
};

int main()
{
Oxcart oc(900); // 宣告牛車物件
oc.turn(90);
oc.parking();
}

2.
#include <iostream>
using namespace std;

class Shape {
public:
virtual double area() { return 0; } // 面積虛擬函式
virtual double round() { return 0; } // 周長虛擬函式
Shape(double x =0, double y=0) { this-> x = x; this->y = y;}
protected:
double x,y;
};

class Circle: virtual public Shape {


public:
Circle(double x=0, double y=0, double radius=0) : Shape(x,y)
{ r = radius; }
double area() { return r*r*3.14159; } // 計算面積
double round() { return 2*r*3.14159; } // 計算周長
private:
double r; // 半徑
};

class Rectangle: virtual public Shape {


public:
Rectangle(double x=0, double y=0,
double x1=1, double y1=1) : Shape(x,y)
{ this->x1 = x1; this->y1 = y1; }
double area() { return (x1-x)*(y1-y); } // 計算面積
double round() { return 2 * (x1-x) + // 計算周長
2 * (y1-y); }
private:
double x1,y1; // 右下角座標
};

void main()
{
Shape* sp[3] = {new Shape(),
new Circle(1,1,3),
new Rectangle(1,2,6,8)};

for(int i=0; i<3; i++)


cout << sp[i]->round() << endl; // 一一輸出各物件的周長
}

3.
#include<iostream>
#include<string>
using namespace std;

enum Gender {male,female}; // 代表性別的列舉型別

class Person { // 人員類別


public:
Person(string, Gender, int);
Person() {}
protected:
string name; // 姓名
Gender sex; // 性別
int age; // 年齡
};

Person::Person(string n, Gender s, int a) : name(n)


{
sex = s; age = a;
}

class Admin : virtual public Person { // 管理、行政人員類別


public:
void goMeeting() { cout << name << ((sex==male)?"先生":"女士") << "去開會" << endl; }
Admin(string n, Gender s, int a):Person(n,s,a) { id = ++counter; }
Admin() {id = ++counter;}
protected:
int id; // 人員編號
static int counter; // 物件計數器
};
int Admin::counter = 0;

class Teacher : virtual public Person { // 教師類別


public:
void goClass() { cout << name << "老師在上課" << endl;}
Teacher(string, Gender, int, string);
Teacher() {id = ++counter;}
protected:
string department; // 系所名稱
int id; // 教師編號
static int counter; // 物件計數器
};
int Teacher::counter = 0;

Teacher::Teacher(string n, Gender s, int a, string d):Person(n,s,a)


{
department = d;
id = ++counter;
}

class Chairman : public Teacher, public Admin { // 系主任類別


friend ostream& operator<<(ostream&, Chairman&);
public:
Chairman(string n, Gender s, int a, string d):Person(n,s,a) { department = d;}
};

ostream& operator<<(ostream& o, Chairman& c)


{
return o << c.department << "系"
<< c.name << "主任(教師編號:" << c.Teacher::id
<< "、人員編號:" << c.Admin::id << ")\n";
}

int main()
{
Admin st[9]; // 隨意建幾個管理人員物件
Teacher te[3]; // 隨意建幾個教師物件
Chairman c("林樹紅", male, 55, "資訊");

cout << c;
c.goClass();
c.goMeeting();
}

4.
#include<iostream>
#include<string>
using namespace std;

enum Gender {male,female}; // 代表性別的列舉型別

class Person { // 人員類別


public:
Person(string, Gender, int);
Person() {}
protected:
string name; // 姓名
Gender sex; // 性別
int age; // 年齡
};

Person::Person(string n, Gender s, int a) : name(n)


{
sex = s; age = a;
}

class Meeting {
public:
void virtual goSchoolMeeting() =0; // 校務會議
void virtual goStudyMeeting() =0; // 學務會議
};

class Admin : virtual public Person, public Meeting { // 管理、行政人員類別


public:
Admin(string n, Gender s, int a):Person(n,s,a) { id = ++counter; }
Admin() {id = ++counter;}
void virtual goSchoolMeeting();
void virtual goStudyMeeting();
protected:
int id; // 人員編號
static int counter; // 物件計數器
};
int Admin::counter = 0;

void Admin::goSchoolMeeting()
{
cout << name << ((sex==male)?"先生":"女士")
<< "去開校務會議" << endl;
}

void Admin::goStudyMeeting()
{
cout << name << ((sex==male)?"先生":"女士")
<< "去開學務會議" << endl;
}

class Teacher : virtual public Person { // 教師類別


public:
void goClass() { cout << name << "老師在上課" << endl;}
Teacher(string, Gender, int, string);
Teacher() {id = ++counter;}
protected:
string department; // 系所名稱
int id; // 教師編號
static int counter; // 物件計數器
};
int Teacher::counter = 0;

Teacher::Teacher(string n, Gender s, int a, string d):Person(n,s,a)


{
department = d;
id = ++counter;
}

class Chairman : public Teacher, public Admin { // 系主任類別


friend ostream& operator<<(ostream&, Chairman&);
public:
Chairman(string n, Gender s, int a, string d):Person(n,s,a) { department = d;}
};

ostream& operator<<(ostream& o, Chairman& c)


{
return o << c.department << "系"
<< c.name << "主任(教師編號:" << c.Teacher::id
<< "、人員編號:" << c.Admin::id << ")\n";
}

int main()
{
Admin st[9]; // 隨意建幾個管理者物件
Teacher te[3]; // 隨意建幾個教師物件
Chairman c("林樹紅", male, 55, "資訊");

cout << c;
c.goClass();
c.goSchoolMeeting();
c.goStudyMeeting();
}

5.
#include<iostream>
using namespace std;

class Diving { // 潛水的介面


public:
virtual void down(int) =0; // 下潛
virtual void up(int) =0; // 上昇
};

class Fish : public Diving { // 魚


friend ostream& operator<<(ostream&, Fish&);
public:
void down(int);
void up(int);
Fish(int i=1) { if (i<0) i=0; deep = i;}
protected:
int deep; // 目前在水面下深度
};

ostream& operator<<(ostream& o, Fish& f)


{
return o << "魚目前在海平面下" << f.deep << "公尺";
}

void Fish::down(int m)
{
deep += m;
cout << "魚下潛" << m << "公尺,目前在海平面下" << deep << "公尺。\n";
}

void Fish::up(int m)
{
if(m>deep)
m = deep;
deep -= m;
cout << "魚上昇" << m << "公尺,目前在海平面下" << deep << "公尺。\n";
}

class Submarine : public Diving { // 潛艦


friend ostream& operator<<(ostream&, Submarine&);
public:
void down(int);
void up(int);
Submarine(int i=0, int j=100) { if (i<0) i=0; deep = i; maxdeep = j;}
protected:
int deep; // 目前在水面下深度
int maxdeep; // 可潛水最大深度
};

ostream& operator<<(ostream& o, Submarine& s)


{
return o << "潛艦目前在海平面下" << s.deep << "公尺";
}

void Submarine::down(int m)
{
if(deep==maxdeep)
cout << "潛艦已達最大深度,不能再下潛了";
else if(deep+m>maxdeep) {
cout << "潛艦只能下潛" << (maxdeep - deep) << "公尺,目前在海平面下" << maxdeep << "公尺。\
n";
deep = maxdeep;
}
else {
deep += m;
cout << "潛艦下潛" << m << "公尺,目前在海平面下" << deep << "公尺。\n";
}
}

void Submarine::up(int m)
{
if(m>deep)
m = deep;
deep -= m;
cout << "潛艦上昇" << m << "公尺,目前在海平面下" << deep << "公尺。\n";
}

int main()
{
Fish tuna(10);
cout << tuna;
tuna.down(5);
tuna.up(20);

Submarine seadragon(0,200);
cout << seadragon;
seadragon.down(50);
seadragon.up(15);
seadragon.down(180);
}
第14章

[學習評量]

1.ostream、istream

2.(c)

3.(a)

4.(b)

5.
(a) 1.23
(b) +1.234568
(c) +1.23457e+00

6.
(a) __C++
(b) C++***
(c) -000100

7.(d)

8.eof()

9.No

10.Pain,

[程式練習]

1.
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
ifstream file("Ch14-02.cpp"); // 開啟檔案

if (!file) // 若無法開啟檔案
cerr << "檔案開啟失敗" << endl;
else {
char ch;
while(!file.get(ch).eof()) // 若還沒到檔案結尾
cout << ch; // 顯示字元
}
}
2.
#include<iostream>
#include<iomanip>
#include<fstream>
using namespace std;

int main()
{
fstream file("NineNineTable",ios_base::out); // 開啟可寫入的檔案

if (!file) // 若無法開啟檔案
cerr << "檔案開啟失敗" << endl;
else {
for (int i = 1;i <=9; i++) {
for (int j = 1;j <=9; j++)
file << i << '*' << j << '=' << setw(2) << i * j << ' ';
file << '\n';
}
file.close(); // 關閉檔案
cout << "寫入完畢" << endl;
}
}

3.
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
ifstream file("NineNineTable"); // 開啟檔案

if (!file) // 若無法開啟檔案
cerr << "檔案開啟失敗" << endl;
else {
char str[80];
while(!file.eof()) { // 若還沒到檔案結尾
file.getline(str,80); // 顯示字元
cout<< str << endl;
}
}
}

4.
#include<iostream>
#include<iomanip>
using namespace std;

int main()
{
string str;
cout << "請輸入一中文字:";
cin >> str;

cout << str[0] << str[1] << "的字碼為:";

unsigned char i = str[0]; // 先顯示前半


cout << showbase << hex << (int) i;
i = str[1]; // 再顯示後半
cout << noshowbase << hex << (int) i << endl;
}

5.
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip> // 使用到 setw() 控制器
#include<cctype> // 使用到 isupper()、islower() 函式
using namespace std;

int main()
{
string filename;
cout << "請輸入要讀取的檔案名稱:";
cin >> filename;

int count[3] = { 0 }; // 用來統計各類型字元的陣列

fstream file(filename.c_str(), ios_base::in);


if (!file) // 若無法開啟檔案
cerr << "檔案開啟失敗" << endl;
else {
char ch;
while (!file.get(ch).eof()) // 未到檔案結尾前持續讀取
if (isalpha(ch)) // 若為字母
count[0]++; // 將對應位置的元素值加 1
else if (isdigit(ch)) // 若為數字字元
count[1]++; // 將對應位置的元素值加 1
else if (isspace(ch)) // 若為空白字元
count[2]++; // 將對應位置的元素值加 1
}
file.close();

cout << "英文字母共計 " << setw(4) << count[0] << " 個\n";
cout << "數字字元共計 " << setw(4) << count[1] << " 個\n";
cout << "空白字元共計 " << setw(4) << count[2] << " 個\n";
}
6.
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip> // 使用到 setw() 控制器
#include<cctype> // 使用到 isupper()、islower() 函式
using namespace std;

int main()
{
string filename;
cout << "請輸入要讀取的檔案名稱:";
cin >> filename;

int counter = 0; // 計算檔案字數的計數器


char buffer[524288]; // 儲存檔案內容的緩衝區,此處設為最大 512KB

fstream ifile(filename.c_str(), ios_base::in);


if (!ifile) // 若無法開啟檔案
cerr << "檔案開啟失敗" << endl;
else { // 以下先將檔案內容讀入 buffer[] 中
while (!ifile.get(buffer[counter]).eof()) { // 未到檔案結尾前持續讀取
if (islower(buffer[counter])) // 若是小寫就轉成大寫
buffer[counter] = toupper(buffer[counter]);
counter++;
}
}
ifile.close();

fstream ofile(filename.c_str(), ios_base::out); // 將檔案以寫入模式開啟


if (!ofile) // 若無法開啟檔案
cerr << "檔案開啟失敗" << endl;
else
for(int i =0;i<counter;i++) // 將 buffer[] 內容依次寫入檔案中
ofile.put(buffer[i]);

ofile.flush();
ofile.close();
}

7.
#include<iostream>
#include<iomanip>
#include<fstream>
using namespace std;

int main()
{
for (int i = 1;i <=9; i++) {
for (int j = 1;j <=9; j++)
cout << i << " * " << j << " = " << setw(2) << i * j
<< ((j%3==0)?'\n' : '\t');
cout << endl;
}
}

8.
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip> // 使用到 setw() 控制器
#include<cctype> // 使用到 isupper()、islower() 函式
using namespace std;

int main()
{
string filename;
cout << "請輸入要讀取的檔案名稱:";
cin >> filename;

fstream ifile, ofile;


ifile.open(filename.c_str(), ios_base::in);
string bakfilename = filename + ".bak";
ofile.open(bakfilename.c_str(), ios_base::out); // 將檔案以寫入模式開啟

if (!ifile | !ofile) // 若無法開啟檔案


cerr << "檔案開啟失敗" << endl;
else {
char ch;
while(!ifile.get(ch).eof()) // 將檔案內容存到 .bak 檔備份
ofile.put(ch);
}
ifile.close();
ofile.flush();
ofile.close();

// 重新開啟檔案, 將原檔案內容加上行號寫回

ifile.open(bakfilename.c_str(), ios_base::in);
ofile.open(filename.c_str(), ios_base::out);

if (!ifile | !ofile) // 若無法開啟檔案


cerr << "檔案開啟失敗" << endl;
else {
int counter = 1;
string oneline;
while (!ifile.eof()) { // 未到檔案結尾前持續讀取
getline(ifile, oneline);
ofile << setw(3) << setfill('0') << counter++ << ' ' << oneline << '\n';
}
}
ifile.close();
ofile.flush();
ofile.close();
}

9.
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip> // 使用到 setw() 控制器
#include<cctype> // 使用到 isupper()、islower() 函式
using namespace std;

int main()
{
string filename;
cout << "請輸入要去除行號的檔案名稱:";
cin >> filename;

fstream ifile, ofile;


ifile.open(filename.c_str(), ios_base::in); // 以唯讀模式開啟檔案
string bakfilename = filename + ".bak";
ofile.open(bakfilename.c_str(), ios_base::out); // 以寫入模式開啟檔案

// 先將檔案內容備份到 .bak 檔中

if (!ifile | !ofile) // 若無法開啟檔案


cerr << "檔案開啟失敗" << endl;
else {
char ch;
while(!ifile.get(ch).eof()) // 將檔案內容存到 .bak 檔備份
ofile.put(ch);
}
ifile.close();
ofile.flush();
ofile.close();

// 重新開啟檔案, 將原檔案內容去除行號寫回

ifile.open(bakfilename.c_str(), ios_base::in);
ofile.open(filename.c_str(), ios_base::out);

if (!ifile | !ofile) // 若無法開啟檔案


cerr << "檔案開啟失敗" << endl;
else {
string oneline;
while (!ifile.eof()) { // 未到檔案結尾前持續讀取
getline(ifile, oneline);
string::size_type pos=oneline.find_first_of(" "); // 本程式假設行號後空一格
// 即為檔案內容開始處
if(pos==string::npos) // 若找不到空白, 表示未加行號時該行為空白
ofile << '\n';
else
ofile << oneline.substr(pos+1) << '\n'; // 取空白後的子字串
} // 即為未加行號前的原始內容
}
ifile.close();
ofile.flush();
ofile.close();
}

10.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

int main()
{
string filename;
cout << "請輸入要複製的檔案名稱:";
cin >> filename;

fstream ifile, ofile;


ifile.open(filename.c_str(), ios_base::in); // 以唯讀模式開啟檔案
string bakfilename = filename + ".bak";
ofile.open(bakfilename.c_str(), ios_base::out); // 以寫入模式開啟備份檔

if (!ifile | !ofile) // 若無法開啟檔案


cerr << "檔案開啟失敗" << endl;
else {
char ch;
while(!ifile.get(ch).eof()) // 從來源檔讀取字元
ofile.put(ch); // 將字元寫到 .bak 檔備份
}
cout << "已將檔案內容複製到 " << bakfilename;
ifile.close();
ofile.flush();
ofile.close();
}
第15章

[學習評量]

1.(b)

2.(c)

3.(c)

4.(d)

5.(b)

6.(c)

7.(c)

8.(c)

9.(a)

10.第1個catch己會處理包含bad_allcate在內的所有exception例外物件,所以第2個catch段落將無法
發生預期效果(永遠不會被執行)。

[程式練習]

1.
#include<iostream>
#include<string>
#include<exception>
using namespace std;
#define SIZE 20

string five(char str[SIZE],int idx)


{
if(idx + 5 >= SIZE) // 若不足 5 個字或超出索引範圍
throw out_of_range("超出範圍!");
else {
string newone = string(str);
return newone.substr(idx,5); // 傳回從 idx 開始的 5 個字元
}
}

int main()
{
char test[20] = "Today is not Monday";
try { // 測試 five() 函式的功能
cout << five(test,0) << '\n';
cout << five(test,6) << '\n';
cout << five(test,16) << '\n';
}
catch (out_of_range e) {
cout << e.what();
}
}

2.
#include<iostream>
#include<exception>
#include<cctype>
using namespace std;
#define SIZE 20

void toupper(char str[SIZE])


{
for(int i=0;i<SIZE-1;i++) {
if(!isalpha(str[i]) && !isspace(str[i]))
throw invalid_argument("含不合法字元!");
else
str[i] = toupper(str[i]);
}
}

int main()
{
char test1[20] = "Today is not Monday";
char test2[20] = "I have 1000 dollars";

try { // 測試函式的功能
toupper(test1);
cout << test1 << '\n';
toupper(test2);
cout << test2 << '\n';
}
catch (invalid_argument e) {
cout << e.what();
}
}

3.
#include<iostream>
#include<exception>
using namespace std;

int caculate(int head, int feet) // 傳回雞隻數量的函式


{
if((feet%2==1) || // 腳是奇數
((feet-2*head)<0) || // 腳的數量太少
((4*head-feet)<0) ) // 腳的數量太多
throw invalid_argument("頭數或腳數不合理!");
else {
return (4*head-feet) / 2;
}
}

int main()
{
int rabbit,chicken;
int head,feet;

cout << "請輸入總頭數:";


cin >> head;
cout << "請輸入總腳數:";
cin >> feet;

try {
chicken = caculate(head,feet);
rabbit = head - chicken;
cout << "雞有" << chicken << "隻,免有" << rabbit << "隻。\n";
}
catch (invalid_argument e) {
cout << e.what();
}
}

4.
#include<iostream>
#include<iomanip>
#include<string>
#include<exception>
using namespace std;

class Account {
friend ostream& operator<<(ostream&, Account&);
public:
Account(string,double);
double deposite(double);
double draw(double);
protected:
string name; // 帳戶名稱
double balance; // 帳戶餘額
};

ostream& operator<<(ostream& o , Account& a)


{
return o << a.name << "的戶頭還有"
<< fixed << setprecision(2) << a.balance << "元\n";
}

Account::Account(string s, double money =0 )


{
name = s;
if (money < 0)
money = 0;
balance = money;
}

double Account::deposite(double money) // 存款


{
if(money > 0)
balance+=money;
return balance;
}

double Account::draw(double money) // 提款


{
if(money < 0)
money = 0;

if(balance < money) // 若餘額不足


throw balance;
else {
balance-=money;
return balance;
}
}

int main()
{
Account richman("王英清");

richman.deposite(10E6);

try {
richman.draw(50E6);
}
catch (double d) {
cout << "存款不足, 帳戶只剩" << fixed << setprecision(2) << d << "元\n";
}
cout << richman;
}

5.
#include<iostream>
#include<iomanip>
#include<string>
#include<exception>
using namespace std;

class Account {
friend ostream& operator<<(ostream&, Account&);
public:
Account(string,double);
double deposite(double);
double draw(double);
double transfer(double, Account&);
protected:
string name; // 帳戶名稱
double balance; // 帳戶餘額
};

ostream& operator<<(ostream& o , Account& a)


{
return o << a.name << "的戶頭還有"
<< fixed << setprecision(2) << a.balance << "元\n";
}

Account::Account(string s, double money =0 )


{
name = s;
if (money < 0)
money = 0;
balance = money;
}

double Account::deposite(double money) // 存款


{
if(money > 0)
balance+=money;
return balance;
}

double Account::draw(double money) // 提款


{
if(money < 0)
money = 0;

if(balance < money) // 若餘額不足


throw balance;
else {
balance-=money;
return balance;
}
}
double Account::transfer(double money, Account& a) // 轉帳
{
if(money < 0)
return balance;
else if (money > 100000)
throw out_of_range("防制洗錢,每次轉帳不可超過十萬元!");

if(balance < money) // 若餘額不足


throw balance;
else {
balance-=money;
a.balance+=money;
return balance;
}
}

int main()
{
Account richman("王英清");
Account richwoman("王玉英");

richman.deposite(10E6);

try {
richman.transfer(50000,richwoman); // 先轉帳 5 萬元
richman.transfer(120000,richwoman); // 再轉帳 12 萬元
}
catch (out_of_range e) {
cout << e.what() << '\n';
}
catch (double d) {
cout << "存款不足, 帳戶只剩" << fixed << setprecision(2) << d << "元\n";
}
cout << richman << richwoman;
}
第16章

[學習評量]

1. template

2.(b)

3. class

4.(c)

5.(a)

6.(d)

7.(d)

8.(c)

9.(d)

10.(b)

[程式練習]

1.
#include<iostream>
using namespace std;

template<class T>
T max(T a,T b)
{
if(a>=b)
return a;
else
return b;
}

int main()
{
cout << "請輸入兩個整數(以空白隔開):";
int i,j;
cin >> i >> j;
cout << "兩數字中最大值是:" << max<int>(i,j) << '\n';

cout << "請輸入兩個字元(以空白隔開):";


char c,d;
cin >> c >> d;
cout << "兩數字中最大值是:" << max<char>(c,d) << '\n';
}

2.
#include<iostream>
using namespace std;

template<class T>
void bubble_sort(T a[], int size) // 氣泡排序法
{
for(int i=0;i<size-1;i++)
for(int j=i+1;j<size;j++)
if(a[i]>a[j]) {
T temp = a[j];
a[j] = a [i];
a[i] = temp;
}
}

int main()
{
int test1[]={22,45,16,234,39}; // 測試用陣列
float test2[]={2.2,1.45,0.16,8.55,3.9}; // 測試用陣列

bubble_sort<int>(test1,5);
bubble_sort<float>(test2,5);

for(int i=0;i<5;i++)
cout << '[' << i << "]\t" << test1[i] << '\t' << test2[i] << '\n';
}

3.
#include<iostream>
using namespace std;

template<class T>
T minimun(T data[], int size) // 取最小值
{
T smallest = data[0]; // 計錄最小值
for(int i=1;i<size;i++)
if(data[i]<smallest)
smallest = data[i];
return smallest;
}

int main()
{
int all[] = {20,17,39,18,22,46};
double another[] = {7.65,3.4,2.11,1.5,4.33};
cout << "all[] 中最小的元素值是:" << minimun<int>(all, sizeof(all)/sizeof(int)) <<'\n';
cout << "another[] 中最小的元素值是:" << minimun<double>(another,
sizeof(another)/sizeof(double)) << '\n';
}

4.
#include<iostream>
#include<algorithm> // 含括必要檔案
using namespace std;

int main()
{
int all[] = {20,17,39,18,22,46};
double another[] = {7.65,3.4,2.11,1.5,4.33};

cout << "all[] 中最大的元素值是:" << *max_element<int*>(&all[0], &all[5]) <<'\n';


cout << "another[] 中最大的元素值是:" << *max_element<double*>(&another[0], &another[5]) << '\
n';
}

5.
#include<iostream>
#include<algorithm> // 含括必要檔案
using namespace std;

int main()
{
int all[] = {20,17,39,18,22,46};
double another[] = {7.65,3.4,2.11,1.5,4.33};

if(find<int*>(&all[0], &all[5],18) > &all[5]) // 若 find() 傳回位址超過最後一個元素的位址


cout << "在 all[] 中找不到值為 18 的元素。\n"; // 表示範圍內無該元素值
else
cout << "在 all[] 中有找到值為 18 的元素。\n";

if(find<double*>(&another[0], &another[5],99.9))
cout << "在 another[] 中找不到值為 99.9 元素。\n";
else
cout << "在 another[] 中有找到值為 99.9 的元素。\n";
}

6.
#include<iostream>
#include<stack> // 含括必要檔案
using namespace std;

int main()
{
stack<char*> hello;
char test[] = "Hello World!";

for(int i=sizeof(test)/sizeof(char)-1;i>=0;i--) // 將字串內容由後往前存入堆疊


hello.push(test+i);

for(int i=0;i< sizeof(test)/sizeof(char);i++) { // 逐字取出堆疊內容


cout << *hello.top();
hello.pop();
}
}

7.
#include<iostream>
using namespace std;

template<class T>
T* my_min(T* first, T* last) // 取 first 及 last 兩指標間最小元素的位址
{
T* smallest = first++; // 先以第 1 個元素為最小值
while(first <= last) { // 逐一比較各元素, 比較至 last 為止
if(*first < *smallest)
smallest = first;
first++;
}
return smallest;
}

int main()
{
int one[] = {20,17,39,18,22,46};
double two[] = {7.65,3.4,2.11,1.5,4.33,18.2};

cout << "one[] 中最小的元素值是:" << *my_min<int>(&one[0],&one[5]) <<'\n';


cout << "two[] 中最小的元素值是:" << *my_min<double>(&two[0],&two[5]) << '\n';
}

8.
#include <iostream>
#define MaxSize 20
using namespace std;

template<class T> // 因書中未提到鏈結串列,故單以陣列實作佇列


class Queue {
public:
Queue() { end = 0; }
void push(T data); // 存入一個元素到佇列最後面
T pop(); // 從佇列最前面取出一個元素
protected:
int end; // 記錄目前佇列結尾
T buffer[MaxSize]; // 代表佇列的陣列
static void Error() { cout << "\nQueue Error\n"; }
};

template<class T>
void Queue<T>::push(T data) // 將一個整數『堆』入佇列
{
if(end == MaxSize) // 若已達最大值, 則不能再放資料進來
Error();
else
buffer[end++] = data; // 將資料存入 end 所指元素, 並將 end 加 1
}

template<class T>
T Queue<T>::pop() // 從佇列中取出一個整數
{
if(end == 0) { // 若已經到底了表示佇列中應無資料
Error();
return 0;
}
else {
T temp = buffer[0]; // 先將佇列中的第1個元素存起來
for(int i=1;i< end;i++)
buffer[i-1]=buffer[i]; // 將佇列中元素都往前移一位
end--;
return temp; // 傳回原佇列中的第1個元素
}
}

int main()
{
Queue<int> qq1; // 定義整數佇列物件
Queue<char> qq2; // 定義字元佇列物件

// 將資料存入佇列中
qq1.push(1); qq1.push(2); qq1.push(3);

// 將資料存入第二個佇列中
qq2.push('a'); qq2.push('x'); qq2.push('e');

cout << qq1.pop();


cout << qq2.pop();
cout << qq1.pop();
cout << qq2.pop();
cout << qq1.pop();
cout << qq2.pop(); qq2.pop(); // 故意多 pop 一次
}
9.
#include <iostream>
#include <queue> // 含括 queue 樣版的定義
using namespace std;

int main()
{
queue<int> qq1; // 定義整數佇列物件
queue<char> qq2; // 定義字元佇列物件

// 將資料存入佇列中
qq1.push(1); qq1.push(2); qq1.push(3);

// 將資料存入第二個佇列中
qq2.push('a'); qq2.push('x'); qq2.push('e');

cout << qq1.front(); qq1.pop(); // 先用 front() 取得第 1 個元素


cout << qq2.front(); qq2.pop(); // 再用 pop() 削掉第 1 個元素
cout << qq1.front(); qq1.pop();
cout << qq2.front(); qq2.pop();
cout << qq1.front(); qq1.pop();
cout << qq2.front(); qq2.pop();
}

10.
#include <iostream>
#include <string>
#include <algorithm> // 含括必要的函式宣告
using namespace std;

void showhand(string* poker)


{
for(int i =0;i<13;i++)
cout << poker[i] << ' ';
cout << '\n';
}

int main()
{
// 代表撲克牌的陣列:S黑桃、H紅心、D方塊、C梅花
string poker[] = {"SA","SK","SQ","SJ","S10","S9","S8","S7","S6","S5","S4","S3","S2",
"HA","HK","HQ","HJ","H10","H9","H8","H7","H6","H5","H4","H3","H2",
"DA","DK","DQ","DJ","D10","D9","D8","D7","D6","D5","D4","D3","D2",
"CA","CK","CQ","CJ","C10","C9","C8","C7","C6","C5","C4","C3","C2"};

// 洗牌
random_shuffle(&poker[0],&poker[51]);
// 顯示洗牌結果
for(int i =1;i<=4;i++) {
cout << "第 " << i << " 位玩家手中的牌:";
showhand(&poker[(i-1)*13]);
}

// 再洗一次
cout << "再洗一次\n";
random_shuffle(&poker[0],&poker[51]);
for(int i =1;i<=4;i++) {
cout << "第 " << i << " 位玩家手中的牌:";
showhand(&poker[(i-1)*13]);

}
}

You might also like