程式設計 博碩文化出版發行.

Slides:



Advertisements
Similar presentations
第一單元 建立java 程式.
Advertisements

Introduction to C Programming
陳維魁 博士 儒林圖書公司 第九章 資料抽象化 陳維魁 博士 儒林圖書公司.
TQC+ JAVA全國教師研習會 PLWeb 程式設計練習平台 簡介.
Chapter 5 遞迴 資料結構導論 - C語言實作.
Chapter 5 迴圈.
函數 Function ●什麼是函數?函數就是一段獨立程式,用來處理獨立的工作。
程式設計概論 1.1 程式設計概論 程式語言的演進 物件導向程式 程式開發流程 1.2 C++開發工具
第十一章 結構.
Visual C++ introduction
簡易C++除錯技巧 長庚大學機械系
程式設計(二) 參考書目: 1. 洪維恩,C++ 教學手冊 第三版,旗標出版圖書公司。 2
JDK 安裝教學 (for Win7) Soochow University
列舉(enum).
101北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
類別(class) 類別class與物件object.
SQL Stored Procedure SQL 預存程序.
Chapter 7 指標.
第6章 函數與巨集 6-1 由上而下的設計方法 6-2 建立函數 6-3 函數的參數呼叫方式 6-4 變數的有效範圍 6-5 遞迴函數
安裝JDK 安裝Eclipse Eclipse 中文化
Methods 靜宜大學資工系 蔡奇偉副教授 ©2011.
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A.
Java 程式設計 講師:FrankLin.
Chap3 Linked List 鏈結串列.
Introduction to the C Programming Language
|12 結構與列舉型態.
程式設計實習課(四) ----C 函數運用----
第一單元 建立java 程式.
Ch20. 計算器 (Mac 版本).
INDEX 資訊學科種子教師研習 課程說明 教學活動計畫.
第一章 直角坐標系 1-3 函數圖形.
第 19 章 XML記憶體執行模式.
|07 函數.
|08 前置處理器與標準函數.
輸入&輸出 函數 P20~P21.
第十章 指標.
Introduction to C Programming
CH05. 選擇敘述.
撰寫MATLAB基礎財務程式 柯婷瑱.
第7章 指標 7-1 指標的基礎 7-2 指標變數的使用 7-3 指標運算 7-4 指標與陣列 7-5 指向函數的指標.
挑戰C++程式語言 ──第8章 進一步談字元與字串
認識常數與變數 學習C++所提供的各種基本資料型態 瞭解溢位的發生 學習認識資料型態之間的轉換
如何使用Gene Ontology 網址:
Class & Object 靜宜大學資工系 蔡奇偉副教授 ©2011.
函數 博碩文化出版發行.
引用檔案.
C qsort.
流程控制:Switch-Case 94學年度第一學期‧資訊教育 東海大學物理系.
第14章 結構與其他資料形式.
函數應用(二)與自定函數.
陣列與結構.
北一女中 資訊選手培訓營 妳不可不了解的指標 Nan.
實習八 函式指標.
2018 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A.
Chap 6 函數 故用兵之法,十則圍之,五則攻之,倍則分之, 敵則能戰之,少則能逃之,不若則能避之。 故小敵之堅,大敵之擒也。
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
作業系統實習課(二) -Scheduler-Related System Calls-
Programming & Language Telling the computer what to do
Chapter 6 函數.
Introduction to the C Programming Language
第三章 Arduino互動程式設計入門 Arduino程式基礎 認識變數 認識數字系統 認識常數.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
String類別 在C語言中提供兩種支援字串的方式 可以使用傳統以null結尾的字元陣列 使用string類別
Array(陣列) Anny
Chapter 4 Multi-Threads (多執行緒).
C語言程式設計 老師:謝孟諺 助教:楊斯竣.
Unix指令4-文字編輯與程式撰寫.
方法(Method) 函數.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
InputStreamReader Console Scanner
Presentation transcript:

程式設計 博碩文化出版發行

第八章 函數 課前指引 軟體開發的工作是相當龐大且複雜,當需求及功能愈來愈多,程式碼就會愈來愈龐大。此時,多人分工合作來完成軟體開發是勢在必行的。而且,如果每次修改一點點程式碼,就要將全部成千上萬行的程式碼重新編譯,這樣的作法顯得相當沒有效率。再者,如果程式中有許多類似的部分,一旦日後要更新,必定會增添其難度。在 C 語言中提供自訂函數的功能,可以讓程式更加具有結構化、模組化的特性。

章節大綱 8-1 認識函數 8-5 遞迴 8-2 函數的應用 8-6 變數的生命週期 8-3 函數中參數傳遞的方式 8-7 前置處理器 8-4 陣列、指標與函數的應用 備註:可依進度點選小節

8-1 認識函數 函數(function)本身其實就像是一部機器,或者說像是一個黑盒子。在國中所學的數學便曾提及函數,數學上函數的形式如下: 其中 x 代表輸入的參數,f(x) 表示是 x 的函數,而 y 則是針對一個特定值 x 所得到的結果與回傳參數。 y = f(x)

8-1 認識函數 模組化精神 是採用結構化分析方式,把程式由上而下逐一分析,並將主體的大問題逐步分解成各個較小的問題,並將這些小問題分別交由不同程式設計師來進行程式碼撰寫。 模組化與結構化的概念,並不是只有在程式設計中才有。舉凡與機關組織與製造工業等等,這種概念已經行之有年了。依據功能來將機關組織區分部門,管理起來比較方便且有頭緒。

8-1 認識函數 使用函數的優點 函數的概念也沿用到程式設計中。事實上,將一個大型程式依據功能來切割,在某一功能有問題的時候,可以針對該部份加以修繕或更換即可。而且,這項作法可以讓大家分工合作開發程式,再統一編譯。日後,如果程式有新版本,若要更新也更加地方便。所以說,使用函數的好處相當多,只要對程式善加規劃,就能讓程式更精簡、更容易維護,也能讓未來改版的工作更加順利。 函數的好處有: 1.避免造成相同程式碼重複出現。 2.讓程式更加清楚明瞭,降低維護時間與成本。 3.將較大的程式分割成多個不同的函數,可以獨立開發、編譯,最後可連結在一起。

8-2 函數的應用 C的函數可區分為系統本身提供的標準函數及使用者自行定義的自訂函數。使用標準函數只要將所使用的相關函數表頭檔含括(include)進來即可。而自訂函數則是使用者依照需求來設計的函數,這也是本章說明的重點所在。

8-2 函數的應用 函數的原型宣告 只要透過函數宣告,說明這個函數的名稱、傳入參數與回傳參數,讓編譯器知道有這個函數,且有完整定義,就可以供整個程式,甚至整個軟體專案使用。基本語法格式如下: 回傳值型態 函數名稱 (引數型態1 引數1, 引數型態2, …, 引數型態n 引數n );

8-2 函數的應用 函數的原型宣告 使用者可以自行定義引數個數與引數資料型態,並指定回傳值型態。如果沒有回傳值,通常會使用以下形式: 而如果沒有任何需要傳遞的引數呢?同樣也是以關鍵字 void 來表示。因此,有回傳值但沒有引數的形式: void 函數名稱 (引數型態1 引數1,引數型態2, …,引數型態n 引數n ); 回傳值型態 函數名稱 (void);

8-2 函數的應用 函數的原型宣告 一般原型宣告的位置是將函數原型宣告放置於程式開頭,通常是位於#include 與 main()之間。函數原型宣告的語法格式如下: 傳回資料型態 函數名稱(資料型態 參數1, 資料型態 參數2, ……….); 或 傳回資料型態 函數名稱(資料型態, 資料型態, ……….);

8-2 函數的應用 函數定義 如果空有函數的宣告,卻沒有函數的定義,這個函數就像一部空有一個外殼而沒有實際的功能的機器一樣,根本無法使用。自訂函數在C中的定義方式與main()函數類似,基本架構如下: 回傳值型態 函數名稱 (引數型態1 引數1, 引數型態2, …, 引數型態n 引數n ) { 函數主體; ... return傳回值; }

8-2 函數的應用 函數定義 讓函數將結果傳回時必須要指定一個資料型態給傳回值,而在接收函數傳回值的這方除非是直接將接收到的傳回值顯示出來,否則存放傳回值的變數其型態必須與函數定義的傳回值型態一樣。傳回值的使用格式如下: return傳回值;

8-2 函數的應用 函數定義 函數名稱是準備定義函數的第一步,是由設計者自行來命名,命名規則與變數命名規則相符,最好能具備可讀性。避免使用不具任何意義的字眼作為函數的名稱,例如bbb、aaa等。 不過在函數名稱後面括號內的參數列,可不能像原型宣告時,只寫上各參數的資料型態即可,必須同時填上每一個資料型態與參數名稱。

8-2 函數的應用 函數呼叫 函數回傳值一方面可以代表函數的執行結果,另一方面可以用來檢測函數是否有成功地執行完成。函數呼叫的方式有兩種,假如沒有傳回值,通常直接使用函數名稱即可呼叫函數。語法格式如下: 如果函數有傳回值,則可運用指定運算子"="將傳回值指定給變數。如下所示: 函數名稱(引數1, 引數2, ……….); 變數=函數名稱(引數1, 引數2, ……….);

8-2 函數的應用 範例CH08_01.c

8-2 函數的應用 範例CH08_01.c 執行結果

8-2 函數的應用 程式解說 第4行在 main 函數前的 void mymax(int,int)就是函數的原型宣告。 第13行在 main 函數中為了要使用 mymax 函數,必須要呼叫mymax(a,b)函數,並以 a 與 b 當作參數傳遞給 mymax 函數。 第18~24行是函數定義主體,其中第21~23行是利用 > 符號判定究竟是 x 較大或是 y 較大,並輸出較大值。

8-2 函數的應用 範例CH08_02.c

8-2 函數的應用 執行結果 程式解說 第4~10行將此函數定義移到main()函數之前,可以省略函數原型宣告,此函數使用void宣告型態。 第19行執行函數呼叫。

8-2 函數的應用 範例CH08_03.c

8-2 函數的應用 範例CH08_03.c

8-2 函數的應用 執行結果 程式解說 第4行函數原型宣告。 第10、12行分別輸入底數及指數。 第21~24行使用do while迴圈來計算次方值。 第26行在呼叫 mypower 後,這個自訂函數會將結果以 return 的方式傳回。

8-2 函數的應用 範例CH08_04.c

8-2 函數的應用 範例CH08_04.c

8-2 函數的應用 執行結果 程式解說 第4行建立Common_Divisor()的函數原型宣告。 第10行輸出最大公因數值。 第26~31行利用輾轉相除法計算最大公因數。 第27行求Num1與Num2的餘數值。

8-3 函數中參數傳遞的方式 在C語言中提供許多函數,也允許使用者自行定義函數。自訂函數當然有許多好處,包括程式的可讀性,與可維護性等等都能提高。因此,使用函數絕對是有必要的。不過,許多 C 語言的初學者對於使用函數上仍常有疑義。這是因為對於 C 語言提供的參數傳遞方式較不明瞭。事實上,傳遞參數的概念並不困難,關鍵僅是在於要不要改變參數本身的內容。

8-3 函數中參數傳遞的方式 參數的意義 一般來說,在C中,函數呼叫時參數的傳遞上,可以分為「傳值呼叫」(call by value)與「傳址呼叫」(call by address)。至於呼叫函數時所傳入的引數本身是否會被更動呢?該如何指定是否要更動呢?這些問題的解決方案,一樣是位址與指標。如果希望傳入的引數不被更動,只要將該變數的數值傳給函數即可。另一方面,如果希望欲傳入的引數能被更動,只要將該變數的位址傳給函數即可。這就是函數有所謂的傳值呼叫 (call by value)、傳址呼叫 (call by address) 的功能。

8-3 函數中參數傳遞的方式 傳值呼叫 C預設的參數傳遞方式為傳值呼叫(call by value),傳值呼叫的函數原型宣告如下所示: 傳值呼叫的函數呼叫型式如下所示: 回傳資料型態 函數名稱(資料型態 參數1, 資料型態 參數2, ……….); 或 回傳資料型態 函數名稱(資料型態, 資料型態, ……….); 函數名稱(引數1,引數2, ……….);

8-3 函數中參數傳遞的方式 範例CH08_05.c

8-3 函數中參數傳遞的方式 範例CH08_05.c

8-3 函數中參數傳遞的方式 執行結果 程式解說 第4行傳值呼叫函數的原型宣告。 第9~10行設定a、b的初值。 第12行函數呼叫指令。 第19行未傳回值的函數。 第23~25行x與y數值的交換過程。

8-3 函數中參數傳遞的方式 範例CH08_06.c

8-3 函數中參數傳遞的方式 執行結果 程式解說 第4~5行宣告a與b為全域變數。 第10行在此再次宣告a為區域變數。 第11行整數b為全域變數,且在 main() 函數中並沒有同樣名稱的變數,故顯示 b 變數為 50。 第10、20行在 main() 函數與 fun1() 函數中皆有自訂 a 變數之值,故只能顯示區域變數之值。

8-3 函數中參數傳遞的方式 傳址呼叫 傳址方式的函數宣告型式如下所示: 傳址呼叫的函數呼叫型式如下所示: 回傳資料型態 函數名稱(資料型態 *參數1, 資料型態 *參數2, ……….); 或 回傳資料型態 函數名稱(資料型態 *, 資料型態 *, ……….); 函數名稱(&引數1,&引數2, ……….);

8-3 函數中參數傳遞的方式 範例CH08_07.c

8-3 函數中參數傳遞的方式 範例CH08_07.c

8-3 函數中參數傳遞的方式 執行結果 程式解說 第5行函數傳址呼叫,指定傳入的引數必須是兩個整數的位址,並以兩個整數指標 *x 與 *y 來接受參數。 第13行必須加上&運算子來呼叫引數。 第24~26行若要交換資料則必須使用「*」運算子,因為 x 與 y 是整數指標,必須透過「*」運算子來存取其內容。

8-3 函數中參數傳遞的方式 範例CH08_08.c

8-3 函數中參數傳遞的方式 範例CH08_08.c

8-3 函數中參數傳遞的方式 執行結果 程式解說 第4行傳址呼叫原型宣告。 第9行輸入多少英尺及英吋的數值。 第12行傳址呼叫函數transfer()。 第19~27行未傳回值的函數定義。 第23行轉換為公制的計算公式。 第24行強制轉換為整數。

8-3 函數中參數傳遞的方式 範例CH08_09.c

8-3 函數中參數傳遞的方式 執行結果 程式解說 第4行宣告未傳回值的傳值與傳址混合函數。 第6、7 行重新設定x與y的值。 第14行同時具有傳值與傳址混合性函數呼叫。

8-4 陣列、指標與函數的應用 函數與陣列參數的傳遞 一維陣列參數傳遞的函數宣告: 一維陣列參數傳遞的函數呼叫如下所示: (回傳資料型態or void) 函數名稱 (資料型態 陣列名稱[ ] ,資料型態 陣列大小…); 或 (回傳資料型態 or void) 函數名稱(資料型態 *陣列名稱 ,資料型態 陣列大小...); 函數名稱 (資料型態 陣列名稱,資料型態 陣列大小…);

8-4 陣列、指標與函數的應用 範例CH08_10.c

8-4 陣列、指標與函數的應用 範例CH08_10.c

8-3 函數中參數傳遞的方式 執行結果 程式解說 第 3行宣告n為常數。 第5行中是函數的原型宣告,以arr[ ]參數及傳址呼叫傳遞,其中在大括號[ ]中的數字可寫也可不寫。 第15行直接用陣列名稱,也就是傳遞陣列位址來呼叫函數Multiple()。

8-4 陣列、指標與函數的應用 範例CH08_11.c

8-4 陣列、指標與函數的應用 範例CH08_11.c

8-4 陣列、指標與函數的應用 執行結果

8-4 陣列、指標與函數的應用 程式解說 第3行因為要使用開根號的函數 sqrt(),則必須額外引入標頭檔 math.h。 第5行宣告了一個函數原型void adjust_grades(float *g1, float *g2, int num),其中包括了傳址與傳值參數。 第16、18行依照所輸入的學生人數,動態配置兩個一維陣列,分別有num 個元素。 第41~47行在該函數中是使用 g1 與 g2 兩個指標變數來對應兩個陣列,可以直接使用 g2[i]=10*sqrt(g1[i]) 的敘述將 g1[i] 的內容先開根號後乘上 10 並指定給 g2[i] 陣列。

8-4 陣列、指標與函數的應用 範例CH08_12.c

8-4 陣列、指標與函數的應用 範例CH08_12.c

8-4 陣列、指標與函數的應用 執行結果 程式解說 第5行第一維省略可以不用定義,其它維數的註標都必須清楚定義長度。 第10行宣告並初始化二維成績陣列。 第11行傳址呼叫並傳遞二維陣列。 第24行輸出二維陣列各元素的函數。

8-4 陣列、指標與函數的應用 命令列引數 argc和argv[]這兩個參數,只是常用的引數宣告名稱,各位可以自由命名,不過目前大多數的程式設計者都以argc和argv[]作為命令列引數慣用的名稱。相關說明如下: argc argc的資料型態為整數,表示命令列引數的個數,argc的值大於等於1,因為至少包括了程式本身名稱。 argv argv[]的資料型態為不定長度的字串指標陣列,所傳遞的資料皆為字串格式,且此字串陣列個數是視使用者輸入的引數數目而定。其中命令列引數字串是以空白或定位(tab)字元作為區隔。

8-4 陣列、指標與函數的應用 範例CH08_13.c

8-4 陣列、指標與函數的應用 執行結果 程式解說 第4行是命令列引數的傳遞宣告,宣告後各位即可在執行時傳遞參數。 第7~8行未指定其它參數,只有程式名稱的輸出結果。 第12~16行是列印出存放在argv[ ]陣列中的參數,由於argv[0]是儲存程式名稱的字串,所以i從0開始執行。

8-4 陣列、指標與函數的應用 指標的回傳值 指標回傳函數宣告語法如下: 回傳資料型態 *函數名稱(資料型態 參數1, 資料型態 參數2, ……….) { …. return 指標變數; }

8-4 陣列、指標與函數的應用 範例CH08_14.c

8-4 陣列、指標與函數的應用 範例CH08_14.c

8-4 陣列、指標與函數的應用 執行結果 程式解說 第3行宣告傳回指標值的函數原型。 第8行呼叫add_value ()函數,並傳值給ptr指標變數。 第10行輸出ptr指標變數的內容。 第18行函數宣告為傳回指標變數。 第25行輸入input與input1變數的值。 第27行兩數相加。 第29行傳回值為指標變數。

8-4 陣列、指標與函數的應用 函數指標 指向函數的指標稱之。 函數指標是 C 語言中一項相當有特色的功能。假設有多個格式相類似的函數,也就是說函數的引數完全相同,回傳值也相同,那麼可以使用同一個函數指標名稱,於程式執行期間,動態來指向所要執行的函數。 函數指標的宣告格式如下: 回傳資料型態 (*函數指標名稱)(參數1資料型態, 參數2資料型態, …);

8-4 陣列、指標與函數的應用 函數指標 將函數指標指向函數位址的方式有兩種方式,如下所示: 回傳資料型態 (*函數指標名稱)(參數1資料型態, 參數2資料型態, …)=函數名稱; 或 回傳資料型態 (*函數指標名稱)(參數1資料型態, 參數2資料型態, …); 函數指標名稱=函數名稱;

8-4 陣列、指標與函數的應用 範例CH08_15.c

8-4 陣列、指標與函數的應用 執行結果 程式解說 第3行使用三角函數,必須含括math.h檔。 第5行宣告常數PI的值。 第9行傳回值為double型態的函數指標宣告。 第10行將sin函數的位址指向pF函數指標。 第11行使用pF()執行sin()函數的功能。 第13行將cos函數的位址指向pF。 第14行使用pF()執行cos()函數的功能。

8-5 遞迴 遞迴函數 函數出現自己呼叫自己的情況時稱之。 使用遞迴函數必須充分了解其終止條件,以避免程式無窮盡地一直進行下去。

8-5 遞迴 範例CH08_16.c

8-5 遞迴 範例CH08_16.c

8-5 遞迴 執行結果

8-5 遞迴 程式解說 第4行宣告遞迴函數的原型宣告。 第5行宣告迴圈函數的原型宣告。 第11行請輸入要計算的階乘數。 第21~24行利用do while迴來控制與計算。 第26行回傳結果值。 第29~35行遞迴函數的程式碼。 第32行跳出反覆執行過程中的缺口。 第34行如果使用者輸入的數值大於 1,則繼續計算這個 n 值乘上 (n-1)! 的結果,ndegree_rec(n-1) 的部分會以 n-1 的值當成引數繼續呼叫 ndegree() 函數。

8-5 遞迴 範例 CH08_17.c

8-5 遞迴 範例 CH08_17.c

8-5 遞迴 執行結果 程式解說 第4行宣告迴圈函數的原型宣告。 第5行宣告遞迴函數的原型宣告。 第23行如果n=0,則傳回m值。 第25行求兩者餘數值再遞迴運算。 第32行求兩者餘數值。

8-6 變數的生命週期 變數依照在C程式中所定義的位置與格式,可以決定其在記憶體中所佔空間大小與程式中可以存取到該變數的程式區塊。 8-6 變數的生命週期 變數依照在C程式中所定義的位置與格式,可以決定其在記憶體中所佔空間大小與程式中可以存取到該變數的程式區塊。 例如針對C的變數而言,我們可以在資料型態前加上一些修飾字,使這些變數成為特殊的變數。 較常見的修飾字包含自動 (auto) 變數、暫存器 (register) 變數、靜態 (static) 變數,以及外部 (extern) 變數等等。

8-6 變數的生命週期 auto 變數 每一個變數宣告後若加上修飾字 auto,或是完全不加修飾字,其型態便是自動變數。 8-6 變數的生命週期 auto 變數 每一個變數宣告後若加上修飾字 auto,或是完全不加修飾字,其型態便是自動變數。 在函數中宣告變數時,變數便因此而開始其生命週期。而變數的值會隨著函數結束而消失。在前面各章的程式中所定義的變數凡未加存儲類型說明符的都是自動變數。宣告語法如下: auto 資料型態 變數名稱;

8-6 變數的生命週期 範例CH08_18.c

8-6 變數的生命週期 執行結果 程式解說 第6行定義 auto整數變數 iVar。 第12行在程式區塊中定義整數變數 iVar。 8-6 變數的生命週期 執行結果 程式解說 第6行定義 auto整數變數 iVar。 第12行在程式區塊中定義整數變數 iVar。 第11~14行底下以大括號區隔出一段程式區塊。 第15行輸出離開程式區塊的 iVar值。

8-6 變數的生命週期 register 變數 (暫存器變數) 由於CPU的暫存器速度較快,因而可以加快變數存取的效率。宣告語法如下: 8-6 變數的生命週期 register 變數 (暫存器變數) 由於CPU的暫存器速度較快,因而可以加快變數存取的效率。宣告語法如下: 由於個人電腦上所使用的暫存器容量有限,因此有些編輯器規定只能最多只能使用2個暫存器變數,因此當各位宣告更多的register變數時,仍然會視其為一般的變數使用。 register 資料型態 變數名稱=初始值;

8-6 變數的生命週期 範例CH08_19.c

8-6 變數的生命週期 執行結果 程式解說 第8行若要使用暫存器變數,只要在變數的資料型態前加上 register 修飾字即可。 8-6 變數的生命週期 執行結果 程式解說 第8行若要使用暫存器變數,只要在變數的資料型態前加上 register 修飾字即可。 第10行呼叫fun1()函數。 第18行fun1()函數中宣告暫存器變數。

8-6 變數的生命週期 static 變數 (靜態變數) 8-6 變數的生命週期 static 變數 (靜態變數) auto變數所佔用的堆疊位置在函數結束時會被清除並釋放,而靜態變數(static)是在函數中可宣告一處固定的記憶體位址來儲存這個變數。 靜態變數的值不會隨著函數結束而消失。如果要使用靜態變數,只要在資料型態前加上 static 修飾字即可。以下是它的宣告語法: static 資料型態 變數名稱=初始值;

8-6 變數的生命週期 範例 CH08_20.c

8-6 變數的生命週期 執行結果 程式解說 第4行建立累加變數值的函數原型宣告。 第9~10行透過for迴圈執行函數呼叫5次。 8-6 變數的生命週期 執行結果 程式解說 第4行建立累加變數值的函數原型宣告。 第9~10行透過for迴圈執行函數呼叫5次。 第18行宣告並初始化自動變數。 第19行宣告並初始化靜態變數。 第23行將auto變數加 1。 第24行將static變數加 1。

8-6 變數的生命週期 範例 CH08_21.c

8-6 變數的生命週期 範例 CH08_21.c

8-6 變數的生命週期 執行結果 程式解說 第4~5行函數原型宣告。 第10~14行執行for迴圈。 8-6 變數的生命週期 執行結果 程式解說 第4~5行函數原型宣告。 第10~14行執行for迴圈。 各位讀者可以發現,雖然程式中所有的變數都是在給定數值後才顯示其內容,但靜態變數 b 之值為 50 是自始至終都不會改變的。 因此,如果需要將函數中變數的內容留存起來,不隨函數的結束而消失,可以使用靜態變數。

8-6 變數的生命週期 extern變數 (外部變數) 8-6 變數的生命週期 extern變數 (外部變數) 我們知道原本所有的變數在使用前都必須要宣告,然而,對於區分為多個檔案的專案而言,存取上則較為困難。 如舉例來說,在某個計算稅率的 counttax.c程式中,其中有個都會使用到的變數tax_rate。 如果不宣告 float tax_rate,則程式根本無法編譯過關,因為程式中有使用到,卻未見其定義。

8-6 變數的生命週期 extern變數 如果在 counttax.c 中直接加入 float tax_rate 的宣告,又會造成重複定義。因為float tax_rate 在 main.c 中已經定義過了。那麼如果要在 counttax.c 檔案中中存取 main.c 中的變數 float tax_rate 又該怎麼做呢?這時只要加上 extern 修飾字,宣告其為外部變數即可: extern float tax_rate;

8-6 變數的生命週期 extern變數 extern修飾詞的功用還可以將宣告在函數或程式區塊後方的外部變數,引用到函數內使用。不過如果函數內利用extern修飾詞宣告一個外部變數時,並不會實際配置記憶體,但在函數外部必須有一個同名的變數存在,在此才會實際配置記憶體。宣告語法如下: extern 資料型態 變數名稱;

8-6 變數的生命週期 範例CH08_22.c

8-6 變數的生命週期 範例CH08_22.c

8-6 變數的生命週期 執行結果 程式解說 第4行transfer函數原型宣告。 8-6 變數的生命週期 執行結果 程式解說 第4行transfer函數原型宣告。 第9行利用extern修飼詞,可引用宣告於函數下方的外部變數。 第25行宣告在函數外的外部變數。 第29行此函數在外部變數pound的下方,因此可直接使用。

8-7 前置處理器 是指在C式開始編譯成機器碼之前,編譯器就會開始執行的一個程序,把C原始檔案中的前置處理指令,適當置換成純粹C語言敘述的新檔案,然後編譯器再用此新檔案產生目的檔(.obj),完成編譯的作業。在C裡,前置處理指令都以#符號開頭,並可以放置在程式的任何地方,藉由這種特性,可以讓程式碼的編排更有彈性。

8-7 前置處理器 巨集指令 巨集(macro)指令,又稱為「替代指令」,是由一些以#為開頭的「前置處理指令」所組成。主要功能是以簡單的名稱取代某些特定常數、字串或函數,能夠快速完成程式需求的自訂指令。簡單來說,善用巨集可以節省不少程式開發與執行時間。其語法如下所示: #define 巨集名稱 表示式 /*不用在結尾加上分號*/

8-7 前置處理器 範例CH08_23.c

8-7 前置處理器 執行結果 程式解說 第4行以#define 指令定義巨集函數MAX(a, b)。 第10行取得變數 x 的值。 第12行取得變數y的值。

8-7 前置處理器 範例CH08_24.c

8-7 前置處理器 執行結果 程式解說 第4~7行定義各種巨集名稱型式。 第5行前置處理器會將程式中所有PI取代為3.14159。 第6行利用#define指令以SHOW取代字串"The Circle's Area="。 第14行輸入半徑值。第15行輸出巨集字串及程式指令。

8-7 前置處理器 範例CH08_25.c

8-7 前置處理器 執行結果 程式解說 第4行輸入整數的scanf巨集定義。 第5行輸入實數的scanf巨集定義。 第13、15行呼叫巨集函數。

8-7 前置處理器 範例CH08_26.c

8-7 前置處理器 執行結果 程式解說 第3、4行定義巨集指令。 第11行解除巨集,之後的程式碼就不可再出現DIVIDE字樣,否則會發生錯誤。

8-7 前置處理器 條件式編譯指令 #if…#endif指令 #if…#endif指令與條件判斷式if…endif的功能是類似的,可分為單一條件判斷式及巢狀判斷式,系統可依據條件運算式的判斷結果來進行程式碼的編譯。其格式如下所示: #if 條件運算式 程式碼內容 #endif

8-7 前置處理器 範例CH08_27.c

8-7 前置處理器 執行結果 程式解說 第4行使用#define指令定義識別字Use_MACRO。 第6~8行使用#if指令判斷是否編譯區段內的程式碼(即是否定義MAX巨集)。 第15行整數變數 x 與 y 儲存輸入值。 第16行顯示結果訊息。

8-7 前置處理器 範例CH08_28.c

8-7 前置處理器 執行結果 程式解說 6~14行中,使用巢狀的#if指令,形成多選一的#if…#elif…#endif選擇結構,藉由第4行的識別字OS_ENV,即可選擇OS的使用字串(或針對特定作業環境所須的參數)。 第13行若前面所列項目都不符合,則進行此區塊的程式敘述。

8-7 前置處理器 #include指令 #include前端處理器指令能將所指定路徑的檔案含括(include)至目前的程式檔案中,接著您就可以在目前的程式碼中使用該含括進來的檔案中所定義的函數或常數了。基本上,除了可含括C所提供的標頭檔外,也能含括自訂的標頭檔。如果要利用#include指令將檔案含括進來,可以有底下兩種語法格式: #include <檔案名稱> #include "檔案名稱"

8-7 前置處理器 範例CH08_29.c

8-7 前置處理器 執行結果 程式解說 第2行引入外部檔案CH08_29_1.h。 第6行呼叫定義在外部檔案中的sayhello()函數。

本章結束 Q&A討論時間