書名:高中程式設計使用C/C++

出版商:泉勝出版公司

作者:洪國勝

序言

高中程式設計為2學分選修課,18週,所以規劃以下教材大綱與目錄,頁數200頁左右。

 

著作權聲明

本書著作權屬與洪國勝,洪國勝所屬公司網站是 www.goodbooks.com.tw 著作權屬於洪國勝。

 

著作財產權聲明

本電子教材財產權屬於泉勝出版,僅供老師選書參考,請共同尊重智慧財產權,不可散播此檔案,也不可將此全部或部分檔案複製成為自己上課教材,這樣以後沒有傻瓜願意繼續編輯與投資教材,以後也沒有教材讓老師們複製了。

 

 

選用紙本教材優點

選用本教材,學生看者紙本,將範例程式打一次,就是很好的學習過程與方式,老師也有時間喝口水喘口氣,快快樂樂春風化雨到六五。老師自編電子書教學,學生只會複製與貼上,永遠不會自己除錯,反而害了學生。

 

本書特色

1、用範例闡述指令。本書用範例闡述程式指令。這樣才會輕鬆明瞭。

2、程式解說融入程式。本書採用一面講解,一面寫程式,這樣學生才能很快融入程式情境。不會程式一大堆,程式寫完了才解說,這樣學生根本看不懂。

3、充分的自我練習。程式設計不是老師一直講,也不是學生一直讀,一定要讓學生依樣畫葫蘆,讓學生看著範例作出與範例相近的自我練習,這樣才是舉一反三,這樣學習才有效果,可以很快開竅,並自己寫出驚人程式。

4、單元教學。本書所有程式都很精簡,這樣學生才能專注的學習每個重點。

 

目錄

第一單元 程式的編輯、編譯與執行 

第二單元 算術運算 

第三單元 資料的種類與亂數的產生 

第四單元 程式的輸出入 

第五單元 程式的除錯 

第六單元 決策if運算 

第七單元 for迴圈

第八單元循序法 

第九單元 while迴圈

第十單元 二分法 

第十一單元 巢狀迴圈 

第十二單元 一維串列 

第十三單元 二維串列 

第十四單元 函式 

第十五單元 用Python學英文  

第十六單元 時間

第十七單元 排序 

第十八單元 搜尋 

 

第一單元 程式的編輯、編譯與執行

目前C/C++ 語言常用熱門的開發環境有Code::BlocksDev-C++因為APCS 考場採用Code::Blocks所以本書介紹Code::Blocks 如下

Code::Blocks

Code::Blocks 是目前最熱門的C/C++ 自由整合式開發環境IDE),APCS 考試也提供此IDECode::Blocks 官網https://www.codeblocks.org/),其下載與安裝方式如下

下載軟體

點選Downloads」,畫面如下圖

點選Download the binary release」,畫面如下圖:(往下捲動)

初學者請直接點選codeblocks-20.03mingw-setup.exe」,因為它才有內含C/C++編譯軟體否則需自備編譯軟體

 

安裝軟體

下載的檔案即是.exe執行檔請在下載區點按程式兩下就可自動執行開啟Code::Blocks」,畫面如下圖

範例1a試寫一程式可以於螢幕輸出"Hello"

提示本例所需程式僅為cout<<"Hello world!";

操作步驟

Step 1 開新專案。點選功能表的「File New Project」,畫面出現要求點選專案類型,本例點選『Console application』/『Go,如下圖。

出現歡迎畫面,如下圖,請點選「skip」。

Step 3 接著,要求點選開發C C++,本例點選「C++」。

Step 4 點選專案名稱與資料夾位置,本例於「Project title」輸入a1,資料夾位置為ch01,如下圖。

Step 5 點選輸出路徑,本例使用預設值,如下圖。

Step 6 完成以上設定,並展開下圖Sources main.cpp,畫面如下圖。

Step 7 編譯程式。點選功能表的「Build Build」。

Step 8 執行程式。點選功能表的「Build Run」。

(以上Step 78 兩個步驟,亦可點選工具列的「Build and Run」。)

Step 9 以上cout << "Hello world!" << endl;,就是本例所執行的程式,往後要寫任何的程式,只要將此述刪除,並在此位置寫下程式即可。

Step 10 開啟檔案總管,全部檔案如下圖:(本例於Step 4 的「Project title」輸入為a1,資料夾位置點選ch01,系統會自動建立a1 資料夾)。

Step 11 調整編輯器字型大小。點選功能表「Settings/Editor」,畫面如下圖,繼續點選「Choose」,即可依照指示完成字型大小的設定。

Step 12 若出現找不到編譯器(若之前有安裝其他C 語言,例如Dev-C++,有可能系統誤判而找不到編譯器)

1.     請點選功能表「Setting/Compiler」,畫面如下圖,在此畫面中,可以指定要使用的編譯器版本。(C++ 語言編譯器版本非常多,分別是111417 等等,往後線上查詢時就會明瞭。)

2. 繼續點選「Toolchain executables」,畫面如下圖,請留意您的編譯器路徑是否正確,若不正確請在此修改。

以下程式可計算長方形的面積與周長,請練習於main() 內輸入程式,並觀察執行結果。程式執行結果

int a=3;

int b=4;

int c,d;

c=a*b;

d=2*(a+b);

cout<<"面積="<<c<<endl;

cout<<"周長="<<d<<endl;

加上系統預設的程式樣版,全部程式如下:

#include <iostream>

 

using namespace std;

 

int main()

{

    int a=3;

    int b=4;

    int c,d;

    c=a*b;

    d=2*(a+b);

    cout<<"面積="<<c<<endl;

    cout<<"周長="<<d<<endl;

    return 0;

}

1. 本例若不指定命名空間,也就是不寫using namespace std;則每次鍵入coutcin 時,都要指定命名空間std::,程式如下:

#include <iostream>

int main() {

        std::cout<<"Hello";

        return 0;

}

2. 本例因為使用cout 物件,所以要預先載入其函式庫

        #include <iostream>

3.C 的函式庫均為.h, 例如: 數學函式庫為math.h。為了方便區分,C++ 新增函式的函式庫,則均沒有.h,例如:C++ 新增cmath 用來包含與取代math.h。又例如:C++ 新增的輸出入物件為cout cin,其函數庫為iostream 則用來取代 <stdio.h> 函式庫的scanf() printf()函式。

4. 鍵入程式應該要有層次感。例如:函式實作應該要使用 Tab 鍵內縮(初學者常用空白鍵內縮,那會很吃力,且無法完全整齊)。例如:以下的cout<<"Hello";,請先鍵入 Tab 鍵,再鍵入程式。

int main() {

        cout<<"Hello";

        return 0;

}

 

自我練習

1、以下是計算一元二次方程式兩根的程式,請自行練習鍵入程式。

#include <iostream>

#include <cmath>

using namespace std;

int main()

{

    int a=1;

    int b=-7;

    int c=6;

    double d,x1,x2;

    d=b*b-4*a*c;

    x1=(-b+sqrt(d))/(2*a);

    x2=(-b-sqrt(d))/(2*a);

    cout<<x1<<endl;

    cout<<x2<<endl;

    return 0;

}

 

2單元 算術運算

前面第1單元,我們已經給一個計算長方形面積的程式,讓大家鍵入程式,觀察執行結果,本單元就要開始介紹如何『設計』程式。

 

範例2a已知長方形的長與寬,請寫一個程式,求其面積。

資料的數位化

1、本題若使用掌上型計算機,其方法是直接將鍵入『長*=』,就可得到答案。例如,鍵入『15*8=』,就可得到答案『120』。

2、但使用電腦計算,必須先將所要計算的值先以一個英文代號儲存,例如a,bscore,此稱為『變數』。目標是將資料與程式分開,這樣當資料改變時,還可重複計算。而且,計算過程都是以程式語言描述,此稱為程式設計,只要第一次對,往後都對,計算結果有一致性。不用像計算機要按兩次,才能確認計算結果正確。

3、評估資料來源的大小。每一種資料均需要不同大小的記憶體儲存電腦為了有效率的處理這些資料所以有資料型態的規劃也就是大的資料用大盒子裝小的資料用小盒子裝如此一來即可節省記憶體又加快處理效率反過來說若不分資料大小通通用大盒子裝資料那將會非常浪費記憶體也拖慢執行效率,就像滑鼠都用冰箱的箱子裝,當然可以,但就會很浪費空間,且搬運很費時下表是C/C++語言的數值資料型態,unsigned表無號整數,即非負數整數:

數值資料型態

佔用記憶體的大小(位元)

所能代表的數值的範圍

short

16

-32,768 ~ +32,767

int

32

-2,147,483,648 ~ +2,147,483,647

long

32

-2,147,483,648 ~ +2,147,483,647

unsigned short

16

0 ~ 65,535

unsigned int

16

0 ~ 4,294,967,295

unsigned long

32

0 ~ 4,294,967,295

float

32

3.4x10-38 ~ 3.4x1038

double

64

1.7x10-308 ~ 1.7x10308

long double

80

3.4x10-4932 ~ 3.4x104932

上表有點複雜,所以取常用資料型態如下:初學者遇到整數就取int,遇到浮點實數就取系統預設的double

數值資料型態

佔用記憶體的大小(位元)

所能代表的數值的範圍

int

32

-2,147,483,648 ~ +2,147,483,647

double

64

1.7x10-308 ~ 1.7x10308

4、變數的宣告

變數宣告的優點是可配置恰當的記憶體而提高資料的處理效率。例如,有些變數的值域僅為整數,則不用宣告為floatdouble。此即為小東西用小箱子裝,大東西用大箱子裝,才能有效運用空間與提升搬運效率。C/C++語言的變數宣告語法如下:

    資料型態 變數名稱[=初值];

例如,

    int a;

即是宣告變數 a int 型態。變數的宣告亦可連同初值一起設定,如下所示:

    double d = 30.2;

宣告ddouble型態, 並設其初值是30.2。以下程式,同時宣告兩個整數,且指派其初值。

    int f1=3,f2=4;

變數經過宣告之後,編譯器即會根據該變數的資料型態配置適當的記憶體儲存此變數,所以若要提高程式的執行效率,則應儘量依照資料性質,選擇佔用記憶體較小的資料型態。本例變數宣告與賦與初值如下:

int a=15,b=8;

 

5、使用程式語言寫出運算結果。前面已將初值以變數儲存,面積的計算也是先將結果先以變數儲存如下,本例宣告面積以area儲存,且其型態是int

int area;

area=a*b;

6、輸出結果。本例將結果輸出如下:

cout<<area;

7、全部程式如下:

#include <iostream>

using namespace std;

int main()

{

    int a=15,b=8;

    int area;

    area=a*b;

    cout<<a;

    return 0;

}

 

識別字Identifiers

真實的世界裡每個人物都有一個名稱程式設計亦不例外於程式設計時必須為每一個變數常數函式結構及類別命名以上所有變數常數函式結構及類別等名稱統稱為程式語言的識別字C/C++語言的識別字命名規則如下

1. 識別字必須是以字母大小寫的A Z或底線_開頭例如以下是一些合法的識別字

        a

        i

        sum

        _sum

        Income

以下是一些非法的識別字

        7eleven  // 不能由數字開頭

        %as   //不能由符號開頭

2. 識別字由字母開頭後僅可由字母底線及數字組合而成但不得包含空白例如以下是一些合法的識別字

        a123

        a123b

        a_b

以下是一些非法的識別字

        A=  //不能含有 = */

        sum!   //不能含有 ! */

        Age#3  //不能含有 # */

        a c  // 不能含空白

        c+3  // 不得含有加號 */

3. 識別字的長度不可以超過32 個字元

4. 識別字的大小寫均視為不同例如Scorescore SCORE 皆代表不同的識別字

5. 識別字不得使用保留字iffor 但是if1fora 等則可使用

 

保留字(Keywords)

保留字(又稱關鍵字)是任一程式語言已事先賦予某一識別字(可識別的文字或字串,稱為識別字)一個特別意義,所以程式設計者不得再重複賦予不同的用途。例如if已賦予決策敘述,程式設計者當然不得再定義if為另外的用途,以下是C/C++語言的保留字,請於 https://en.cppreference.com/w/點選 Keywords』。

 

 

算術運算子(Arithmetic operators)

算術運算子用來執行一般的數學運算,包括指派(=)、取正負數( +/- )、加( + )、減( - )、乘( * )、除( / )、取餘數(%)、遞增(++)及遞減(--)等,下表是C/C++語言的算術運算子列表:

運算子

定義

優先順序

結合律

=

指派

14

由右至左

++,--

後置遞增/遞減

1

由左至右

++/--

前置遞增/遞減

2

由右至左

+/-

正負號,一元運算子

2

由右至左

*

乘法運算

3

由左至右

/

除法運算

3

由左至右

%

求餘數(Modulus)

3

由左至右

+/-

加法/減法運算

4

由左至右

以上運算子的運算結果、運算子優先順序、運算子結合律等,分別說明如下:

 

指派運算子(Assignment operators

指派運算子的符號為(=),又稱為賦值運算子,其作用為將運算符號右邊運算式的值指派給運算符號左邊的運算元。所以,以下敘述sum=sum+a是將sum+a先運算,再將運算結果的值指派給sum

    int sum = 0,a = 3;

    sum = sum + a;

上式與數學的『等號』是不同的,所以不要一直糾結為什麼0會等於8。其次,你是不能將常數放在指派運算子的左邊,例如,    

    8 = a ;

此為一個不合法的敘述,但以下敘述,將常數8指派給變數a是合法的。

    a = 8 ;

算術五則運算

以下是一些算術五則運算,請鍵入以下程式,並寫出執行結果。

#include <iostream>

using namespace std;

int main() {

        int x=5, y=4;

        cout <<x+y<<endl; // 9

        cout <<x-y<<endl; // 1

        cout <<x*y<<endl; // 20

        cout <<x/y<<endl; // 1 兩者都是整數,商也是整數

        cout <<x%y<<endl; // 1

        return 0;

}

 

整數除法或實數除法

C/C++ 語言的除法運算只有被除數與除數的型態均為整數才是整數除法得到整數商其次只要被除數與除數有一型態為實數即為實數除法得到實數商請鍵入以下程式,並寫出執行結果。

int main() {

        int x=5, y=4;

        double z=4;

        cout <<x/y<<endl; // 1

        cout <<x/z<<endl; // 1.25

        cout <<y/x<<endl; // 0

        cout <<z/x<<endl; // 0.8

        z=x/y;

        cout<<z<<endl; //

}

整數除法與取餘的應用

整數除法與取餘可以將一個整數分解為數個數字例如若要將一個整數152 分解為152 三個數字其方法如下

        int a=152;

        int a3=152%10; // 個位數

        a=a/10;

        int a2=a%10; // 十位數

        a=a/10;

        int a1=a ; // 百位數

        cout<<a1<<a2<<a3; 取餘

若要讓一個數字在累加的過程中保持一定的循環那也是用取餘例如

        while(1) { // 無窮迴圈,參看第6 單元

                b=a[i];

                i=(i+1) %4;

        }

i 就永遠在0123 循環這樣i才不會越來越大,讓索引溢位。

程式與數學的差異

數學有

       19/10=1…9

的書寫習慣,但電腦並沒有此運算方式,因此以上運算方式,一定要先取餘數,再求整數商如下:

       int a=19,b=10;

  int c=a%b;

  int d=a/b;

順序錯也不行,以下程式,先除再取餘數,結果就不一樣。

       int a=19,b=10;

    int d=a/b;

       int c=a%b;

 

自我練習

1. 請指派一個四位數,並將其分解輸出為四個數字。例如:輸入1234,可以輸出4,3,2,1,且輸出其數字和,本例為10

2. 請指派一個0 86399 的整數,並分解為HHMMSS 等時間格式。

3. 請任意指派一個5 位數,請問如何分解為兩個一組。例如:a=25678,如何分別得到78,67,56,25 4 個數字;其次,要如何得到78,56,2 等三組數字呢。

4. 請任意指派一個5 位數,如何得到最左邊與最右邊數字的和。例如:a=12345,那結果是6

5. 請任意指派一個5 位數,那如何得到最左邊兩位數與最右邊兩位數字的和。例如:a=12345,那結果是12+45=57

6. 請任意指派一個6 位數,那如何得到最左邊三位數與最右邊三位數字的和。例如:a=123456,那結果是123+456=579

7. 請任意指派一個6 位數, 並計算其奇位數與偶位數之和。例如:a=123456,那結果是12 9

 

遞增++及遞減––

遞增++及遞減––C/C++ 語言特有的運算子此二個運算子又分為前置與後置前置是運算子在運算元之前

        a=1;++a;cout<<a<<endl; // 2

後置是運算子在運算元之後

        a=1;a++;cout<<a<<endl; // 2

原則上不論++a a++ 都是將a 值加1 並放回a但若是

        a=1;b=++a; // a=a+1;b=a;2 2

        a=1;b=a++ ; // b=a;a=a+1;2 1

則其a 值均會加1b 值會有差異前置b 值會得到加1 的結果後者只能得原a 請鍵入以下程式,寫出執行結果。程式執行結果

#include <iostream>

using namespace std;

int main() {

        int a,b;

        a=1;++a;cout<<a<<endl;

        a=1;a++;cout<<a<<endl;

        a=1;b=++a;cout<<a<<endl;cout<<b<<endl;

        a=1;b=a++;cout<<a<<endl;cout<<b<<endl;

        return 0;

}

複合指派運算子

結合指派與算術的運算子稱為複合指派運算子,此乃C語言特有的運算子,例如程式設計者常會鍵入sum=sum+5,程式語言乃制定此一複合指派運算子『+=』,所以上述sum=sum+5,即可寫成sum + = 5,下表是C/C++語言常用的複合指派運算子:

運算子

定義

優先順序

結合律

=

指派內容

14

由右至左

+=

相加之後再指派內容

14

由右至左

-=

相減之後再指派內容

14

由右至左

*=

相乘之後再指派內容

14

由右至左

/=

相除之後再指派內容

14

由右至左

%=

取餘之後再指派內容

14

由右至左

例如,

        int sum=0,a=5;

        sum+=5;

        cout<<sum;//5

        sum/=a;

        cout<<a;//1

 

運算子的優先順序(Precedence)

同一敘述,若同時含有多個運算子,此時即需定義運算子的優先順序。例如:

   x=a+b*c;

在數學裡,我們定義先乘除再加減,程式語言也是相同,必須定義這些運算子的優先順序,C語言的運算子優先順序如下表:

優先順序

運算子

說明

結合律

1

++,--

後置遞增與遞減。例如a++,a--

由左至右

2

++,--

+/-

!

前置遞增與遞減。例如++a,--a

取正或取負。

邏輯否定。

由右至左

3

*,/,%

算術乘、除、取餘。

由左至右

4

+,-

算術加、減

6

>,>=,<,<=

關係運算的大小。

7

==,!=

關係運算的相等或不相等。

11

&&

邏輯的and

12

||

邏輯的or

14

=,+=,-=,*=,/=,%=

指派與複合指派。

由右至左

 

由以上各運算子的『先順序』可知,乘號『*』的優先順序是第3,而加號『+』則是第4。所以,以上敘述:

x=a+b*c;

的結果與

x=(a+(b*c));

的效果相同。同理,

x=a>b && b>z;

的結果同義於

      x=(a>b) && (b>z);

自我練習

1、鍵入、執行以下程式,並寫出執行結果。

程式

執行結果

#include <stdio.h>

#include <stdlib.h>

int main() {

        int a,b,c; 

        a=1;b=2;b=3;

        a=a+a*2/2-3%2;

        cout<<a<<endl;     

        a=5;b=4;

        c= a>2  && !(b>3) ||(a==3);

        cout<<c;

        return 0;

}

 

 

運算子的結合律(Associativity)

當同一敘述,相鄰的運算子擁有相同優先順序的運算子,此時即需定義運算子是『由左至右』的左結合或『由右至左』的右結合。例如:

x=a-b-c;

同樣是減號(-),優先順序相同,此時就要靠定義結合律,減法結合律是由左至右,所以以上同義於

x=((a-b)-c);

a=b=c=2;

指派運算子的結合律是由右至左,所以以上式子同義於:

(a=(b=(c=2)));

以上式子,abc的結果都是2

 

自我練習

1、鍵入、執行以下程式,並寫出執行結果。

程式

執行結果

#include <stdio.h>

#include <stdlib.h>

int main() {

        int a=3,b=2,c=1;

        c=a-b-c;

        cout<<c;

        a=b=c=2;

        cout<<a<<b<<c<<endl;

        return 0;

}

 

關於以上運算子的詳細說明可點選https://en.cppreference.com/w/c裡面的『Expressions』,如下圖:

 

繼續點選上圖的『operator precedence 』,還可得運算子的優先順序,如下圖:

 

 

次方與根號

C/C++ 語言的術運算子只有以上+, –, *, /, %若所需運算沒有運算子那就要用數學函式例如您想要次方或開根號運算應因為C/C++ 並沒有次方運算子^與開根號所以若要執行次方運算,那就要使用數值處理函式中的pow() 函式如下所示為計算3 的平方:,

a=pow(3,2)// include<math.h> <cmath>

若要執行根號運算則應使用數值處理函式的sqrt() 函式如以下敘述是計算9 的開根號

x=sqrt(9); // include<math.h> <cmath>

但以上數值函數C 語言是放在math.hC++ 是放在cmath因為C++ 包含C所以在標頭檔通通使用

#include<cmath>

載入函式就可以使用所有數學函式。請留意以上敘述載入標頭檔不用分號;結束請鍵入以下程式,並觀察執行結果。

 

自我練習

1、請寫一程式,可以指派長方體的長、寬、高,計算其表面積與體積。

範例2b請寫一程式,滿足以下條件。

(1)   可以指派兩個座標。

(2)   計算此兩點座標距離。

(3)   輸出此兩點距離。

(4)   例如:P(0,3)Q(4,0)的距離是5

 

解題步驟

1.資料的數位化。

         int x1=0,y1=3;

         int x2=4,y2=0;

2.寫出演算法。本例已知兩點座標分別是(x1,y1),(x2,y2),則其距離的公式的數學語言是:

        

3.將演算法以程式語言表示。

         double d=sqrt(pow((x1-x2),2)+pow((y1-y2),2));

    cout<<d;

自我練習

1.已知三角形三邊長a b c,求其面積。

提示:先計算d=(a+b+c)/2,則三角形面積= ,本例假設所輸入的三角形三邊長可圍成三角形,例如:指派int a=3,b=4,c=5;則得三角形面積6,但並不是任意三條線都可圍成三角形,若要判斷是否可圍成三角形,請繼續研讀下一單元。

 

計數器

日常生活常需要計數,例如,景點通常有一個計數器,累計今天進園人數,程式設計也不例外,常常需要統計執行幾次,此件事由電腦做的程式如下:首先,先宣布與清除計數值變數。

int num=0;

每執行一次計數值加1的程式如下:

num=num+1;

請鍵入以下程式,並觀察執行結果:

#include <iostream>

using namespace std;

int main()

{

    int num=0;

    int a=8,b=3;

    a=a-b;

    num=num+1;

    a=a-b;

    num=num+1;

    cout<<a<<endl;

    cout<<num<<endl;

    return 0;

}

自我練習

請鍵入以下程式,寫出執行結果。

題號

題目

輸出結果

1

#include <iostream>

using namespace std;

int main()

{

       int a=321;

       int s=0;

       int num=0;

       int b;

       b=a%10;

       s=s+b;

       a=a/10;

       num++;

       cout<<"b="<<b<<endl;

       cout<<"s="<<s<<endl;

       cout<<"a="<<a<<endl;

       cout<<"num="<<num<<endl;

 

       b=a%10;

       s=s+b;

       a=a/10;

       num++;

       cout<<"b="<<b<<endl;

       cout<<"s="<<s<<endl;

       cout<<"a="<<a<<endl;

       cout<<"num="<<num<<endl;

 

       b=a%10;

       s=s+b;

       a=a/10;

       num++;

       cout<<"b="<<b<<endl;

       cout<<"s="<<s<<endl;

       cout<<"a="<<a<<endl;

       cout<<"num="<<num<<endl;

       return 0;

}

 

 

變數內容的交換

程式設計常常需要將兩個變數的內容交換,兩個變數的內容要交換,就如同兩隻手的東西要交換位置。所以假設你有ab 兩隻手,各拿一樣東西,那要交換其位置的方法如下:

1. 先找來第3 隻手t

2. a 的東西交給t 暫存。

        t=a;

3. b 的東西交給a

        a=b;

4. t 的東西交給b,而完成兩隻手東西的交換。

        b=t;

5. 其次,若未先找來第三之手t 幫忙,電腦並沒有這個能力,同時拋出雙手東西,再同時接住另一手的東西,如以下述:

        a=b;

        b=a;

6. 這就是一種運算思維,電腦運算要很明確,全部程式如下:

#include <iostream>

using namespace std;

int main() {

        int a=3,b=4;

        int t;

        t=a;a=b;b=t;

        cout<<"a="<<a<<endl;

        cout<<"b="<<b<<endl;

        return 0;

}

自我練習

試寫一程式,可以指派三個數,並將1 交給22 交給33 交給1,並輸出。

 

 

資料抽象化

若有一直線方程式是ax+by+c=0,點p(m,n)到直線的距離是

這件事若要由電腦做,就是將資料從人類約定的書寫習慣ax+by+c=0獨立抽象出來。例如,直線方程式是3x+4y+5=0,求點p(1,2)到直線的距離,首先,以

       int a=3,b=4,c=5;

約定此為直線

       3x+4y+5=0

然後以

       int m=1,n=2;

約定此為p(1,2),所以全部程式如下:

#include <iostream>

#include <cmath>//使用abs()  and sqrt()

using namespace std;

int main( )

{

    int a=3,b=4,c=5;

    int m=1,n=2;

    double d;

    d=abs(a*m+b*n+c)/sqrt(a*a+b*b);

    cout<<d;//3.2

 return 0;

}

範例2c

寫一個程式,可以指派一個一元二次方程式ax2 + bx + c = 0的係數a,b,c,並求其解(本例假設所輸入的方程式恰有二解)。

參考解答

解一元二次方程式的公式法,演算步驟如下:

(1)    設有一元二次方程式如下:

ax2 + bx + c = 0

(2)輸入a,b,c三個整數。(本例假設整係數方程式,先指派其為a=2;b=-7;c=3

(3)d=。提示:此為數學語言,C/C++語言是d=sqrt(b*b-4*a*c); ,括號、乘號均不能省。)

(4)    則其二解分別為。(提示:此為數學語言,C/C++語言是x1=(-b+d)/(2*a),括號、乘號均不能省。)

(5)例如,2x2-7x+3=0。其解為x1=3.0 ,x2=0.5

參考解答

本例先假設所指派的係數一定有實數解,待下一單元再判斷所輸入係數有沒有實數解。

#include <iostream>

#include <cmath>//使用 sqrt()

using namespace std;

int main( )

{

    int a=2,b=-7,c=3;

    double d=sqrt(b*b-4*a*c);

    double x1=(-b+d)/(2*a);

    double x2=(-b-d)/(2*a);

    cout<<x1<<endl;

    cout<<x2;

 return 0;

}

什麼是『運算思維』?

近來運算思維廣為被大家討論,筆者淺見是各有各的特性與優勢,所謂運算思維,就是要學習電腦有哪些特性與優勢,並使用電腦的運算思維寫程式。以本範例解一元二次方程式為例,人類用十字交叉法較快,但是電腦使用公式法較快,此即為電腦的運算思維,往後各單元還有更多電腦運算思維,學習這些運算思維,就可增加程式設計功力。

 

自我練習

1、寫一個程式,可以指派一個二元一次方程式,並求其解(本例假設所指派的方程式恰有一解)。

提示:解二元一次方程式的克拉馬公式演算過程如下:

 (1). 設二元一次方程式如下:

 (2)資料的抽象化。本例可指派a1,b1,c1,a2,b2,c2等六個整數。

 (3)     = a1b2 – a2b1

(4).   則其解分別是          

(5)例如,

         3x+y=5

         x-2y=-3

指派變數如下:

    a1=3;b1=1;c1=5;

         a2=1;b2=-2;c2=-3;

則其解為 x=1 y=2

 

補充說明

解二元一次方程式,國中會先教代入消去法與加減消去法,這都需要一點判斷,但可以簡化計算,本題使用公式法,可完全不用判斷,直接計算而得,這樣最適合計算機了,也是電腦的運算思維。

 

亂數

程式設計常常需要一些任意整數來測試或模擬結果此時就需要請電腦取亂數 C++ 取亂數的方法較為複雜,以下是C語言取亂數的方法

rand()

C 語言傳回0 32767 的亂數例如

        int a=rand();

        cout<<a;

傳回0 32767 的任意整數使用前應先匯入

        #include <stdlib.h> // 使用rand()

但電腦不是萬能要如何於亂數表任意選擇一個起點呢因為每次執行的系統時間不同所以就可以以系統時間當作亂數的起點全部程式如下

#include <iostream>

#include <time.h> // 使用time()

#include <stdlib.h> // 使用rand()

using namespace std;

int main()

{

        srand(time(NULL));

        int a=rand();

        cout<<a;

        return 0;

}

以下程式可取0 5 的任意整數

        int a=rand()%6;

以下程式可取1 6 的任意整數

        int a=1+rand()%6;

小寫字元的ASCII97122,以下程式,可產生1個小寫字元。

#include <iostream>

#include <time.h> // 使用time()

#include <stdlib.h> // 使用rand()

using namespace std;

int main()

{

       srand(time(NULL));

       int a=97+rand()%26;

       cout<<a<<endl;

       cout<<(char)a;

       return 0;

}

自我練習

1、          請問如何取38的亂數。

2、          請問如何取小數點兩位的實數亂數。

 

發聲

要讓電腦發出聲音,可使用_beep()函式,此函式C語言放在stdlib.h,所以要載入標頭檔 #include <stdlib.h>C++則放在<iostream>其與法如下:

         void _beep(unsigned int x,unsigned int y);

x是要發出的頻率,單位是Hzy是發聲的時間,單位是ms。其次,鋼琴鍵盤頻率對照表如下:

G1003

例如,以下敘述可發出『Do』的音,且持續0.5 秒。

       _beep(523,500);

又例如,以下程式可發出DoReMeFa…等八個音。

#include <iostream>

int main()

{

    _beep(523,500);

    _beep(587,500);

    _beep(659,500);

    _beep(698,500);

    _beep(784,500);

    _beep(880,500);

    _beep(988,500);

    _beep(1046,500);

    return 0;

}

演奏音樂

要讓電腦演奏音樂,那就要先下載一個簡譜,如下圖。(摘自http://blog.roodo.com/midiland/archives/1679070.html,特別致謝)

G1004

本例一分鐘80拍,以一個四分音符為1拍,所以1拍的時間是,60000ms/80。上圖一個八分音符所佔的時間是60000ms/(2*80),每小節是2拍。其次,上圖所有音符的最小速度是八分音符,所以我就取八分音符的時間為1個單位。以下僅作4 小節,『我有一隻小毛驢我從來也不騎』。

#include <iostream>

int main()

{

    int t=60000/160;

    _beep(523,t);

    _beep(523,t);

    _beep(523,t);

    _beep(659,t);

    _beep(784,t);

    _beep(784,t);

    _beep(784,t);

    _beep(784,t);

    _beep(880,t);

    _beep(880,t);

    _beep(880,t);

    _beep(1064,t);

    _beep(784,4*t);

    return 0;

}

自我練習

1、          請繼續完成以上音樂。

2、          請用輸出指令讓輸出音樂的同時,銀幕也輸出歌詞,那就是KTV了。

3、          請自己找一首歌,完成輸出歌詞與音階。

補充說明

1、請熟悉以上發音方式,第五章還會介紹如何製作電子琴。

2、以上僅輸出一小節,程式就有點冗長,那寫完一首歌不就累垮。請放心,待介紹迴圈與陣列就會明瞭。

警車聲音

警車的警報聲是連續發出頻率265Hz 350Hz 所形成,以下以C語言示範發出此聲音。

#include <stdio.h>

#include <stdlib.h>

int main()

{

    while(1){//無窮迴圈,請看第六章

        _beep(265,300);

        _beep(350,700);

        _sleep(50);//空白

    }

    return 0;

}

自我練習

1. 市內電話來電大都採用1000Hz 500Hz 交錯形成的樂音,請寫程式完成。

2. 同上題,練習讓鈴聲可越來越急。(此題可待學完迴圈再作)

3. 音感練習。請觀察您家微波爐、洗衣機、汽車安全帶未繫、倒車警告、手機的各種聲響,並寫程式完成。

4. 作曲練習。請嘗試發出不同頻率的聲音,觀察是否悅耳而吸引人,您是否能作曲呢?

 

3單元 字元、字串與布林型態

字元常數Character literals

使用單引號'圍住的單一字元稱為字元常數例如'A' 'a' C++ 語言使用8 bits ASCII所以可表示256 個字元包含大小寫英文字母數字標點符號及其它特殊符號C++使用    char 型態儲存字元。例如:

        char a='a';

    cout<<a;

字元轉數字

字元轉數字靠轉型。例如:

int main(){

         char a='a';

         int b=(int)a;

         cout<<b;

         return 0;

}

數字轉字元

數字轉字元也是靠轉型。例如:

int main()

{

         int a=65;

         char b;

         b=(char)a;

         cout<<b;

         return 0;

}

字串String

C/C++ 語言中字串以雙引號"所圍住例如"Gwosheng"" 臺灣" C使用字元陣列儲存,例如,

       char a[]="gwosheng";

    cout<<a;

C++新增 string型態儲存,例如,

       string b="gwosheng";

    cout<<b;

且原來的字元陣列也可以在C++使用。請鍵入以下程式,觀察執行結果。

#include <iostream>

using namespace std;

int main()

{

    char a[]="gwosheng";

    cout<<a<<endl;

    string b="gwosheng";

    cout<<b;

    return 0;

}

字串的運算

除非要考APCS學科,不然就不用學C的字串處理方式,因為C++處理字串和上一單元數值處理的習慣較相同較合乎我們的使用習慣。例如,以下程式是字串的複製、清除與相加:

#include <iostream>

using namespace std;

int main()

{

    string a="123",b="456",c;

    c=a;

    cout<<c<<endl;//123

    c="";

    cout<<c<<endl;

    c=a+b;

    cout<<c<<endl;//123456

    return 0;

}

字串與數值轉換

字串與數值轉換要使用string 物件的方法使用前請先載入

        #include<string> or #include<cstring>

但因cstring 包含string所以本書直接通通載入

        #include<cstring>

 

stoi

將字串轉數值請鍵入以下程式並寫出執行結果

        string a="123";

        string b="123";

        string c=a+b; // 123123

        cout<<c<<endl;

        int d=stoi(a)+stoi(b);

        cout<<d<<endl; // 246

to_string

將數值轉字串請鍵入以下程式並寫出執行結果

        int a=123;

        int b=123;

        int c=a+b;

        cout<<c<<endl; // 246

        string d=to_string(a)+to_string(b);

        cout<<d<<endl; // 123123

鍵入以下程式,寫出執行結果。

#include <iostream>

#include<string>

using namespace std;

int main()

{

       int a=6;

       int n=2;

       int r=0;

       string d="";

       r=a%n;

       a=a/n;

       d=to_string(r)+d;

       cout<<d<<endl;

       r=a%n;

       a=a/n;

       d=to_string(r)+d;

       cout<<d<<endl;

       r=a%n;

       a=a/n;

       d=to_string(r)+d;

       cout<<d<<endl;

       return 0;

}

更多的物件方法,線上查詢basic_stringhttps://en.cppreference.com/w/cpp/string/basic_string

 

 

4單元 程式的輸出入

C++ 使用cout cin 物件作為輸出入分別說明如下:

cout

cout 物件可輸出指定任何文數字與變數內容而且不用去管變數的資料型態其語法如下

        cout << 字串或變數 [<< 字串或變數] [<<endl] ;

語法中的中刮號"[]" 表示可省略例如

        int a=5;

        cout<<a;

可輸出5又例如

        int a=5;

        cout <<"a="<<a;

則可輸出a=5」。其中第一個『a』用雙引號刮住『"a="』表示字串內容將會以字串方式輸出第二個a」,則是變數將會往前找對應變數的內容,且輸出此內容。『endl(endline)代表此列的輸出結束跳離此列往後的輸出移至下一列的開頭例如

        cout <<"Good"<<endl;

        cout <<"Good";

可輸出

        Good

        Good

但是

        cout <<"Good";

        cout <<"Good";

則輸出

        GoodGood

請鍵入以下程式,並觀察執行結果。

#include <iostream>

using namespace std;

int main() {

        cout <<"Good"<<endl;

        int a=5;

        cout <<"a="<<a<<endl;

        return 0;

}

cin

cin 物件可輸入文數字至指定的變數其語法如下

        cin>> 變數 [>> 變數] ;

例如

        char a;

        cin >>a;

        cout <<"a="<<a<<endl;

可輸入字元至變數a又例如

        int b;

        cin >>b;

        cout<<"b="<<b<<endl;

可輸入整數至變數bC語言使用字元陣列表示字串,以下程式可輸入字串:

        char c[5]; // 字元陣列,代表字串,C style

        cin>>c;

        cout<<c<<endl;

C++語言使用string型態表示字串,以下程式可輸入字串:

        string d; // 字串,C++ style

        cin>>d;

        cout<<d;

若要輸入含空白字串例如"This is a book."則要使用getline() 函式程式如下

        string b;

        getline(cin,b); // 可輸入含空白字串

        cout<<b;

以下程式則可連續輸入3 個變數輸入時變數之間請以空白隔開例如輸入3 4 5 則三個變數變數a,b,c 分別得到3,4,5

        int a,b,c;

        cin>>a>>b>>c;

        cout<<a<<" "<<b<<" "<<c;

自我練習

 1. 請寫一個程式,程式一開始要求使用者輸入人名,有提示字「Pleaseinput your name:」,接著要求輸入身高,有提示字「input yourheight」,最後輸出「Your Name is..., your height is...」。

2. 請於「https://en.cppreference.com/w/」搜尋cout cin 的語法。

提示 請點選「Stream-based I/O」。

 

5單元 決策運算

人類的生活必須不斷地面對決策問題。程式語言是協助解決人類問題的工具,當然也有決策指令。本單元即是探討C++決策所需使用的運算子與指令。請先鍵入以下程式,並觀察執行結果。

#include <iostream>

using namespace std;

int main( )

{

    int a=66;

    string r="不及格";

    if (a>=60){

        r="及格";

    }

    else{

        r="不及格";

    }

    cout<<r;

 return 0;

}

以上『>=』稱為關係運算子,『if else』稱為決策運算指令。請繼續建議以下程式,並觀察執行結果。

#include <iostream>

using namespace std;

int main()

{

    int x=3,y=5;

    string r="";

    if (x>0 && y>0){

        r="1象限";

    }

    cout<<r<<endl;

    return 0;

}

以上『&&』稱為邏輯運算子,此為本單元所要介紹的內容。

 

關係運算子(Relational Operators)

關係運算子又稱為比較(Comparison) 運算子,用於資料之間的大小比較,比較的結果可得到int 型態的1(true) 0(false),下表是C/C++ 語言中的關係運算子符號。

例如:

#include <iostream>

using namespace std;

int main() {

    int x=3,y=4;

    cout<<(x>0)<<endl;  //1

    cout<<(x>=y)<<endl; //0

    cout<<(x==y)<<endl; //0

    cout<<(x!=y)<<endl; //1

    return 0;

}

邏輯運算子(Logical Operators)

當同一個運算式要同時存在兩個以上的關係運算子時,每兩個關係運算子之間必須使用邏輯運算子連結,例如,您要找男生且年齡大於40,此一選擇就同時含有兩個關係運算式,此時就要使用邏輯運算子。C/C++ 的邏輯運算子有否定not!』、邏輯and&&』、邏輯or||』,如下表所示:

!

邏輯!是取反相。例如,

         int x=3;

    cout<<!(x>0);//0

 

&&

邏輯and 是兩件事都true,結果才是true,其餘都是false,其真值表如下:

例如:

         int x=3,y=4;

    cout<<((x>0) && (y>=0));

||

邏輯or 是兩件事只要有一件為true,那就為true,只有兩件事全為false,才為false,其真值表如下:

例如:

         int x=3,y=4;

    int x=3,y=4;

    cout<<((x>0) || (y<0));  //1

自我練習

1. 若有一數學式,判斷x 是否滿足1<x<=6,請轉換為C/C++ 述。

2. 請指派1 x,判斷是否x<3 x>7,請以C/C++ 表示。

3. 輸入三角形三邊長a,b,c,圍成三角形的條件是,任兩邊之和要大於第三邊,那如何以C/C++ 語言表示?

提示 任兩邊之和大於第三邊的數學語言是a+b> c and a+c> b andb+c> a,請將以上數學語言轉為C/C++ 語言。(測資:a=1,b=2,c=7 is 0;a=3,b=4,c=5 is 1)

4. 若有一數學式,同時判斷六個變數是否滿足,請轉換為C/C++ 述。(測資:a1=1,b1=2,c1=3,a2=2,b2=4,c2=6 is 1; a1=1,b1=2,c1=3,a2=2,b2=4,c2=8 is 0)

5.同上題, 又如何表示?(測資:a1=1,b1=2,c1=3,a2=2,b2=4,c2=6 is 0; a1=1,b1=2,c1=3,a2=2,b2=4,c2=8 is 1)

 

if...else

在日常生活領域中,當出現“假如∼則∼,否則∼”時,此種決策流程模式有兩種解決問題的方案,故稱為雙向分歧決策流程,此時可使用if...else敘述。if...else敘述的語法如下:

if(運算式)

{

   敘述區塊1

}

[else

{

   敘述區塊2

}]

 

以上語法說明如下:

1.  運算式的值若為1(true),則執行敘述區塊1;運算式的值若為0(false),則執行敘述區塊2,其流程圖如下:

5-2

請鍵入以下程式,並觀察執行結果。

int main(){

    int a=66;

    char r='';

    if (a>=60)

        r='P'; 

    else

        r='F';

    cout<<r;

}

2.有時為了簡化程式的撰寫,可將否則的部分寫在if前面,並省略else。例如,以下程式同義於上面程式。

int main(){

r='F';

    if(a>=60) {

        r=P;

    }

}

3.if else 後面預設僅執行一個敘述,若要執行兩個以上敘述,請加上{},請要{}對稱排列。請鍵入以下程式,並寫出執行結果。

int main(){

    int a=33,b=0,c=0;

    if (a>=60)

        b=b+1;

        c=c+1;

    cout<<b<<endl;

    cout<<c<<endl;

    return 0;

}

int main(){

    int a=33,b=0,c=0;

    if (a>=60){

        b=b+1;

        c=c+1;

    }

    cout<<b<<endl;

    cout<<c<<endl;

    return 0;

}

4if()後面不用加分號(),請鍵入以下程式,並觀察執行結果。

int main(){

    int a=33,b=0,c=0;

    if (a>=60)

        b=b+1;       

    cout<<b<<endl;

    return 0;

}

int main(){

    int a=33,b=0,c=0;

    if (a>=60);

        b=b+1;       

    cout<<b<<endl;

    return 0;

}

 

8.  C語言為了強調語法的簡潔性,若決策流程的結果,只為求得簡單的運算式,則可用以下敘述的三元運算子(?:),

    r=(運算式1)?(運算式2):(運算式3)

其中『運算式2』與『運算式3』的括號只是增加程式的可讀性,此兩括號的有無並不影響程式的執行結果。當運算式1的值為1(true)時,z=運算式2,當運算式1的值為0(false)時,則Z=運算式3,例如,請鍵入以下程式,並寫出執行結果。

int main(){

    int a=66;

    char r;

    r=(a>=60)?('P'):('F');

    cout<<r<<endl;

    return 0;

}

7.  敘述區塊內可以放置任何合法敘述,當然也可以再放置ifif中有if,稱為巢狀if,請看以下範例。

 

範例 5a

請寫一個程式,完成以下要求:

1.  輸入一個0~100的分數。

2.  當分數大於90分時,輸出A

3.  當分數介於80~89時,輸出B

4.  當分數介於70~79時,輸出C

5.  當分數介於0~69時,輸出D

【流程分析】

1.  使用流程圖分析如下:

 

2.  以上每一個決策流程點,都有兩個分歧點,所以適用if~else

3.  每一個else後面均需進一步決策流程,所以可在每一else後面再放置if

#include <iostream>

using namespace std;

int main() {

    int a=88;

    char r;

    if(a>=90)           /* 高於90分為A */

        r='A';

    else

        if(a>=80)      /* 介於 8090分為B */

            r='B';

        else

            if(a>=70)       /* 介於 7080分為C */

                r='C';

            else

                r='D';     /* 不符合上述情況則為D */

    cout<<r<<endl;

    return 0;

}

補充說明

1、此題有人會寫成 if (90<a<100 ),但C/C++並沒有這種運算式,因為90<a<100 是數學語言,不是程式語言。

2、有人會這樣寫,這樣也可以,這樣可以減少一直縮排。

         if(a>=90)          //高於90分為A

               r='A'

        else if(a>=80)             //介於 8090分為B

            r='B';

     else if(a>=70)       // 介於 7080分為C

         r='C';

    else

         r='D';           // 不符合上述情況則為D

         cout<<r<<endl;

 

3、有人會寫成 

if (a<100 && a>=90) r='A';

         if (a<90  && a>=80)  r='B';

         if (a<80  && b>=70)  r='C';

         if (a<70  && b>=0)   r='D';

這樣雖然也可以,但是其執行效率非常差,因為不管分數為何,僅有一項會成立,但卻都要進行四次判斷,如此會讓電腦不斷進行無效的判斷。而且,電腦的判斷時間遠大於執行計算的時間。

 

自我練習

1.請寫一程式,由電腦產生-33的整數,電腦判斷是正數、0或負數。

2.某一貨品定價100元,若購買500件,(含)以上打7折,若購買499300件則打8折,若購買299100件則打9折,購買100件以下則不打折,試寫一程式可以輸入購買件數而得總價。

測試資料:

編號

輸入

 

1

20

100202000

2

200

1002000.918000

3

400

1004000.832000

4

500

1005000.735000

 

3.直線。直線標準式為ax+by+c=0,請寫一程式,可以指派一直線係數a,b,c。其次,可再輸入任一點座標,並判斷所輸入點式否在直線上。例如,指派a,b,c分別是1,2,-3,那方程式就是x+2y-3=0,其次,輸入點若是(1,1),是在直線上,若是(1,2),則不在直線上。

4.請寫一程式,可以由電腦產生一個小寫字元,請判斷其是否為母音。說明,字元a,e,i,o,u稱為母音,其餘為子音。

5.請寫一個程式,可以產生一個025的亂數,且依以下分數顯示燈號

    2125:五個燈。

    1620:四個燈。

    1115:三個燈。

    610:兩個燈。

    15:一個燈。

    0:零個燈。

 

範例 5b 請寫一個程式,可以判斷所輸入座標的所在象限。

【程式列印】

#include <iostream>

using namespace std;

int main() {

    int x=3,y=4;

         char r;

        if(x>0)

             if(y>0)

                     r='1';       // 第一象限

               else

                     r='4';      //第四象限

        else

               if(y>0)

                     r='2';      // 第二象限

               else

                     r='3';     //第三象限

    cout<<r;

    return 0;

}

補充說明   

1、此題目有人會寫成

    if (x>0 && y>0) r='1';

    if (x<0 && y>0) r='2';

    if (x<0 && y<0) r='3';

    if (x>0 && y<0 ) r='4';

這樣雖然沒有錯,但是執行效率非常差,因為電腦要不斷的比較。

 

自我練習

1、同上範例,但增加先判斷是否在原點或xy軸上。

2、同上題,但程式一執行,要求先輸入密碼,密碼若為數字1234,那才可執行本程式。

 

範例5c打字練習。

請由電腦產生一個小寫字元,讓使用者輸入,電腦並判斷是否正確。

程式列印

#include <iostream>

#include <time.h> // 使用time()

#include <stdlib.h> // 使用rand()

using namespace std;

int main()

{

    srand(time(NULL));

    int a=97+rand()%26;

    //cout<<a<<endl;

    cout<<(char)a;

    char b;

    cin>>b;

    if ((int)b==a)

        cout<<"right"  

    else

        cout<<"wrong";

    return 0;

}

自我練習

1、心算練習。請由電腦產生兩個1位數,讓使用者練習加法,電腦並評判是否正確。

 

switch...case

一個決策流程點若同時擁有三個或三個以上的解決方案,則稱此為多向分歧決策流程。多向分歧決策流程雖也可使用5-1的巢狀if else解決,但卻增加程式的複雜度及降低程式可讀性,若此一決策流程點能找到適當的運算式,能使問題同時找到分歧點,則可使用switch case敘述。switch case語法如下:

switch(運算式)

  {

    case常數1

        敘述區塊1

        break;

    case常數2

        敘述區塊2

        break;

    case常數3

       敘述區塊3

        break;

 

    default:

        敘述區塊n]

  }

 

以上語法說明如下:

1.  switch的運算式值僅能為『整數』或『字元』。

2.  case的常數僅能『整數』或『字元』,且其型態應與上面的switch運算式相同。

3.  電腦將會依switch的運算式值,逐一至常數1、常數2尋找合乎條件的case,並執行相對應的敘述區塊,直到遇到break敘述,才能離開switch

4.  default可放置特殊情況,也就是沒有適當的case,則執行default。若省略default,且若沒有任何case滿足switch運算式,則程式會默默離開switch敘述。語法中,兩旁加中括號表示此敘述可省略。

5.  敘述區塊可放置任何合法的敘述,當然也可放置switchif

6.  以下敘述,可將1234轉為字元'A' 'B' 'C' 'D'

#include <iostream>

using namespace std;

int main() {

    int a=1;

        char r;

        switch(a) {

              case 1:

                        r='A';

                    break;

              case 2:

                    r='B';

                        break;

              case 3:

                    r='C';

                        break;

              case 4:

                        r='D';

                        break;

                default :

                        r='  ';

        }

    cout<<r;

    return 0;

}

7.  有些語言可用逗號將兩種case放在一起,但在C/C++語言中每一case僅能放置一個常數,所以若兩個或兩個以上case,有相同的處理方法,則應將兩個case分成兩個敘述,且共用1break,如以下程式。

         case 10:

     case 9:

            r='A';

            break;

請看以下範例。

 

範例5d

試以switch case重作範例5-1a

 

【程式列印】

2.  使用return可提早離開main()函式。

#include <iostream>

#include<cmath>

using namespace std;

int main()

{

    int a;

         char r;

        cout<<"input a grade: ";

        cin>>a;

         if(a>100 || a<0) {  // 如果輸入的成績大於100或小於0,則 提早離開

               return 0;

         }

        switch(a/10) {

               case 10:

               case 9:

                     r='A';

                     break;

               case 8:

                     r='B';

                     break;

               case 7:

                     r='C';

                     break;

               case 6:

               case 5:

               case 4:

               case 3:

               case 2:

               case 1:

               case 0:

                     r='D';

                     break;

         }

         cout<<"the grade is:"<<r;

    return 0;

}

自我練習

1請寫一程式,將所輸入的012…6,轉為'S''M''T''W''T''F''S'等字元。

2.請寫一個程式,可以產生一個025的亂數,且依以下分數顯示燈號

    2125:五個燈。

    1620:四個燈。

    1115:三個燈。

    610:兩個燈。

    15:一個燈。

    0:零個燈。

 

範例 5e 電子琴。前面我們已經介紹電腦如何使用_beep()函式發DoReMe等音,本例則要依此製作一個電子琴。

解題步驟

1.  使用cin輸入字元都還要輸入Enter,這樣不像電子琴。所以線上查尋,發現getche()(放在conio.h)可輸入字元,但不用輸入Enter,所以本例使用此函式輸入字元。

#include <iostream>

#include <conio.h>//本例使用getche

int main()

{

    char a;

    while(1){//無限迴圈,請看下一章

        a= getche();//輸入後,不用按Enter

        switch(a) {

            case('1'):

                _beep(523,500);//Do

                break;

            case ('2'):

                _beep(587,500);//Le

                break;

            case ('3'):

                _beep(659,500);//Mi

                break;

            case ('4'):

                _beep(698,500);//Fa

                break;

            case ('5'):

                _beep(784,500);

                break;

            case ('6'):

                _beep(880,500);

                break;

            case ('7'):

                _beep(988,500);

                break;

            case ('8'):

                _beep(1046,500);

                break;

        }

    }

    return 0;

}

 

範例5f 猜拳遊戲。請寫一個程式,可以由人和電腦猜拳。

解題步驟

1、這一任務就是寫人工智慧程式的入門了,寫程式前先想一下您和一個3歲小孩或沒玩過猜拳的人猜拳,那您們如何開始此遊戲呢?首先,我們先規定有三種拳,分別是『剪刀、石頭與布』,且『剪刀贏布,石頭贏剪刀、布贏石頭,兩者相同則平手等』。『人工智慧』就是您聰明,它傻瓜,要把這些規定以程式語言表示,並由以上規定來執行遊戲與評判勝負。

2、資料的數位化。我們人類猜拳是直接用手勢表示『剪刀、石頭與布』,但是如何讓電腦瞭解您的拳法呢,裝一個攝影機當然可以,但是也還要影像處理,這不是我們這一單元任務,我們電腦只有鍵盤,所以可以先將以上『剪刀、石頭與布』以『1,2,3』表示,此即為資料的數位化。因為用『1,2,3』,表示只要1byte就可以,若您用『剪刀、石頭與布』表示,當然也可以,但一個中文字就佔用3byte,且往後的處理也是比較複雜。

3、本例因為電腦有三種拳法,可以用一個switch,人也有三種拳法,所以每一個switch裡面還有一個switch,所以共有9種情況,您要讓電腦也能思考,其實就是將以上所有可能發生的情況,以程式語言先規定好,如以下程式。

 

範例5g 求極大值。假如有資料如下:

 3,2,5

如何求極大值。

參考解答

1、資料數位化。本例以單一變數儲存如下:

int a=3,b=2,c=5;

2、求極大值的演算法如下:

(1)    指派第1個為極大值。

int max=a

(2)從第2個資料起,都要和極大值比較,若大於極大值,則取代極大值。

if (b> max)

         max=b;

3、輸出極大值。

4、根據以上演算法,程式撰寫如下:

#include <iostream>

using namespace std;

int main()

{

    int a=3,b=2,c=5;

    int max=a;

    if (b>max)

        max=b;

    if (c>max)

        max=c;

    cout<<max;

    return 0;

}

自我練習

1、若有4筆資料如下:

33,22,77,66

請寫一個程式,可以求其極小值。

2、有一批資料,含有3個人的人名與成績,請寫一程式,可以找出最低分的人名與成績。例如,

        aa,60

        bb,30

        cc,80

3、請寫一程式,可以輸入5個數值,請去掉最大值與最小值,再求其平均。

 

一元二次方程式 

前面我們直接假設所輸入的一元二次方程式有解,因為不是隨便給三個係數,一個方程式就通通有解,本例則要加上判斷了,解一元二次方程式的演算法如下:

1、設有一元二次方程式如下:

ax2 + bx + c = 0

2、若a=0則輸出“輸入錯誤”。

3、令d=b24ac

4、若d=0,則方程式有唯一解;否則,若d>0,則方程式有二解;否則,無實數解。

5、例如:2x2-7x+3=0。其解是x1=3.0,y1=0.5

以上演算分析,以流程圖說明如下:

 

範例 5h

請設計一個程式,可以解一元二次方程式ax2 + bx + c = 0

#include <iostream>

#include<cmath>

using namespace std;

 

int main()

{

    int a=2,b=-7,c=3;

        double d,x1,x2;

        if(a==0)   {

              cout<<"input error";            // a=0,則列印錯誤訊息 

              return 0;

       }

       d=pow(b,2)-4*a*c;     // 計算d

       if(d==0)

            cout<<"only one answer,x1,x2="<< (-b/(2*a));

     else if(d>0){

        x1=(-b+sqrt(d))/(2*a);

        x2=(-b-sqrt(d))/(2*a);

        cout <<"two answer x1="<<x1;

        cout <<" ,x2= "<<x2<<endl;

    }

    else

        cout<<"no real answer:";

    return 0;

}

自我練習

1.解二元一次方程式。解二元一次方程式的演算法如下:

(1)    設二元一次方程式如下:

(2)      (表示d = a1b2 - a2b1

(3)    假如,則方程式無限多解,且程式結束。(代表兩重疊直線)

(4)    假如,則方程式無解,且程式結束。(代表兩平行直線)

(5)   

(6)   

(7)例如:

         3x+y=5

         x-2y=-3

的解為x=1,y=2

請設計一個程式,可以解二元一次方程式。

2、三角形判斷(APCS105第二梯次試題)

若已知三角形三邊長,判斷是否構成三角形、評定三角形種類與計算三角形面積的演算法如下:

(1)    輸入三角形的三邊長abc

2)任兩邊之和要大於第三邊,才能構成三角形,否則程式結束。

3c是最長邊,假如a2 + b2 > c2則為銳角三角形;否則,假如a2 + b2 = c2,則為直角三角形;否則此三角形為鈍角三角形。

4)令

5)三角形面積

請輸入三角形三邊長,首先判斷是否構成三角形、其次判別三角形的種類,最後計算其面積。

範例一輸入

3 4 5

範例一正確輸出

3 4 5

Right

說明

a×a + b×b = c×c

成立時為直角三角形

範例二輸入

101 100 99

範例二正確輸出

99 100 101

Acute

說明

邊長排序由小到大輸出

a×a + b×b > c×c

成立時為銳角三角形

範例三輸入

10 100 10

範例三正確輸出

10 10 100

No

說明

由於無法構成三角形

因此第二行須印出

No」。

 

6單元 迴圈運算

我們小時候常常被老師罰寫某個句子十遍,這件事若讓電腦做,那可就輕鬆了,因為電腦有for迴圈運算。例如,以下敘述可將『洪國勝』重複寫10次。

        for (int i=1;i<=10;i++)

        cout<<"洪國勝"<<endl;

for指令的語法如下:

       for([計數變數=起始值] [迴圈運算式][計數變數的改變量])     {

                        [指令區塊1]

                        [break]

                        [continue]

                        [goto (標籤名稱)]

                [指令區塊2]

                }

以上語法說明如下:

1.    只要“迴圈運算式”結果為1(),則繼續執行迴圈內的指令區塊。

2.    計數變數的改變量可為遞增,請留意終值較大。請鍵入以下程式,並寫出執行結果。

int main(){

    for (int i=1;i<=5;i++)

        cout<<i<<" ";

    cout<<endl;

    for (int i=2;i<=6;i+=2)

        cout<<i<<" ";

    cout<<endl;

}

3.    計數變數的改變量可遞減,請留意終值較小。請鍵入以下程式,並寫出執行結果。

int main(){

    for (int i=5;i>=1;i--)

        cout<<i<<" ";

    cout<<endl;

    for (int i=9;i>=1;i-=3)

        cout<<i<<" ";

    cout<<endl;

    return 0;

}

2.只要迴圈運算式為0(false),就離開迴圈。請鍵入以下程式,並寫出執行結果。

int main(){

    for (int i=1;i>=5;i++)

        cout<<i<<" ";

    cout<<endl;

    for (int i=5;i<=1;i++)

        cout<<i<<" ";

    cout<<endl;

    return 0;

}

4.         關係運算子通常使用『<,<=,>,>=』,若使用『==,!=』,也沒有錯誤訊息,但執行結果不同。

int main(){

    for (int i=1;i==5;i++)

        cout<<i<<" ";

    cout<<endl;

    return 0;

}

int main(){

    for (int i=1;i!=5;i++)

        cout<<i<<" ";

    cout<<endl;

    return 0;

}

 

5.    for 運算僅預設執行1個敘述,若要執行兩個以上敘述,請加上{}

int main(){

    int s=0;

    for (int i=1;i<=5;i++)

        cout<<i<<endl;

        s=s+i;

    cout<<s<<endl;

    return 0;

}

int main(){

    int s=0;

    for (int i=1;i<=5;i++){

        cout<<i<<endl;

        s=s+i;

    }

    cout<<s<<endl;

    return 0;

}

6.         以上變數i的有效範圍僅在迴圈內,所以以下程式的i無效。

int main(){

    int s=0;

    for (int i=1;i<=5;i++)

        cout<<i<<endl;

        s=s+i;

    cout<<s<<endl;

    return 0;

}

 

int main(){

    int s=0;

    for (int i=1;i<=5;i++){

        cout<<i<<endl;

        s=s+i;

    }

    cout<<i<<endl;

    cout<<s<<endl;

    return 0;

}

7.    以下程式都可以,但是變數i的有效範圍不同。

int main(){

    int i=0;

    for (int i=1;i<=5;i++){

        cout<<i<<endl;

    }

         cout<<i<<endl;

    return 0;

}

int main(){

    int i=0;

    for (i=1;i<=5;i++){

        cout<<i<<endl;

    }

         cout<<i<<endl;

    return 0;

}

8.         計數變量也可在迴圈內改變。例如:

int main(){

    for (int i=1;i<=10 ;i++){

        cout<<i<<endl;

        i++;

    }

    return 0;

}

9.    程式若執行到break,則會提早離開for迴圈。

int main(){

    int i, sum=0;

        for(i=1; i<=6; i++) {

        cout<<i<<endl;

               if(i==4)

                        break;  //強制離開迴圈

                cout<<i<<endl;

        }

        cout <<"when out of loop, i="<<i;

    return 0;

}

10.      程式若執行到continue,則會略過continue下面的指令區塊2,繼續執行下一個計數變量。

int main(){

    int i, sum=0;

        for(i=1; i<=6; i++) {

        cout<<i<<endl;

               if(i==4)

                        continue;  //強制離開迴圈

                cout<<i<<endl;

        }

        cout <<"when out of loop, i="<<i;

    return 0;

}      

9程式若執行到goto,則會略過goto下面的指令區塊2,跳躍至 (標籤名稱) 所在的位置,繼續執行標籤以下的指令區塊。

int main(){

    int i, sum=0;

        for(i=1; i<=6; i++) {

        cout<<i<<endl;

               if(i==4)

                        goto aa;  //強制離開迴圈

                cout<<i<<endl;

        }

        aa:

        cout <<"when out of loop, i="<<i;

    return 0;

}

8.  指令區塊內可以放置任何合法的指令,當然也可含forfor內有for,稱為巢狀迴圈。例如,以下指令可印出110 次,請看6_2

int main(){

    for (int i=1;i<=5;i++){

                   for (int j=1;j<=10;j++)

                            cout<<j;

        cout<<endl;

         }

    return 0;

}

11.  運算式只要合理就好,不一定要用計數變數。例如:

int main(){

    int i=0,s=0;

    for (i=1;s<=10;i++){

        cout<<i<<endl;

        s=s+i;

    }

         cout<<i<<endl;

         cout<<s<<endl;

    return 0;

}

int main(){

    int i=0,s=0;

    for (i=1;i<=10 && s<=10;i++){

        cout<<i<<endl;

        s=s+i;

    }

         cout<<i<<endl;

         cout<<s<<endl;

    return 0;

}

 

範例6a 請寫一個程式,電腦可以連續出現6個字元,由使用者輸入,並判斷是否正確,統計正確與錯誤題數。

程式列印

#include <iostream>

#include <time.h> // 使用time()

#include <stdlib.h> // 使用rand()

using namespace std;

int main()

{

         srand(time(NULL));

         int r=0,w=0;

         for (int i=1;i<=10;i++){

        int a=97+rand()%26;

 

        cout<<(char)a;

        char b;

        cin>>b;

        if ((int)b==a){

            cout<<"right"<<endl;

            r++;

        }

        else{

            cout<<"wrong"<<endl;

            w++;

        }

         }

    cout<<"right="<<r<<endl;

    cout<<"wrong="<<w<<endl;

         return 0;

}

自我練習

1、請產生6-3~3的亂數,統計正數、0、負數的個數。

2、請產生101~6的亂數,統計偶數與奇數個數。

3、請產生101~6的亂數,統計所有數字出現的次數。

4、請產生101~6的亂數,統計哪一個數字出現的次數最多。

5、請連續產生8題兩個1位數,由使用者輸入相加結果,電腦回應對或錯,並統計正確與錯誤的題數。

6、請由電腦自動產生30個大於等於0且小於等於100的亂數x,統計0~59,60~69,70~79,80~89,90~100的個數。

7、請寫一個程式,電腦可以連續出現50個小寫字元,電腦統計出現母音的個數。

 

aa

#include <stdio.h>

int main( )

{

 int Sum=0, Array[] ={1, 2, 3}, i;

 printf("%d",Array[7]);

 for(i=1; i<4; i++)

 Sum+=Array[i];

 printf( "%d", Sum);

 return 0;

}