版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第七章 函數(shù)及變量存儲(chǔ)類別,本章要求 理解模塊化程序設(shè)計(jì)思想; 掌握函數(shù)的定義與調(diào)用方法; 掌握C語(yǔ)言的參數(shù)傳遞方式; 掌握變量的作用域和存儲(chǔ)方式。 掌握用#define定義無(wú)參數(shù)宏和帶有參數(shù)宏定義和調(diào)用方法; 掌握#include文件包含的使用方法,理解多個(gè)源文件的C程 序的運(yùn)行 ; 了解條件編譯的使用。,第七章 函數(shù)及變量存儲(chǔ)類別,本章重點(diǎn) 函數(shù)的定義與調(diào)用 參數(shù)傳遞 變量的作用域和存儲(chǔ)方式 帶參宏定義和使用方法、文件包含的使用 本章難點(diǎn) 參數(shù)傳遞 變量的作用域和存儲(chǔ)方式 帶參宏定義和使用方法,函數(shù)的概念,函數(shù)的概念,函數(shù)的概念,函數(shù)的概念,函數(shù)的概念,函數(shù)的概念,函數(shù)的定義和聲明,函數(shù)的
2、定義形式 存儲(chǔ)類型標(biāo)識(shí)符 類型標(biāo)識(shí)符 函數(shù)名(類型名 形式參數(shù)1, ) 說(shuō)明部分 語(yǔ)句部分 函數(shù)定義由函數(shù)首部和函數(shù)體兩部分組成。函數(shù)首部即定義一個(gè)函數(shù)時(shí)的第一行,包括存儲(chǔ)類型標(biāo)識(shí)符、類型標(biāo)識(shí)符 函數(shù)名和由()括起來(lái)的參數(shù)表; 部分稱為函數(shù)體,語(yǔ)法上是一個(gè)復(fù)合語(yǔ)句。,1)存儲(chǔ)類型標(biāo)識(shí)符說(shuō)明函數(shù)的存儲(chǔ)類型,它規(guī)定了函數(shù)可被調(diào)用的范圍??捎糜诤瘮?shù)存儲(chǔ)類型標(biāo)識(shí)符有static和extern,指定為static的函數(shù)為靜態(tài)函數(shù),靜態(tài)函數(shù)只能由和它在同一文件中定義的函數(shù)調(diào)用;缺省或指定為extern存儲(chǔ)類型的函數(shù)為外部函數(shù)。例如:例7.1中的square() 函數(shù)是外部函數(shù)。 )類型標(biāo)識(shí)符說(shuō)明函數(shù)返回值
3、的數(shù)據(jù)類型,可以為任何基本類型、結(jié)構(gòu)體類型,還可以是指針類型,也可以是無(wú)返回值類型即空類型(void)。缺省時(shí)為int型。 )函數(shù)名是一個(gè)標(biāo)識(shí)符,一程序中除main()外,其余函數(shù)的名字可以任意取。函數(shù)名一般不要超過(guò)個(gè)字符。同一文件中的函數(shù)不能同名。 )形式參數(shù)可以是0個(gè)、一個(gè)或多個(gè),表示該函數(shù)被調(diào)用時(shí)所需的一些必要信息,函數(shù)定義的說(shuō)明:,函數(shù)定義的說(shuō)明:,)對(duì)于有參函數(shù),形式參數(shù)的定義與變量的定義形式相似 )函數(shù)體是一組放在一對(duì)花括號(hào)中的語(yǔ)句 ,一般包括聲明部分和執(zhí)行部分 )在函數(shù)中,形式參數(shù)可以作為已知的變量,不需要對(duì)它賦值就可使用它,它的值是函數(shù)調(diào)用時(shí)由實(shí)參傳遞給形參變量而得到的,函數(shù)的
4、定義和聲明,函數(shù)返回值 C語(yǔ)言通過(guò)return語(yǔ)句獲得函數(shù)返回值的,其格式如下: return 表達(dá)式; 或 return(表達(dá)式); 表達(dá)式的值就是函數(shù)的返回值。對(duì)于基本類型,表達(dá)式的類型和函數(shù)的類型不相同時(shí)表達(dá)式的值自動(dòng)轉(zhuǎn)換為涵數(shù)的類型,對(duì)于指針,表達(dá)式的類型和函數(shù)的類型不相同時(shí),須使用類型強(qiáng)制符將表達(dá)式轉(zhuǎn)換為函數(shù)的類型;對(duì)于結(jié)構(gòu)體,表達(dá)式值的類型與函數(shù)定義的類型必須相同。 例如,可以將power()函數(shù)定義為: double power(int x,int n) int i; long p; return(p); 其中,“return(p)”將表達(dá)式p的值作為power()函數(shù)的返回值。
5、p自動(dòng)轉(zhuǎn)換成double類型。,函數(shù)的聲明(函數(shù)原型) 在使用自定義函數(shù)時(shí),除了進(jìn)行函數(shù)的定義外,還需要在調(diào)用該函數(shù)之前對(duì)其進(jìn)行原型聲明 函數(shù)原型聲明和函數(shù)定義的區(qū)別 函數(shù)原型聲明的作用是將函數(shù)類型告訴編譯系統(tǒng),使程序在編譯階段對(duì)調(diào)用函數(shù)的合法性進(jìn)行全面的檢查,避免函數(shù)調(diào)用時(shí)出現(xiàn)參數(shù)的個(gè)數(shù)或類型不一致的運(yùn)行錯(cuò)誤。 函數(shù)定義部分則是函數(shù)的實(shí)際實(shí)現(xiàn)代碼 函數(shù)原型聲明的格式: 存儲(chǔ)類型標(biāo)識(shí)符類型符 函數(shù)名(形式參數(shù)表);,7.2 函數(shù)的定義和聲明,7.2.3 函數(shù)的聲明(函數(shù)原型) 說(shuō)明: (1)函數(shù)原型聲明語(yǔ)句最后的分號(hào)不能省略,其作用是表示該語(yǔ)句是進(jìn)行函數(shù)聲明而不是函數(shù)定義。 (2)在原型聲明中
6、,形式參數(shù)名可以省略。 如:double power(int, int ); 和 double power(int x, int n); 和 double power(int a, int n); 都是等價(jià)的。power()函數(shù)是double類型的,它有兩個(gè)int參數(shù)。聲明給出的參數(shù)名x、n被編譯忽略,因?yàn)閰?shù)的存儲(chǔ)空間是在函數(shù)衩調(diào)用時(shí)進(jìn)行的。 對(duì)于無(wú)參數(shù)表的函數(shù),聲明時(shí)參數(shù)表應(yīng)指定為void。 (3)如果被調(diào)用函數(shù)的定義出現(xiàn)在調(diào)用函數(shù)之前,可以不對(duì)被調(diào)用函數(shù)進(jìn)行原型聲明。 (4)如果被調(diào)用函數(shù)已在所有函數(shù)定義之前進(jìn)行了原型聲明,則在各個(gè)調(diào)用函數(shù)中不必再對(duì)該函數(shù)進(jìn)行原型聲明 ()標(biāo)準(zhǔn)庫(kù)函數(shù)的原
7、型在系統(tǒng)提供的相應(yīng)頭文件中,因此,程序中調(diào)用標(biāo)準(zhǔn)庫(kù)函數(shù)時(shí),只需用#include預(yù)處理控制包含所需的頭文件,而不需要寫函數(shù)聲明。,函數(shù)的定義和聲明,函數(shù)的聲明(函數(shù)原型) 說(shuō)明: (1)函數(shù)原型聲明語(yǔ)句最后的分號(hào)不能省略,其作用是表示該語(yǔ)句是進(jìn)行函數(shù)聲明而不是函數(shù)定義。 (2)在原型聲明中,形式參數(shù)名可以省略。 如:double power(int, int ); 和 double power(int x, int n); 和 double power(int a, int n); 都是等價(jià)的。power()函數(shù)是double類型的,它有兩個(gè)int參數(shù)。聲明給出的參數(shù)名x、n被編譯忽略,因?yàn)閰?/p>
8、數(shù)的存儲(chǔ)空間是在函數(shù)衩調(diào)用時(shí)進(jìn)行的。 對(duì)于無(wú)參數(shù)表的函數(shù),聲明時(shí)參數(shù)表應(yīng)指定為void。 (3)如果被調(diào)用函數(shù)的定義出現(xiàn)在調(diào)用函數(shù)之前,可以不對(duì)被調(diào)用函數(shù)進(jìn)行原型聲明。 (4)如果被調(diào)用函數(shù)已在所有函數(shù)定義之前進(jìn)行了原型聲明,則在各個(gè)調(diào)用函數(shù)中不必再對(duì)該函數(shù)進(jìn)行原型聲明 ()標(biāo)準(zhǔn)庫(kù)函數(shù)的原型在系統(tǒng)提供的相應(yīng)頭文件中,因此,程序中調(diào)用標(biāo)準(zhǔn)庫(kù)函數(shù)時(shí),只需用#include預(yù)處理控制包含所需的頭文件,而不需要寫函數(shù)聲明。,函數(shù)的定義和聲明,函數(shù)的說(shuō)明,函數(shù)說(shuō)明的形式 函數(shù)返回值的類型名 函數(shù)名(類型名 形式參數(shù)名1,類型名形參數(shù)名 ); 簡(jiǎn)單地說(shuō)就是在函數(shù)的首部加上一個(gè)“;”。因?yàn)楹瘮?shù)的聲明是語(yǔ)句,
9、因此后面的“;”必不可少。 double area(double a ,double b); /*函數(shù)聲明*/ main() double x=1.2,y=2.4,z; z=area(x,y);/*函數(shù)調(diào)用*/ printf(“area=%lf”,z); double area(double a ,double b)/*函數(shù)定義*/ double s; s=a*b; return s; ,函數(shù)的說(shuō)明,函數(shù)說(shuō)明的形式 函數(shù)在說(shuō)明時(shí)的形參名可以和定義時(shí)的形參名不同 函數(shù)返回值的類型名 函數(shù)名(類型名 參數(shù)名1,類型名 參數(shù)名2 ); 如上例中就完全可以把函數(shù)聲明為 double area(doub
10、le m,double n ); /*函數(shù)聲明*/ main() double x=1.2,y=2.4,z; z=area(x,y);/*函數(shù)調(diào)用*/ printf(“area=%lf”,z); double area(double a ,double b)/*函數(shù)定義*/ double s; s=a*b; return s; ,函數(shù)的說(shuō)明,函數(shù)說(shuō)明的形式 函數(shù)在說(shuō)明時(shí)甚至可以省略不寫形參名,只有類型名 函數(shù)返回值的類型名 函數(shù)名(類型名 ,類型名 ); 如上例中就完全可以把函數(shù)聲明為 double area(double ,double ); /*函數(shù)聲明*/ main() double x
11、=1.2,y=2.4,z; z=area(x,y);/*函數(shù)調(diào)用*/ printf(“area=%lf”,z); double area(double a ,double b)/*函數(shù)定義*/ double s; s=a*b; return s; ,函數(shù)的說(shuō)明,函數(shù)說(shuō)明的形式 函數(shù)在說(shuō)明也可以與普通變量一起出現(xiàn)在同一個(gè)類型定義語(yǔ)句中, 類型名變量名1,變量名2, 函數(shù)名(類型名 ,類型名 ); 如上例中就完全可以把函數(shù)聲明為 main() double x=1.2,y=2.4,z, area(double ,double );/*變量定義、函數(shù)聲明*/ z=area(x,y); /*函數(shù)調(diào)用*
12、/ printf(“area=%lf”,z); double area(double a ,double b) /*函數(shù)定義*/ double s; s=a*b; return s; ,函數(shù)的定義與調(diào)用,函數(shù)的定義與調(diào)用,函數(shù)的參數(shù),函數(shù)的參數(shù),函數(shù)的參數(shù)傳遞,數(shù)據(jù)只能從實(shí)參單向傳到形參,即實(shí)參的值不能通過(guò)函數(shù)改變。 到目前為止,函數(shù)最多只能返回一個(gè)函數(shù)值。,void swap(int x, int y) int t; t=x; x=y; y=t; printf(%d %d ,x ,y); main( ) int a= 3,b=4; swap(a,b); printf(%d %d ,a,b);
13、 ,程序輸出結(jié)果: 4 3 3 4,形式參數(shù)(形參),實(shí)際參數(shù)(實(shí)參),單向值傳遞,函數(shù)的參數(shù)傳遞,【例】以下程序的輸出結(jié)果是,例:形參與實(shí)參的數(shù)值傳遞。 程序代碼如下: #include void swap(int a,int b); /*聲明函數(shù)原型*/ void main() int x,y; x=10; y=20; printf(Before swapping:x=%d y=%dn,x,y); swap(x,y); /*調(diào)用函數(shù)*/ printf(After swapping:x=%d y=%dn,x,y); void swap(int a,int b) /*定義函數(shù)*/ int t;
14、 t=a; a=b; b=t; ,形參和實(shí)參的數(shù)值傳遞,程序輸出如下: Before swapping:x=10 y=20 After swapping:x=10 y=20,形參和實(shí)參的數(shù)值傳遞,s(int r) return 3.14*r*r; main( ) int r,area; scanf(%d, ,自動(dòng)轉(zhuǎn)換為int型,思考: 若要得到單精度實(shí)型的圓面積,程序應(yīng)如何修改,程序運(yùn)行情況如下: 2 12,?,例 參數(shù)的返回值,7.4 指針與函數(shù),例函數(shù)的嵌套調(diào)用,main( ) int n=3; printf (%dn,sub1(n); ,sub1(int n) int i,a=0; fo
15、r (i=n; i0; i-) a+=sub2(i); return a ; ,sub2(int n) return n+1; ,程序輸出結(jié)果: 9,遞歸調(diào)用過(guò)程,例 用遞歸方法求Fibonacci數(shù)列。,#include double fib(int n) if (n=1|n=2) return 1; return fib(n-1)+fib(n-2); void main( ) int n; printf(“n=”); scanf(“%d, ,歷年真題,2009年3月 (33)有以下程序 #include int fun(int x,int y) if(x=y) return(x); els
16、e returen(x+y)/2) main() int a=4,b=5,c=6; printf(“%dn”,fun(2*a,fun(b,c) 程序運(yùn)行后的輸出結(jié)果是 A)3 B)6 C)8 D)12,答案:B,歷年真題,2009年3月 (12)請(qǐng)將以下程序中的函數(shù)聲明語(yǔ)句補(bǔ)充完整 #include int【12】 ; main( ) int x,y,(*p)(); p=max; printf(“%dn”,(*p)(x,y); int max(int a,int b) return (ab/a:b);,答案: max(int a,int b),歷年真題,2008年9月 (22)下面的函數(shù)調(diào)用語(yǔ)
17、句中func函數(shù)的實(shí)參個(gè)數(shù)是 func(f2(v1,v2),(v3,v4,v5),(v6,max(v7,v8); A)3 B) 4 C)5 D)8,答案: A,2008年9月 (25)以下敘述中錯(cuò)誤的是 A) 用戶定義的函數(shù)中可以沒(méi)有return語(yǔ)句 B)用戶定義的函數(shù)中可以有多個(gè)return語(yǔ)句,以便可以調(diào)用一次返回多個(gè)函數(shù)值 C)用戶定義的函數(shù)中若沒(méi)有return語(yǔ)句,則應(yīng)當(dāng)定義函數(shù)為void類型 D)函數(shù)的return語(yǔ)句中可以沒(méi)有表達(dá)式,答案: B,void sub(int a,int b) int c; a=a+b; b=b+a; c=b-a; printf(sub:ta=%d b=
18、 %d c= %dn,a,b,c); ,main( ) int a=1,b=1,c=1; printf(main:ta=%d b= %d c= %dn,a,b,c); sub(a,b); printf(main:ta=%d b= %d c= %dn,a,b,c); int a=2,b=2; printf(comp:ta=%d b= %d c= %dn,a,b,c); printf(main:ta=%d b= %d c= %dn,a,b,c); ,“分程序”或“程序塊”,程序輸出結(jié)果: main: a=1 b= 1 c= 1 sub: a=2 b= 3 c= 1 main: a=1 b= 1 c
19、= 1 comp: a=2 b= 2 c= 1 main: a=1 b= 1 c= 1,int a = 5; void f(int x, int y) int b,c; b=a+x; c=a-y; printf(%dt%dt%dn,a,b,c); ,程序輸出結(jié)果: 5 11 -2 5 6 7 9 8 7 9 8 10 9 8 10 5 6 10,全局變量,變量的存儲(chǔ)類別,變量的生存期與變量的存儲(chǔ)分類,變量的生存期:變量在內(nèi)存中占據(jù)存儲(chǔ)空間的時(shí)間。,思考:1. 何時(shí)為變量分配內(nèi)存單元? 2. 將變量分配在內(nèi)存的什么區(qū)域? 3. 變量占據(jù)內(nèi)存的時(shí)間(生存期)?,動(dòng)態(tài)存儲(chǔ)變量,靜態(tài)存儲(chǔ)變量,變量的存
20、儲(chǔ)類別,變量的屬性,數(shù)據(jù)類型: 決定為變量分配內(nèi)存單元的長(zhǎng)度, 數(shù)據(jù)的存放形式, 數(shù)的范圍。,存儲(chǔ)類別: 決定了變量的生存期, 給它分配在哪個(gè)存儲(chǔ)區(qū)。,變量定義語(yǔ)句的一般形式,存儲(chǔ)類別 數(shù)據(jù)類型 變量名1, , 變量名n ;,auto(自動(dòng)的) register(寄存器的)static(靜態(tài)的) extern(外部的),1自動(dòng)變量(auto類別) 局部變量可以定義為自動(dòng)變量。, 內(nèi)存分配 調(diào)用函數(shù)或執(zhí)行分程序時(shí)在動(dòng)態(tài)存儲(chǔ)區(qū)為其分配存儲(chǔ)單元,函數(shù)或分程序執(zhí)行結(jié)束,所占內(nèi)存空間即刻釋放。 變量的初值 定義變量時(shí)若沒(méi)賦初值,變量的初值不確定;如果賦初值則每次函數(shù)被調(diào)用時(shí)執(zhí)行一次賦值操作。 生存期 在
21、函數(shù)或分程序執(zhí)行期間。 作用域 自動(dòng)變量所在的函數(shù)內(nèi)或分程序內(nèi)。,自動(dòng)變量,2靜態(tài)變量(static類別),除形參外,局部變量和全局變量都可以定義為靜態(tài)變量。, 內(nèi)存分配 編譯時(shí),將其分配在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)中,程序運(yùn)行結(jié)束釋放該單元。 靜態(tài)變量的初值 若定義時(shí)未賦初值,在編譯時(shí),系統(tǒng)自動(dòng)賦初值為0;若定義時(shí)賦初值,則僅在編譯時(shí)賦初值一次,程序運(yùn)行后不再給變量賦初值 。 生存期 整個(gè)程序的執(zhí)行期間。 作用域 局部靜態(tài)變量的作用域是它所在的函數(shù)或分程序。全局靜態(tài)變量的作用域是從定義處開始到本源文件結(jié)束。,靜態(tài)變量,3.外部變量(extern類別),在函數(shù)外定義的變量若沒(méi)有用 static說(shuō)明,則是
22、外部變量。外部變量只能隱式定義為extern類別,不能顯式定義。, 內(nèi)存分配 編譯時(shí),將其分配在靜態(tài)存儲(chǔ)區(qū),程序運(yùn)行結(jié)束釋放該單元。 變量的初值 若定義變量時(shí)未賦初值,在編譯時(shí),系統(tǒng)自動(dòng)賦初值為0。 生存期 整個(gè)程序的執(zhí)行期間。 作用域 從定義處開始到本源文件結(jié)束。 此外,還可以用extern進(jìn)行聲明,以使其作用域擴(kuò)大到該程序的其它文件中。,外部變量,外部變量聲明的一般格式,extern 數(shù)據(jù)類型 變量名1,變量名n; 或 extern 變量名1,變量名n;,注意: 外部變量聲明用關(guān)鍵字extern,而外部變量的定義不能用extern,只能隱式定義。 定義外部變量時(shí),系統(tǒng)要給變量分配存儲(chǔ)空間,
23、而對(duì)外部變量聲明時(shí),系統(tǒng)不分配存儲(chǔ)空間,只是讓編譯系統(tǒng)知道該變量是一個(gè)已經(jīng)定義過(guò)的外部變量,與函數(shù)聲明的作用類似。,int p=1,q=5; float f1(int a) extern char c1,c2; char c1,c2; char f2(int x,int y) main( ) ,思考:在f1函數(shù)中聲明c1、c2的作用是什么?如何修改程序使所有函數(shù)都可以使用外部變量而又不需要聲明?,例7.11 在一個(gè)文件內(nèi)聲明外部變量。,4.寄存器變量(register類別),只有函數(shù)內(nèi)定義的變量或形參可以定義為寄存器變量。寄存器變量的值保存在CPU的寄存器中。 受寄存器長(zhǎng)度的限制,寄存器變量只
24、能是char、int和指針類型的變量。,例7.13 寄存器變量的使用。 main( ) long int sum=0; register int i; for (i=1; i=1000; i+) sum+=i; printf(sum=%ldn ,sum); ,程序輸出結(jié)果: sum=500500,說(shuō)明:計(jì)算機(jī)的寄存器是有限的,為確保寄存器用于最需要的地方,應(yīng)將使用最頻繁的值說(shuō)明為寄存器存儲(chǔ)類型。,歸納變量的分類,1按照變量的作用域?qū)ψ兞糠诸?局部變量 全局變量 2按照變量的生存期對(duì)變量分類 靜態(tài)存儲(chǔ)變量 包括:局部靜態(tài)變量和全局靜態(tài)變量 動(dòng)態(tài)存儲(chǔ)變量 包括:自動(dòng)變量,7.7 編譯預(yù)處理,在C語(yǔ)
25、言源程序中以“#”號(hào)開頭的預(yù)處理命令都放在函數(shù)之外,一般都放在源文件的前面,它們稱為預(yù)處理部分。 所謂預(yù)處理是指在進(jìn)行編譯的第一遍掃描(詞法掃描和語(yǔ)法分析)之前所作的工作。 預(yù)處理是語(yǔ)言的一個(gè)重要功能,由預(yù)處理程序負(fù)責(zé)完成。 對(duì)源文件進(jìn)行編譯時(shí),系統(tǒng)將自動(dòng)引用預(yù)處理程序?qū)υ闯绦蛑蓄A(yù)處理部分作處理,處理完再自動(dòng)進(jìn)入對(duì)源程序的編譯。 語(yǔ)言提供了多種預(yù)處理功能,主要有宏定義、文件包含、條件編譯。,7.7.1 宏定義,預(yù)處理命令#define用來(lái)建立符號(hào)常量(用符號(hào)表示的常量)和宏(用符號(hào)定義的操作)。 語(yǔ)言源程序中用一個(gè)標(biāo)識(shí)符來(lái)表示一個(gè)字符串, 稱為宏。 被定義為“宏”的標(biāo)識(shí)符稱為“宏名”。 在編譯
26、預(yù)處理時(shí),對(duì)程序中所有出現(xiàn)的“宏名”,都用宏定義中的字符串去代換,稱為“宏代換”或“宏展開”。 宏定義是由源程序中的宏定義命令完成的。 宏代換是由預(yù)處理程序自動(dòng)完成的。 語(yǔ)言中,“宏”分為有參數(shù)和無(wú)參數(shù)兩種。,例7-14 通過(guò)鍵盤輸入100個(gè)實(shí)數(shù),將其中大于它們平均值的數(shù)打印輸出。 (使用無(wú)參宏定義) #define NUM 100 void main() int i;float xNUM,ave=0; for(i=0;iave) printf(%f ,xi); ,1.無(wú)參宏定義,1.無(wú)參宏定義,一般形式: #define 標(biāo)識(shí)符 字符串 第一部分為#define命令本身。第二部分為自定義的宏
27、名。宏的名字中不允許有空格,遵循C語(yǔ)言變量的命名規(guī)則。第三部分(#define行的其余部分)稱為替換文本。 預(yù)處理器在處理過(guò)程中發(fā)現(xiàn)程序中的宏實(shí)例后,會(huì)用它的等價(jià)替換文本代替宏。從宏變成最終替換文本的過(guò)程為“宏展開”或“宏代換”。 如例7-14的程序被預(yù)處理之后,程序中所有的NUM已經(jīng)由預(yù)處理器替換成了100。從這里可以看出給符號(hào)常量取有意義的名字能提高程序的可讀性和可維護(hù)性。,例7-15 輸入一個(gè)圓的半徑,輸出該圓的周長(zhǎng)。 #define PI 3.14 #define C 2*PI*r/*PI是已定義的宏名*/ void main() double r; printf(Enter The
28、Radiusn); scanf(%lf, ,1.無(wú)參宏定義,C語(yǔ)言允許宏定義嵌套,在宏定義的字符串中可以使用已經(jīng)定義的宏名。在宏展開時(shí)由預(yù)處理器進(jìn)行層層代換。 本例的宏定義用“C”替換表達(dá)式“2*PI*r”,因此宏不僅可以代替常量,宏還可以表示任何字符串,甚至是整個(gè)表達(dá)式。 如果本例中沒(méi)有“double r;”這個(gè)定義,則程序編譯時(shí)會(huì)出現(xiàn)變量未定義的語(yǔ)法錯(cuò)誤。因此,我們還要注意若替換字符串中含有其他字符,一般需要在程序中定義,否則編譯時(shí)會(huì)出現(xiàn)標(biāo)識(shí)符(變量)未定義的錯(cuò)誤。這樣做的原因在于預(yù)處理器不能理解C語(yǔ)言,預(yù)處理時(shí)不檢查語(yǔ)法,不分配內(nèi)存空間,僅作簡(jiǎn)單字符串置換。源程序只有在進(jìn)行編譯時(shí)才作語(yǔ)法
29、檢查。,1.無(wú)參宏定義,例7-17 #define PI 3.14 #define ADDPI (PI+1) #define TWO_ADDPI (2*ADDPI),如有以下語(yǔ)句: x=TWO_ADDPI/2 ;,把x=TWO_ADDPI/2替換為x=(2*ADDPI)/2 ;,把x=(2*ADDPI)/2 替換為x=(2*(PI+1)/2;,把x=(2*(PI+1)/2 替換為x=(2*(3.14+1)/2;,1.無(wú)參宏定義,例7-18 #define PI 3.14 #define ADDPI PI+1 #define TWO_ADDPI 2*ADDPI,如有以下語(yǔ)句: x=TWO_ADD
30、PI/2 ;,把x=TWO_ADDPI/2替換為x=2*ADDPI/2 ;,把x=2*ADDPI/2 替換為x=2*PI+1/2;,把x=2*PI+1/2 替換為x=2*3.14+1/2;,1.無(wú)參宏定義,1. 無(wú)參宏定義,使用無(wú)參數(shù)宏定義還有以下幾點(diǎn)說(shuō)明:,宏名一般習(xí)慣用大寫字母表示,以與變量名區(qū)別。但這并非規(guī)定,也可用小寫字母。 使用宏名代替一個(gè)字符串,可以減少程序中重復(fù)書寫某些字符串的工作量。 宏定義是用宏名代替一個(gè)字符串,也就是作簡(jiǎn)單的置換,不作語(yǔ)法檢查。 宏定義不是C語(yǔ)句,不必在行末加分號(hào),如果加了分號(hào)則會(huì)連分號(hào)一起進(jìn)行置換。,1. 無(wú)參宏定義,(5) #define命令寫在文件的開
31、頭,函數(shù)之前,作為文件的一部分,在文件范圍內(nèi)有效。 (6)可以用#undef終止宏定義的作用域。例如: #define MIN 500 宏名MIN的有效范圍 #undef MIN /*此處取消了MIN的定義*/ (7)在進(jìn)行宏定義時(shí),可以引用已定義的宏名,并層層替換。如例7-15。 (8) 對(duì)程序中用雙引號(hào)括起來(lái)的字符,即使與宏名相同,也不進(jìn)行替換。 (9)宏定義的替換文本通常在同一行中,如果替換文本超過(guò)一行,必須在該行的最后加上反斜杠“”,反斜杠表示替換文本繼續(xù)到下一行。,無(wú)參數(shù)宏用于定義符號(hào)來(lái)代替常量,C語(yǔ)言還允許用符號(hào)來(lái)定義操作。通過(guò)使用參數(shù),可以創(chuàng)建外形和作用都與函數(shù)相似的類函數(shù)宏。,
32、例7-19 用定義帶參數(shù)宏來(lái)改寫例7-15的程序。 #define PI 3.14 #define C(r) 2*PI*r/*PI是已定義的宏名*/ void main() double radius,perimeter; printf(Enter The Radiusn); scanf(%lf, ,2. 帶參宏定義,本例宏定義括號(hào)內(nèi)的r稱為形式參數(shù),將宏調(diào)用時(shí)出現(xiàn)的變量名radius稱為實(shí)際參數(shù),形參和實(shí)參可以不止一個(gè)。 帶參數(shù)宏定義的一般形式為: #define 宏名(形參表) 替換文本 帶參宏調(diào)用的一般形式為: 宏名(實(shí)參表) 帶參宏定義的宏展開步驟可以歸納為下面兩步: 自左向右依次將替
33、換文本中形參字符用相應(yīng)位置上的實(shí)參字符來(lái)替換; 在程序中出現(xiàn)宏調(diào)用的位置進(jìn)行宏展開,這一步與無(wú)參宏定義的宏代換相同。,2. 帶參宏定義,說(shuō)明:,(1)對(duì)帶參的宏展開只是將語(yǔ)句中的宏名后面的括號(hào)內(nèi)的實(shí)參字符串代替#define命令行中的形參。 (2)在宏定義時(shí),在宏名與帶參的括號(hào)之間不應(yīng)加空格,否則將空格以后的字符串都作為代替字符串的一部分。 (3)定義宏時(shí)最好用括號(hào)括起來(lái)。如:#define square(n) n*n, 調(diào)用時(shí)s=square(a+1),則變成了s=a+1*a+1,與預(yù)期效果不同。,2. 帶參宏定義,2 帶參數(shù)的宏定義,【例7-21】分析下面程序運(yùn)行后的輸出結(jié)果。 #defi
34、ne MUL(a,b) (a)*(b) main( ) printf(%dn, MUL(10-5,5+1)/2); ,分兩次替換: MUL(10-5,5+1) 用(a)*(b) 替換。 用10-5替換a,用5+1替換b 。 printf語(yǔ)句被展開為: printf(%dn,(10-5)*(5+1)/2);,程序輸出結(jié)果:15,2 帶參數(shù)的宏定義,【例7.22】分析下面程序運(yùn)行后的輸出結(jié)果。 #define MA(x) x*(x-1) main( ) int a=1,b=2; printf(%dn, MA(1+a+b); ,分兩次替換: MA(1+a+b) 用x*(x-1) 替換。 用1+a+b
35、替換x。 printf語(yǔ)句被展開為: printf(%dn, 1+a+b*(1+a+b-1);,特別注意: 由于替換文本中的x沒(méi)有用括號(hào)括起,因此,1+a+b也不能用括號(hào)括起。,程序輸出結(jié)果:8,7.7.2 文件包含命令 #include,所謂“文件包含”,是指一個(gè)原文件可以將另外一個(gè)原文件的所有內(nèi)容包含進(jìn)來(lái)。其使用格式為: #include “文件名” 或:#include 例如,在前面我們已多次用此命令包含過(guò)庫(kù)函數(shù)的頭文件: #include “stdio.h” /* 包含標(biāo)準(zhǔn)輸入輸出頭文件*/ #include “math.h” /* 包含數(shù)學(xué)函數(shù)頭文件*/ #include “stri
36、ng.h” /* 包含字符串處理函數(shù)頭文件*/ 預(yù)處理器發(fā)現(xiàn)#include命令后,就會(huì)尋找后跟的文件名,并把這個(gè)文件的內(nèi)容替換源代碼文件中的這一行#include命令,從而把指定的文件和當(dāng)前的源程序文件連成一個(gè)源文件,再對(duì)合并后的文件進(jìn)行編譯。,例7-23 修改例7-15求圓周長(zhǎng)的程序成為兩個(gè)文件。 文件一:文件名為mydef.h;文件內(nèi)容如下: #define PI 3.14 #define C(r) 2*PI*r 文件二:文件名為perimeter.c;文件內(nèi)容如下: #include #include mydef.h void main() double radius,perimete
37、r; printf(Enter The Radiusn); scanf(%lf, ,此處宏展開為 perimeter=2*3.14*radius;,7.7.2 文件包含命令 #include,例7.24 下面程序由兩個(gè)源程序文件14.h和14.c組成,程序編譯運(yùn)行后的結(jié)果是。 14.H的源程序?yàn)椋?#define N 10 #define f2(x) (x*N) 14.C的源程序?yàn)椋?#include #define M 8 #define f(x) (x)*M) #include “14.h” main() int i,j; i=f(1+1);j=f2(1+1); printf(“%d %dn,i,j); ,f(1+1)展開為: (1+1)*8),f2(1+1)展開為: (1+1*10),7.7.2 文件包含命令 #include,(1)一個(gè)#include命令只能指定
溫馨提示
- 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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 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年中職植物保護(hù)(農(nóng)藥殘留檢測(cè))試題及答案
- 2025年中職(大數(shù)據(jù)與會(huì)計(jì))財(cái)務(wù)管理基礎(chǔ)試題及答案
- 2025年中職(畜牧獸醫(yī))動(dòng)物防疫階段測(cè)試題及答案
- 2025年高職測(cè)繪與地理信息技術(shù)(測(cè)繪地理信息)試題及答案
- 2024指揮中心建設(shè)白皮書
- 2026廣東廣州市白云區(qū)人民政府棠景街道辦事處第一次招聘政府雇員9人備考題庫(kù)及答案詳解一套
- 2026中國(guó)科學(xué)院高能物理研究所黨委辦公室主任崗位招聘1人備考題庫(kù)及1套參考答案詳解
- 2025年鐵嶺市事業(yè)單位公開招聘動(dòng)物檢疫崗位工作人員77人備考題庫(kù)及參考答案詳解1套
- 2026中國(guó)科學(xué)院長(zhǎng)春光學(xué)精密機(jī)械與物理研究所動(dòng)態(tài)成像室學(xué)術(shù)秘書招聘1人備考題庫(kù)(吉林)及答案詳解1套
- 2026河南鄭州軌道工程職業(yè)學(xué)院寒假教師與輔導(dǎo)員招聘76人備考題庫(kù)有完整答案詳解
- 河道治理、拓寬工程 投標(biāo)方案(技術(shù)方案)
- 政治審查表(模板)
- 《最奇妙的蛋》完整版
- 三年級(jí)科學(xué)上冊(cè)蘇教版教學(xué)工作總結(jié)共3篇(蘇教版三年級(jí)科學(xué)上冊(cè)知識(shí)點(diǎn)整理)
- 種子室內(nèi)檢驗(yàn)技術(shù)-種子純度鑒定(種子質(zhì)量檢測(cè)技術(shù)課件)
- SEMI S1-1107原版完整文檔
- 心電監(jiān)測(cè)技術(shù)操作考核評(píng)分標(biāo)準(zhǔn)
- 2023年中級(jí)財(cái)務(wù)會(huì)計(jì)各章作業(yè)練習(xí)題
- 金屬罐三片罐成型方法與罐型
- 大疆植保無(wú)人機(jī)考試試題及答案
- 《LED顯示屏基礎(chǔ)知識(shí)培訓(xùn)》
評(píng)論
0/150
提交評(píng)論