




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第5章 函數(shù)與程序結(jié)構(gòu),蘇小紅,C語(yǔ)言大學(xué)實(shí)用教程,內(nèi)容提要,函數(shù)定義、函數(shù)調(diào)用、函數(shù)原型、函數(shù)返回值 難點(diǎn):函數(shù)的參數(shù)傳遞與返回值 全局變量、自動(dòng)變量、靜態(tài)變量、寄存器變量 難點(diǎn):變量的作用域與存儲(chǔ)類型 程序調(diào)試 結(jié)構(gòu)設(shè)計(jì)與模塊化,程序設(shè)計(jì)的藝術(shù),程序設(shè)計(jì)有兩大最高級(jí)的藝術(shù) 算法設(shè)計(jì)藝術(shù) 程序的靈魂 Donald E. Knuth, The Art of Computer Programming, 清華大學(xué)出版社, 2002 結(jié)構(gòu)設(shè)計(jì)藝術(shù) 程序的肉體 “.the larger the project, the more essential the structuring!”Dijkstra,
2、 1968 模塊化(Parnas, 1972) 結(jié)構(gòu)化(Structural) 面向?qū)ο螅∣bject-Oriented) 面向組件(Component-Oriented) 面向智能體(Agent-Oriented) 函數(shù)(function)是結(jié)構(gòu)設(shè)計(jì)的最基本單位 “一個(gè)程序應(yīng)該是輕靈自由的,它的子過(guò)程就象串在一根線上的珍珠?!?Geoffrey James的編程之道,用函數(shù)解決問題,打印階乘表的程序 函數(shù)把較大的任務(wù)分解成若干個(gè)較小的任務(wù),并提煉出公用任務(wù) 程序員可以在其他函數(shù)的基礎(chǔ)上構(gòu)造程序,而不需要從頭做起 設(shè)計(jì)得當(dāng)?shù)暮瘮?shù)可以把具體操作細(xì)節(jié)對(duì)程序中不需要知道它們的那些部分隱藏掉,從而使整
3、個(gè)程序結(jié)構(gòu)清楚 分而治之、信息隱藏,假如不模塊化,讀多少行的程序能讓你不頭疼? main()當(dāng)中能放多少行程序? 假如printf()函數(shù)由10行代碼替換,那么你見過(guò)的程序會(huì)成什么樣子? 如果所有代碼都在main()當(dāng)中,怎么團(tuán)隊(duì)合作? 如果代碼都在一個(gè)文件中,怎么團(tuán)隊(duì)合作?,模塊化的優(yōu)點(diǎn),模塊各司其職 每個(gè)模塊只負(fù)責(zé)一件事情,它可以更專心 便于進(jìn)行單個(gè)模塊的設(shè)計(jì)、開發(fā)、調(diào)試、測(cè)試和維護(hù)等工作 一個(gè)模塊一個(gè)模塊地完成,最后再將它們集成 開發(fā)人員各司其職 按模塊分配任務(wù),職責(zé)明確 并行開發(fā),縮短開發(fā)時(shí)間 分而治之(Wirth, 1971 )信息隱藏(Parnas, 1972),函數(shù)(functi
4、on)和模塊(module),函數(shù)是C語(yǔ)言中模塊化編程的最小單位 可以把每個(gè)函數(shù)看作一個(gè)模塊 若干相關(guān)的函數(shù)可以合并作一個(gè)“模塊”,函數(shù)的分類,函數(shù)生來(lái)都是平等的,沒有高低貴賤之分,只有main()稍微特殊一點(diǎn)點(diǎn) 庫(kù)函數(shù) ANSI C定義的標(biāo)準(zhǔn)庫(kù)函數(shù) 符合標(biāo)準(zhǔn)的C語(yǔ)言編譯器必須提供這些函數(shù) 函數(shù)的行為也要符合ANSI C的定義 第三方庫(kù)函數(shù) 由其它廠商自行開發(fā)的C語(yǔ)言函數(shù)庫(kù) 不在標(biāo)準(zhǔn)范圍內(nèi),能擴(kuò)充C語(yǔ)言的功能 自定義函數(shù) 自己編寫的函數(shù) 包裝后,也可成為函數(shù)庫(kù),供別人使用,函數(shù)定義(definition),返回值類型 函數(shù)名 (參數(shù)表)函數(shù)體return 表達(dá)式; 返回值類型與return語(yǔ)句
5、配合 如果不需要返回值,則應(yīng)該用void定義返回值類型,同時(shí)return語(yǔ)句之后不再需要任何表達(dá)式 當(dāng)函數(shù)執(zhí)行到return語(yǔ)句時(shí),就中止函數(shù)的執(zhí)行,返回到調(diào)用它的地方 函數(shù)內(nèi)部可以定義只能自己使用的變量,稱內(nèi)部變量。參數(shù)表里的變量也是內(nèi)部變量,函數(shù)定義(definition),函數(shù)是這樣的一種運(yùn)算: 函數(shù)名說(shuō)明運(yùn)算規(guī)則 參數(shù)是運(yùn)算的操作數(shù) 返回值是運(yùn)算的結(jié)果 當(dāng)函數(shù)執(zhí)行到return語(yǔ)句或時(shí),函數(shù)的運(yùn)算停止。程序從當(dāng)次調(diào)用函數(shù)的地方繼續(xù)執(zhí)行 函數(shù)可以有多個(gè)return,但最好只有一個(gè)且是最后一行 用void定義返回值類型 函數(shù)沒有運(yùn)算結(jié)果,沒有返回值 return語(yǔ)句之后不需要任何表達(dá)式 用
6、void定義參數(shù),表示沒有參數(shù) 參數(shù)表里的參數(shù)(叫形式參數(shù),parameter)也是函數(shù)的語(yǔ)句塊內(nèi)的變量,函數(shù)名命名,Windows風(fēng)格函數(shù)名命名 用大寫字母開頭的單詞組合而成 變量名形式 “名詞”或者“形容詞+名詞” 如變量名oldValue與newValue等 函數(shù)名形式 “動(dòng)詞”或者“動(dòng)詞+名詞”(動(dòng)賓詞組) 如函數(shù)名GetMax()等,對(duì)函數(shù)接口加以注釋說(shuō)明,/* 函數(shù)功能:實(shí)現(xiàn)功能 函數(shù)參數(shù):參數(shù)1,表示 參數(shù)2,表示 函數(shù)返回值: */ 返回值類型 函數(shù)名 (參數(shù)表) 函數(shù)體return 表達(dá)式; ,函數(shù)調(diào)用(call),函數(shù)名(表達(dá)式1, 表達(dá)式2, ); 調(diào)用一個(gè)函數(shù)之前,先要
7、對(duì)其返回值類型、函數(shù)名和參數(shù)進(jìn)行聲明(declare) 不對(duì)函數(shù)進(jìn)行聲明是非常危險(xiǎn)的 函數(shù)定義也有聲明函數(shù)的效果 調(diào)用函數(shù)時(shí),提供的表達(dá)式(叫實(shí)際參數(shù), argument)和該函數(shù)的形式參數(shù)必須匹配 數(shù)目一致 類型一一對(duì)應(yīng)(會(huì)發(fā)生自動(dòng)類型轉(zhuǎn)換) 表達(dá)式的值賦值給對(duì)應(yīng)的參數(shù) 返回值可以按需處理,realeql.c,函數(shù)調(diào)用的過(guò)程,函數(shù)的每次執(zhí)行都會(huì)建立一個(gè)全新的獨(dú)立的環(huán)境 在“?!敝袨楹瘮?shù)的每個(gè)變量(包括形式參數(shù))分配內(nèi)存 把實(shí)際參數(shù)的值復(fù)制給形式參數(shù) 開始執(zhí)行函數(shù)內(nèi)的第一條語(yǔ)句 函數(shù)內(nèi)的代碼在這個(gè)獨(dú)立的環(huán)境內(nèi)工作 函數(shù)退出時(shí) 求出返回值,將其存入一個(gè)可以被調(diào)用者訪問的地方(x86中通常使用EA
8、X寄存器) 收回分配給所有變量(包括形式參數(shù))的內(nèi)存 程序控制權(quán)交給調(diào)用者,調(diào)用者拿到返回值,將其作為函數(shù)調(diào)用表達(dá)式的結(jié)果,例5.1a 計(jì)算兩個(gè)整數(shù)的平均數(shù),/* 函數(shù)功能: 計(jì)算平均數(shù) 函數(shù)入口參數(shù): 整型x,存儲(chǔ)第一個(gè)運(yùn)算數(shù) 整型y,存儲(chǔ)第二個(gè)運(yùn)算數(shù) 函數(shù)返回值: 平均數(shù) */ int Average(int x, int y) int result; result = (x + y) / 2; return result; ,函數(shù)調(diào)用(call),單向值傳遞 調(diào)用函數(shù)時(shí),必須提供所有的參數(shù) printf和scanf是采用變長(zhǎng)變量表定義的函數(shù),所以變量的個(gè)數(shù)不固定。 提供的參數(shù)個(gè)數(shù)、類型、
9、順序與定義時(shí)相同 有返回值時(shí) 放到一個(gè)數(shù)值表達(dá)式中,如c = max(a,b); 作為另一個(gè)函數(shù)調(diào)用的參數(shù),如 c = max(max(a,b),c); printf(%dn, max(a,b); 無(wú)返回值時(shí) 函數(shù)調(diào)用表達(dá)式,如display(a,b);,例5.1b 使用了Average函數(shù)的main(),main() int a = 12; int b = 24; int ave; ave = Average(a, b); printf(Average of %d and %d is %d.n, a, b, ave); ,函數(shù)原型(prototype),調(diào)用一個(gè)函數(shù)之前,先要對(duì)其返回值類型、
10、函數(shù)名和參數(shù)進(jìn)行聲明(declare) 不對(duì)函數(shù)進(jìn)行聲明是非常危險(xiǎn)的 聲明時(shí)不要省略參數(shù)以及返回值的類型,main()、printf()和scanf()特 殊 嗎?,main() C語(yǔ)言允許不對(duì)函數(shù)參數(shù)和返回值類型進(jìn)行說(shuō)明 甚至可以連函數(shù)名都不聲明 此時(shí)默認(rèn) 該函數(shù)的參數(shù)是不定個(gè)數(shù)的int型 該函數(shù)返回值為int型 永遠(yuǎn)不要利用此特性! printf()、scanf() 變長(zhǎng)參數(shù)表, 缺點(diǎn):對(duì)參數(shù)類型和個(gè)數(shù)無(wú)法嚴(yán)格驗(yàn)證,易使用出錯(cuò),使用函數(shù)要注意,每個(gè)函數(shù)只完成一個(gè)功能(包括main()) 對(duì)函數(shù)的功能可以用不含連詞的一句話描述 函數(shù)不能過(guò)長(zhǎng) 1986年IBM在OS/360的研究結(jié)果:大多數(shù)有
11、錯(cuò)誤的函數(shù)都大于500行 1991年對(duì)148,000行代碼的研究表明:小于143行的函數(shù)比更長(zhǎng)的函數(shù)更容易維護(hù) 函數(shù)一定要對(duì)傳進(jìn)來(lái)的非法參數(shù)做點(diǎn)什么 向調(diào)用者提供錯(cuò)誤信息 assert(),safediv.c,例5.1,#include /* 函數(shù)功能: 計(jì)算平均數(shù) 函數(shù)入口參數(shù): 整型x,存儲(chǔ)第一個(gè)運(yùn)算數(shù) 整型y,存儲(chǔ)第二個(gè)運(yùn)算數(shù) 函數(shù)返回值: 平均數(shù) */ int Average(int x, int y) int result; result = (x + y) / 2; return result; main() int a = 12; int b = 24; int ave = Av
12、erage(a, b); printf(Average of %d and %d is %d.n, a, b, ave); ,例5.2,#include int Average(int x, int y); /*聲明Average()函數(shù)*/ main() int a = 12; int b = 24; int ave = Average(a, b); printf(Average of %d and %d is %d.n, a, b, ave); /* 函數(shù)功能: 計(jì)算平均數(shù) 函數(shù)入口參數(shù): 整型x,存儲(chǔ)第一個(gè)運(yùn)算數(shù) 整型y,存儲(chǔ)第二個(gè)運(yùn)算數(shù) 函數(shù)返回值: 平均數(shù) */ int Averag
13、e(int x, int y) int result; result = (x + y) / 2; return result; ,函數(shù)的嵌套調(diào)用,main() . ,a 函數(shù) ,b函數(shù) ,在被調(diào)函數(shù)中,又調(diào)用了函數(shù)-嵌套調(diào)用,變量的作用域,指在源程序中定義變量的位置及其能被讀寫訪問的范圍 分為 局部變量(Local Variable) 全局變量(Global Variable ),局部變量,局部變量 在語(yǔ)句塊內(nèi)定義的變量 形參也是局部變量 定義時(shí)不會(huì)自動(dòng)初始化,除非程序員指定初值 進(jìn)入語(yǔ)句塊時(shí)獲得內(nèi)存,僅能由語(yǔ)句塊內(nèi)語(yǔ)句訪問,退出語(yǔ)句塊時(shí)釋放內(nèi)存,不再有效 并列語(yǔ)句塊各自定義的同名變量互不干
14、擾,全局變量,全局變量 在所有函數(shù)之外定義的變量 在程序中定義它的位置以后都有效 自動(dòng)初始化為0 從程序運(yùn)行起即占據(jù)內(nèi)存,程序運(yùn)行過(guò)程中可隨時(shí)訪問,程序退出時(shí)釋放內(nèi)存 在定義點(diǎn)之前或在其他文件中引用,應(yīng)該進(jìn)行如下聲明: extern 類型名 變量名; 使函數(shù)之間的數(shù)據(jù)交換更容易,也更高效 但是并不推薦使用 因?yàn)檎l(shuí)都可以改寫全局變量,所以很難確定是誰(shuí)改寫了它 盡量少用全局變量。不得不用時(shí),要嚴(yán)格控制對(duì)它的改寫,例5.7,#include int global;/*定義全局變量*/ void GlobalPlusPlus(void); main() global = 1; printf(Befor
15、e GlobalPlusPlus(), it is %dn, global); GlobalPlusPlus(); printf(After GlobalPlusPlus(), it is %dn, global); /* 函數(shù)功能: 對(duì)全局變量global加1,并打印加1之前與之后的值 函數(shù)入口參數(shù): 無(wú) 函數(shù)返回值: 無(wú) */ void GlobalPlusPlus(void) printf(Before +, it is %dn, global); global+; printf(After +, it is %dn, global); ,例5.8,#include void Globa
16、lPlusPlus(void); main() int global = 1; printf(Before GlobalPlusPlus(), it is %dn, global); GlobalPlusPlus(); printf(After GlobalPlusPlus(), it is %dn, global); /* 函數(shù)功能: 對(duì)局部變量global加1,并打印加1之前與之后的值 函數(shù)入口參數(shù): 無(wú) 函數(shù)返回值: 無(wú) */ void GlobalPlusPlus(void) int global = 1; printf(Before +, it is %dn, global); gl
17、obal+; printf(After +, it is %dn, global); ,變量的存儲(chǔ)類型,指數(shù)據(jù)在內(nèi)存中存儲(chǔ)的方式,即編譯器為變量分配內(nèi)存的方式,它決定變量的生存期 動(dòng)態(tài)存儲(chǔ) 根據(jù)需要臨時(shí)分配存儲(chǔ)空間,離開即釋放 靜態(tài)存儲(chǔ) 在程序運(yùn)行期間分配固定的存儲(chǔ)空間不釋放,自動(dòng)變量 (auto ),“自動(dòng)”體現(xiàn)在 進(jìn)入語(yǔ)句塊時(shí)自動(dòng)申請(qǐng)內(nèi)存,退出時(shí)自動(dòng)釋放內(nèi)存 動(dòng)態(tài)局部變量 標(biāo)準(zhǔn)定義格式 auto 類型名 變量名; 缺省的存儲(chǔ)類型 不初始化時(shí),值是不確定的,靜態(tài)變量(static),一個(gè)函數(shù)的內(nèi)部變量在函數(shù)退出后失效。再次進(jìn)入函數(shù),變量值重新初始化 把此變量定義為static,則變量的值可以
18、保存到下次進(jìn)入函數(shù) static int i; 靜態(tài)變量和全局變量都是靜態(tài)存儲(chǔ)類型 自動(dòng)初始化為0 從靜態(tài)存儲(chǔ)區(qū)分配,生存期為整個(gè)程序運(yùn)行期間 但作用域不同,例5.9,#include void Func(void); main() int i; for (i=0; i10; i+) Func(); /* 函數(shù)功能: 打印被調(diào)用的次數(shù) 函數(shù)入口參數(shù): 無(wú) 函數(shù)返回值: 無(wú) */ void Func(void) static int times = 1;/*定義靜態(tài)變量*/ printf(Func() was called %d time(s).n, times+); ,假如沒有static,結(jié)
19、果會(huì)怎樣呢?,寄存器變量(register),寄存器 CPU的內(nèi)部容量很有限但速度極快的存儲(chǔ)器 使用頻率比較高的變量聲明為register ,可以使程序更小、執(zhí)行速度更快 register 類型名 變量名; register int i; 現(xiàn)代編譯器有能力自動(dòng)把普通變量?jī)?yōu)化為寄存器變量,并且可以忽略用戶的指定,所以一般無(wú)需特別聲明變量為register,用extern聲明外部變量,外部變量是在函數(shù)的外部定義的全局變量,它的作用域是從變量的定義處開始,到本程序文件的末尾。在此作用域內(nèi),全局變量可以為程序中各個(gè)函數(shù)所引用。編譯時(shí)將外部變量分配在靜態(tài)存儲(chǔ)區(qū)。用extern來(lái)聲明外部變量,以擴(kuò)展外部變
20、量的作用城。,在一個(gè)文件內(nèi)聲明外部變量,例 用extern聲明外部變量,擴(kuò)展它在程序文件中的作用域 #include void main() int max(int,int); *外部變量聲明* extern A,B; printf(%dn,max(A,B); int A=13,B=-8; *定義外部變量* int max(int x,int y) *定義函數(shù) * int z; z=xy?x:y; return(z); ,在多文件的程序中聲明外部變量,#include int A; /*定義外部變量*/ void main() int (int); /*函數(shù)聲明*/ int ,; printf
21、(enter the number a and its power m:n); scanf(,A,); A*; printf(*,A,); (); printf(*n,A,); ,例 用extern將外部變量的作用域擴(kuò)展到其他文件。本程序的作用是給定的值,輸入和,求和am的值。文件file.中的內(nèi)容為:,文件file中的內(nèi)容為: extern A; /*聲明A為一個(gè)已定義的外部變量*/ int powre(int ); int ,; for(;) *A; return(); ,用static聲明外部變量,在程序設(shè)計(jì)中,某些外部變量只限于被本文件引用,而不能被其他文件引用。這時(shí)可以在定義外部變量
22、時(shí)加一個(gè)staitic聲明。 例如: file1.c file2.c static int A; extern int A; void main ( ) void fun (int n) A=A*n; ,關(guān)于變量的聲明和定義,定義性聲明:需要建立存儲(chǔ)空間的(如:int a; )聲明。 引用性聲明:不需建立存儲(chǔ)空間的聲明(extern a;)。 注意: 聲明包括定義,但并非所有的聲明都是定義。對(duì)“int a;” 而言,它既是聲明,又是定義。而對(duì)“extern a;” 而言,它是聲明而不是定義。,存儲(chǔ)類別小結(jié),從作用域角度分,有局部變量和全局變量。它們采用的存儲(chǔ)類別如下: 局部變量包括: 自動(dòng)變量
23、、 靜態(tài)局部變量、寄存器變量。 形式參數(shù)可以定義為自動(dòng)變量或寄存器變量。 全局變量包括: 靜態(tài)外部變量、外部變量。,(2)從變量存在的時(shí)間來(lái)區(qū)分,有動(dòng)態(tài)存儲(chǔ)和靜態(tài)存儲(chǔ)兩種類型。靜態(tài)存儲(chǔ)是程序整個(gè)運(yùn)行時(shí)間都存在,而動(dòng)態(tài)存儲(chǔ)則是在調(diào)用函數(shù)時(shí)臨時(shí)分配單元。 動(dòng)態(tài)存儲(chǔ) :自動(dòng)變量、寄存器變量、形式參數(shù)。 靜態(tài)存儲(chǔ):態(tài)局部變量、靜態(tài)外部變量 、外部變量。,(3) 從變量值存放的位置來(lái)區(qū)分,可分為: 內(nèi)存中靜態(tài)存儲(chǔ)區(qū):靜態(tài)局部變量、靜態(tài)外部變量、 外部變量。 內(nèi)存中動(dòng)態(tài)存儲(chǔ)區(qū):自動(dòng)變量和形式參數(shù)。 CPU中的寄存器:寄存器變量。,(4) static對(duì)局部變量和全局變量的作用不同。對(duì)局部變量來(lái)說(shuō),它使變量
24、由動(dòng)態(tài)存儲(chǔ)方式改變?yōu)殪o態(tài)存儲(chǔ)方式。而對(duì)全局變量來(lái)說(shuō),它使變量局部化,但仍為靜態(tài)存儲(chǔ)方式。從作用域角度看,凡有static聲明的,其作用域都是局限的,或者是局限于本函數(shù)內(nèi),或者局限于本文件內(nèi)。,編譯預(yù)處理,作用:對(duì)源程序編譯之前做一些處理,生成擴(kuò)展C源程序 種類 宏定義 #define 文件包含 #include 條件編譯 #if-#else-#endif等 格式: “#”開頭 占單獨(dú)書寫行 語(yǔ)句尾不加分號(hào),不帶參數(shù)宏定義 一般形式: #define 宏名 宏體 功能:用指定標(biāo)識(shí)符(宏名)代替字符序列(宏體),宏展開:預(yù)編譯時(shí),用宏體替換宏名-不作語(yǔ)法檢查,宏體可缺省,表示宏名 定義過(guò)或取消宏體
25、,定義位置:任意(一般在函數(shù)外面) 作用域:從定義命令到文件結(jié)束 #undef可終止宏名作用域 格式: #undef 宏名,宏定義可嵌套,不能遞歸,例 #define MAX MAX+10 (),引號(hào)中的內(nèi)容與宏名相同也不置換,宏定義中使用必要的括號(hào)(),宏定義,(1) 宏名一般習(xí)慣用大寫字母表示,以便與變量名相區(qū)別。但這并非規(guī)定,也可用小寫字母。 (2) 使用宏名代替一個(gè)字符串,可以減少程序中重復(fù)書寫某些字符串的工作量。 (3) 宏定義是用宏名代替一個(gè)字符串,只作簡(jiǎn)單置換,不作正確性檢查。只有在編譯已被宏展開后的源程序時(shí)才會(huì)發(fā)現(xiàn)語(yǔ)法錯(cuò)誤并報(bào)錯(cuò)。,說(shuō)明:,(4) 宏定義不是語(yǔ)句,不必在行末加分
26、號(hào)。如果加了分號(hào)則會(huì)連分號(hào)一起進(jìn)行置換。 (5) define命令出現(xiàn)在程序中函數(shù)的外面,宏名的有效范圍為定義命令之后到本源文件結(jié)束。通常,define命令寫在文件開頭,函數(shù)之前,作為文件一部分,在此文件范圍內(nèi)有效。 (6) 可以用undef命令終止宏定義的作用域。,#define G 9.8 _ void main() G的有效范圍 - #undef G f1() ,在f1函數(shù)中,不再代表9.8。這樣可以靈活控制宏定義的作用范圍。,例如:,(7) 在進(jìn)行宏定義時(shí),可以引用已定義的宏名,可以層層置換。,說(shuō)明:,#include #define R 3.0 #define PI 3.141592
27、6 #define L 2*PI*R #define S PI*R*R void main() printf(L=%fnS=%fn,L,S); ,運(yùn)行情況如下:,L=18.849556 S=28.274333,例 在宏定義中引用已定義的宏名。,經(jīng)過(guò)宏展開后,printf函數(shù)中的輸出項(xiàng)被展開為: 2*3.1415926*3.0 展開為 3.1415926*3.0*3.0 printf函數(shù)調(diào)用語(yǔ)句展開為:,printf(“L=%fnS=%fn”, 2*3.1415926*3.0, 3.1415926*3.0*3.0);,(8) 對(duì)程序中用雙撇號(hào)括起來(lái)的字符串內(nèi)的字符,即使與宏名相同,也不進(jìn)行置換。
28、 (9) 宏定義是專門用于預(yù)處理命令的一個(gè)專用名詞,它與定義變量的含義不同,只作字符替換,不分配內(nèi)存空間。,說(shuō)明:,一般形式: #define 宏名(參數(shù)表) 宏體,例 #define S (r) PI*r*r 相當(dāng)于定義了不帶參宏S,代表字符串“(r) PI*r*r”,宏展開:形參用實(shí)參換,其它字符保留 宏體及各形參外一般應(yīng)加括號(hào)(),例 #define S(a,b) a*b . area=S(3,2); 宏展開: area=3*2;,不能加空格,例 #define POWER(x) x*x x=4; y=6; z=POWER(x+y); 宏展開:z=x+y*x+y; 一般寫成: #defi
29、ne POWER(x) (x)*(x) 宏展開: z=(x+y)*(x+y);,帶參數(shù)宏定義,例 用宏定義和函數(shù)實(shí)現(xiàn)同樣的功能,(1)對(duì)帶參數(shù)的宏展開只是將語(yǔ)句中的宏名后面括號(hào)內(nèi)的實(shí)參字符串代替define 命令行中的形參。 (2) 在宏定義時(shí),在宏名與帶參數(shù)的括弧之間不應(yīng)加空格,否則將空格以后的字符都作為替代字符串的一部分。,說(shuō)明:,帶參的宏與函數(shù)區(qū)別,(1) 函數(shù)調(diào)用時(shí),先求出實(shí)參表達(dá)式的值,然后代入形參。而使用帶參的宏只是進(jìn)行簡(jiǎn)單的字符替換。 (2) 函數(shù)調(diào)用是在程序運(yùn)行時(shí)處理的,為形參分配臨時(shí)的內(nèi)存單元。而宏展開則是在編譯前進(jìn)行的,在展開時(shí)并不分配內(nèi)存單元,不進(jìn)行值的傳遞處理,也沒有“
30、返回值”的概念。 (3) 對(duì)函數(shù)中的實(shí)參和形參類型要求一致。而宏名無(wú)類型,它的參數(shù)也無(wú)類型,只是一個(gè)符號(hào)代表,展開時(shí)代入指定的字符串即可。宏定義時(shí),字符串可以是任何類型的數(shù)據(jù)。 (4) 調(diào)用函數(shù)只可得到一個(gè)返回值,而用宏可以設(shè)法得到幾個(gè)結(jié)果。,帶參數(shù)的宏和函數(shù)的區(qū)別:,#include #define PI 3.1415926 #define CIRCLE(R,L,S,V) L=2*PI*R;S=PI*R*R; V=4.0/3.0*PI*R*R*R void main() float r,l,s,v; scanf(%f, ,例 通過(guò)宏展開得到若干個(gè)結(jié)果。,void main() float r
31、,l,s,v; scanf(%f, ,對(duì)宏進(jìn)行預(yù)編譯,展開后的main函數(shù)如下:,運(yùn)行情況如下:,3.5 r=3.50,l=21.99,s=38.48,v=179.59,(5) 使用宏次數(shù)多時(shí),宏展開后源程序長(zhǎng),因?yàn)槊空归_一次都使程序增長(zhǎng),而函數(shù)調(diào)用不會(huì)使源程序變長(zhǎng)。 (6) 宏替換不占運(yùn)行時(shí)間,只占編譯時(shí)間。而函數(shù)調(diào)用則占運(yùn)行時(shí)間(分配單元、保留現(xiàn)場(chǎng)、值傳遞、返回)。,帶參數(shù)的宏和函數(shù)的區(qū)別:,如果善于利用宏定義,可以實(shí)現(xiàn)程序的簡(jiǎn)化,如事先將程序中的“輸出格式”定義好,以減少在輸出語(yǔ)句中每次都要寫出具體的輸出格式的麻煩。,例 通過(guò)宏展開得到若干個(gè)結(jié)果。,#include #define PR
32、 printf #define NL n #define D %d #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S %s,void main() int a,b,c,d; char string=CHINA; a=1;b=2;c=3;d=4; PR(D1,a); PR(D2,a,b); PR(D3,a,b,c); PR(D4,a,b,c,d); PR(S,string); ,運(yùn)行時(shí)輸出結(jié)果:, ,功能:一個(gè)源文件可將另一個(gè)源文件的內(nèi)容全部包含進(jìn)來(lái) 一般形式: #inclu
33、de “文件名” 或 #include ,處理過(guò)程:預(yù)編譯時(shí),用被包含文件的內(nèi)容取代該預(yù)處理命令,再對(duì)“包含”后的文件作一個(gè)源文件編譯, 直接按標(biāo)準(zhǔn)目錄搜索 “” 先在當(dāng)前目錄搜索,再搜索標(biāo)準(zhǔn)目錄 可指定路徑,文件包含,源文件(*.c) 頭文件(*.h),宏定義 數(shù)據(jù)結(jié)構(gòu)定義 函數(shù)說(shuō)明等,文件包含可嵌套,被包含文件內(nèi)容,例 文件包含舉例,條件編譯,概念:所謂“條件編譯”,是對(duì)部分內(nèi)容指定編譯的條件,使其只在滿足一定條件才進(jìn)行編譯。,條件編譯命令的幾種形式:,(1)ifdef 標(biāo)識(shí)符 程序段 else 程序段 endif,(2)ifndef 標(biāo)識(shí)符 程序段 else 程序段 endif,(3) if 表達(dá)式 程序段 else 程序段 endif,例97 輸入一行字母字符,根據(jù)需要設(shè)置條件編譯,使之能將字母全改為大寫輸出,或全改為小寫字母輸出。,#inc
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030轉(zhuǎn)向臂起重機(jī)行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 2025至2030中國(guó)自穿孔鉚釘行業(yè)市場(chǎng)占有率及投資前景評(píng)估規(guī)劃報(bào)告
- 2025至2030中國(guó)自助秤行業(yè)發(fā)展趨勢(shì)分析與未來(lái)投資戰(zhàn)略咨詢研究報(bào)告
- 2025至2030中國(guó)自動(dòng)視覺檢測(cè)系統(tǒng)行業(yè)市場(chǎng)占有率及投資前景評(píng)估規(guī)劃報(bào)告
- 2025至2030中國(guó)腕帶高爾夫GPS行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 2025至2030中國(guó)腳輪上的患者升降平臺(tái)行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 2025至2030中國(guó)胃腸病學(xué)設(shè)備行業(yè)市場(chǎng)深度研究及發(fā)展前景投資可行性分析報(bào)告
- 2025至2030中國(guó)腸內(nèi)飼管行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 2025至2030中國(guó)聚苯醚(PPE)混合物和合金行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 2025至2030中國(guó)聚丙烯蜂窩行業(yè)產(chǎn)業(yè)運(yùn)行態(tài)勢(shì)及投資規(guī)劃深度研究報(bào)告
- 路燈安裝考試試題及答案
- 赤峰市翁牛特旗招聘社區(qū)工作者筆試真題2024
- 線上游戲賬號(hào)及虛擬物品交易合同
- 2025至2030全球及中國(guó)家用濕巾行業(yè)發(fā)展趨勢(shì)分析與未來(lái)投資戰(zhàn)略咨詢研究報(bào)告
- 市場(chǎng)監(jiān)管培訓(xùn)
- 2025至2030中國(guó)電鍍鋅鋼行業(yè)發(fā)展趨勢(shì)分析與未來(lái)投資戰(zhàn)略咨詢研究報(bào)告
- 山西省2025年中考語(yǔ)文真題(含答案)
- 企業(yè)研發(fā)人員管理制度
- 黑吉遼蒙2025年高考政治真題含解析
- 滬教七年級(jí) (下) Unit 7 Role models of our time 重點(diǎn)復(fù)習(xí)課件
- 遼寧省沈陽(yáng)市沈河區(qū)2025屆英語(yǔ)八下期末監(jiān)測(cè)模擬試題含答案
評(píng)論
0/150
提交評(píng)論