




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、 The C Programming Language Chapter 6 Function第第6章章 函數(shù)函數(shù) 函數(shù)是C語言程序的基本模塊,由于采用了函數(shù)模塊式的結構,C語言易于實現(xiàn)結構化程序設計,使程序的結構清晰、減少重復編寫程序的工作量、提高程序的可讀性和可維護性。函數(shù)的定義與調(diào)用函數(shù)間的數(shù)據(jù)傳遞方法函數(shù)的遞歸調(diào)用變量的作用域和存儲類型編譯預處理命令 The C Programming Language Chapter 6 Function6.1 函數(shù)概述函數(shù)概述q 如果軟件可劃分為可獨立命名和編程的部件,則每個部件稱為一個模塊。q 模塊化就是把系統(tǒng)劃分成若干個模塊,每個模塊完成一個子功
2、能,把這些模塊集中起來組成一個整體,從而完成指定的功能,滿足問題的要求。圖書采編圖書采編讀者管理讀者管理圖書流通圖書流通圖書查詢圖書查詢輸入圖書信息輸入圖書信息借書借書還書還書圖書管理系統(tǒng)圖書管理系統(tǒng) The C Programming Language Chapter 6 Function6.1.2 函數(shù)的概念函數(shù)的概念q根據(jù)模塊化設計的原則,一個較大的程序一般應分為若干個程序模塊,每一個模塊用于實現(xiàn)一個特定的功能。q在不同的程序設計語言中,模塊實現(xiàn)的方式有所不同。在C語言中,模塊用函數(shù)來實現(xiàn)。q 在C語言中,函數(shù)分為以下兩種:(1)標準庫函數(shù)標準庫函數(shù)這種函數(shù)用戶不必定義,但可直接使用。例
3、如scanf()、 printf()、fabs()、sprt()、exp()、sin()、cos()等都是C語言中常用的庫函數(shù)。(2)用戶自己定義的函數(shù)用戶自己定義的函數(shù)這種函數(shù)用以解決用戶的專門問題,一般由用戶自己編寫?!纠?.1】 從鍵盤輸入兩個正整數(shù)從鍵盤輸入兩個正整數(shù)m和和n,求,求m!/(m-n)!的值。的值。#include stdio.hvoid main() int m,n; int p(int); /*聲明本函數(shù)中要調(diào)用的函數(shù)p()是整型,有一個整型參數(shù)*/ scanf(%d,%d,&m,&n); if(m=n) printf(%d,p(m)/p(m-n);
4、else printf(mn!n); int p(int k) /*計算階乘的函數(shù) */ int s,i; s=1; for(i=1;i=n) printf(%d,p(m)/p(m-n); else printf(mn!n); /*函數(shù)p ()放在文件sp.c中*/int p(int k) int s,i; s=1; for(i=1;i=n) printf(%d,p(m)/p(m-n); else printf(mn!n); /*函數(shù)p ()放在文件sp1.c中*/int p(int k) int s,i; s=1; for(i=1;iy) m=x; else m=y; if (zm) m=z
5、; return m; The C Programming Language Chapter 6 Function6.2.1 函數(shù)定義函數(shù)定義q 函數(shù)定義的一般形式:函數(shù)類型 函數(shù)名 (形式參數(shù)表) /* 函數(shù)頭 */ 聲明部分 執(zhí)行語句 int max3 ( int x, int y, int z) int m; if (xy) m=x; else m=y; if (zm) m=z; return m; 數(shù)據(jù)類型說明數(shù)據(jù)名形參類型形參 The C Programming Language Chapter 6 Function一個函數(shù)(定義)由函數(shù)頭(函數(shù)首部)和函數(shù)體兩部分組成。q (1)函
6、數(shù)頭(首部):說明函數(shù)類型、函數(shù)名稱及參數(shù)。1)函數(shù)類型:函數(shù)返回值的數(shù)據(jù)類型,可以是基本數(shù)據(jù)類型也可以是構造類型。如果省略則默認為int類型,如果不返回值,則定義為void類型。2)函數(shù)名:給函數(shù)取的名字,以后用這個名字調(diào)用。函數(shù)名由用戶命名,命名規(guī)則與標識符相同。3)函數(shù)名后面是形式參數(shù)表,也可以沒有參數(shù),但“( )”號不能省略,這是格式的規(guī)定。形式參數(shù)表說明形式參數(shù)的類型和形式參數(shù)的名稱,各個形式參數(shù)之間用“,”分隔。q (2)函數(shù)體:函數(shù)頭下方用一對括起來的部分。如果函數(shù)體內(nèi)有多個,最外層是函數(shù)體的范圍。函數(shù)體一般包括聲明部分和執(zhí)行部分。1)聲明部分:定義本函數(shù)所使用的變量和進行有關聲
7、明(如函數(shù)聲明)。2)執(zhí)行部分:程序段,即由若干條語句組成的命令序列(可以在其中調(diào)用其他函數(shù))。q 注意:函數(shù)不能單獨運行,函數(shù)可以被主函數(shù)或其他函數(shù)調(diào)用,也可以調(diào)用其他函數(shù),但是不能調(diào)用主函數(shù)。 The C Programming Language Chapter 6 Function6.2.2 函數(shù)的參數(shù)和返回值函數(shù)的參數(shù)和返回值q 函數(shù)的參數(shù)分為形式參數(shù)和實際參數(shù)兩種。形式參數(shù)(形參):函數(shù)定義時設定的參數(shù)。實際參數(shù)(實參):調(diào)用函數(shù)時所使用的實際的參數(shù)。q 形參和實參的功能是進行數(shù)據(jù)傳遞。q 發(fā)生函數(shù)調(diào)用時,主調(diào)函數(shù)把實參的值傳遞給被調(diào)函數(shù)的形參,從而實現(xiàn)主調(diào)函數(shù)向被調(diào)函數(shù)的數(shù)據(jù)傳遞。
8、q C語言可以從函數(shù)(被調(diào)用函數(shù))返回值給調(diào)用函數(shù)(這與數(shù)學函數(shù)相當類似)。q 在函數(shù)內(nèi)是通過return語句返回值的。q 使用return語句能夠返回一個值或不返回值(此時函數(shù)類型是void)。q return語句的格式為:return 表達式;或return(表達式); 說明:說明:(1)函數(shù)的類型就是返回值的類型,return語句中表達式的類型應該與函數(shù)類型一致。如果不一致,以函數(shù)類型為準(賦值轉化)。(2)函數(shù)類型省略,默認為int。(3)如果函數(shù)沒有返回值,函數(shù)類型應當說明為void(空類型)。 The C Programming Language Chapter 6 Functio
9、n6.2.3 函數(shù)的聲明函數(shù)的聲明q 函數(shù)定義的位置可以在調(diào)用它的函數(shù)之前,也可以在調(diào)用它的函數(shù)之后,甚至可位于其他的源程序模塊中。q 若函數(shù)定義位置在前,函數(shù)調(diào)用在后,不必聲明,編譯程序產(chǎn)生正確的調(diào)用格式。q 若函數(shù)定義在調(diào)用它的函數(shù)之后或者函數(shù)在其他源程序模塊中,且函數(shù)類型不是整型,這時,為了使編譯程序產(chǎn)生正確的調(diào)用格式,可以在函數(shù)使用前對函數(shù)進行聲明。q 函數(shù)聲明的格式為:函數(shù)類型 函數(shù)名(形式參數(shù)表); q .h文件內(nèi)許多都是函數(shù)聲明,當源程序要使用庫函數(shù)時,就應當包含相應的頭文件。 The C Programming Language Chapter 6 Function6.3 函數(shù)
10、的調(diào)用函數(shù)的調(diào)用q一個函數(shù)調(diào)用另一個函數(shù)稱為函數(shù)調(diào)用,其調(diào)用者稱為主調(diào)函數(shù),被調(diào)用者稱為被調(diào)函數(shù)。 The C Programming Language Chapter 6 Function6.3.1 調(diào)用函數(shù)的一般形式調(diào)用函數(shù)的一般形式qC語言中,函數(shù)調(diào)用的一般形式為:函數(shù)名(實參表列); q說明:(1)無參函數(shù)調(diào)用沒有參數(shù),但是“( )”不能省略,有參函數(shù)若包含多個參數(shù),各參數(shù)用“,”分隔,實參參數(shù)個數(shù)與形參參數(shù)個數(shù)相同,類型一致或賦值兼容。(2)函數(shù)調(diào)用可以出現(xiàn)的位置如下: 1)以單獨語句形式調(diào)用(注意后面要加一個分號,構成語句)。以語句形式調(diào)用的函數(shù)可以有返回值,也可以沒有返回值。2)
11、在表達式中調(diào)用(后面沒有分號)。在表達式中的函數(shù)調(diào)用必須有返回值。printf(max=%d,nmax);swap(x,y);puts(s);if (strcmp(s1,s2)0)/*函數(shù)調(diào)用strcmp()在關系表達式中。*/nmax=max(n1,n2,n3); /*函數(shù)調(diào)用max()在賦值表達式中,“;”是賦值表達式作為語句時加的,不是max函數(shù)調(diào)用的。*/fun1(fun2(); /*函數(shù)調(diào)用fun2()在函數(shù)調(diào)用表達式fun1()中。函數(shù)調(diào)用fun2()的返回值作為fun1的參數(shù)。*/調(diào)用函數(shù)時需要注意下列事項:被調(diào)用函數(shù)必須是已經(jīng)存在的函數(shù)(庫函數(shù)和用戶自定義函數(shù))。如調(diào)用庫函數(shù),
12、在文件的開頭必須使用#include命令將庫函數(shù)相應的頭文件包含進來。如調(diào)用用戶自定義函數(shù),在調(diào)用之前必須對其進行聲明。 一個函數(shù)調(diào)用另一個函數(shù)稱為函數(shù)調(diào)用,其調(diào)用者稱為主一個函數(shù)調(diào)用另一個函數(shù)稱為函數(shù)調(diào)用,其調(diào)用者稱為主調(diào)函數(shù),被調(diào)用者稱為被調(diào)函數(shù)。調(diào)函數(shù),被調(diào)用者稱為被調(diào)函數(shù)。 The C Programming Language Chapter 6 Function6.3.2 調(diào)用函數(shù)時數(shù)據(jù)的傳遞調(diào)用函數(shù)時數(shù)據(jù)的傳遞q在調(diào)用函數(shù)時,主調(diào)函數(shù)和被調(diào)函數(shù)之間有數(shù)據(jù)的傳遞實參傳遞給形參。q具體的傳遞方式有兩種:(1)值傳遞方式(傳值):將實參單向傳遞給形參的一種方式。(2)地址傳遞方式(傳址)
13、:將實參地址單向傳遞給形參的一種方式。 The C Programming Language Chapter 6 Function函數(shù)的調(diào)用函數(shù)的調(diào)用q 在傳值調(diào)用時,函數(shù)的形參和實參具有以下特點:(1)形參變量只有在被調(diào)用時才分配內(nèi)存單元,在調(diào)用結束時,即刻釋放所分配的內(nèi)存單元。因此,形參變量只有在函數(shù)內(nèi)部有效。函數(shù)調(diào)用結束返回主調(diào)函數(shù)后則不能再使用該形參變量。(2)實參可以是常量、變量、表達式、函數(shù)等,無論實參是何種類型的量,在進行函數(shù)調(diào)用時,它們都必須具有確定的值,以便把這些值傳遞給形參。因此應預先用賦值、輸入等辦法使實參獲得確定值。(3)實參和形參在數(shù)量上、類型上、順序上應嚴格一致,否
14、則會發(fā)生“類型不匹配”的錯誤。(4)函數(shù)調(diào)用中發(fā)生的數(shù)據(jù)傳遞是單向的。即只能把實參的值傳送給形參,而不能把形參的值傳遞給實參。nmax=max3(n1 , n2 ,n3)int max3(int x,int y,int z)實際參數(shù)形式參數(shù)傳遞過程 The C Programming Language Chapter 6 Function【例6.3】 定義函數(shù),求ni 1i 的值。#include stdio.hvoid main() int n; void s(int n); printf(請輸入n的值:n); scanf(%d,&n); s(n); printf(n=%dn,n);
15、void s(int n) int i; for (i=n-1;i=1;i-) n=n+i; printf(n=%dn,n);程序運行結果為程序運行結果為:n=100n=5050n=100 The C Programming Language Chapter 6 Function6.3.3 函數(shù)的嵌套調(diào)用函數(shù)的嵌套調(diào)用 C語言不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),也就是說,在調(diào)用一個函數(shù)的過程中,又調(diào)用另一個函數(shù)。 其執(zhí)行過程是:其執(zhí)行過程是:執(zhí)行main函數(shù)中調(diào)用a函數(shù)的語句時,即轉去執(zhí)行a函數(shù);在a函數(shù)中調(diào)用b函數(shù)時,又轉去執(zhí)行b函數(shù);b函數(shù)執(zhí)行完畢,返回a函數(shù)的斷點繼續(xù)執(zhí)行;a函數(shù)執(zhí)行完
16、畢,返回main函數(shù)的斷點繼續(xù)執(zhí)行。 main( )調(diào)用函數(shù)a結束a函數(shù)b函數(shù)調(diào)用函數(shù)b The C Programming Language Chapter 6 Function【例6.4】計算分析:分析:本題可編寫兩個函數(shù),一個是用來計算平方值的函數(shù)f1,另一個是用來計算階乘值的函數(shù)f2。主函數(shù)先調(diào)用f1計算出平方值,再在f1中以平方值為實參,調(diào)用 f2計算其階乘值,然后返回f1,再返回主函數(shù),在循環(huán)程序中計算累加和。#include stdio.hlong f1(int p) int k; long r; long f2(int q); k=p*p; r=f2(k); return r;
17、long f2(int q) long c=1; int i; for (i=1;i=q;i+) c=c*i; return c;void main() int i; long s=0; for (i=2;i1) 當n大于等于2的時候,欲求n的階乘,只要先求出n-l的階乘,把所得結果乘以n即為n的階乘。至于n-l的階乘是多少,在這一步可先不考慮,設它為p。則:n!=np 接下來求p=(n-l)!,再把它進行分解。它等于n-l去乘n-2的階乘,即p= (n-l)(n-2)!,設(n-2)!=q,則p=(n-l)q。接下來的問題是再去求q。按照上述方法繼續(xù)類似的操作,問題一步步地化簡,最終一定能達
18、到求1的階乘的地步,這時就稱達到了邊界條件,可以直接求解了。#include stdio.hlong ff(int n) long f; if (n=0|n=1) f=1; else f=ff(n-1)*n; return(f);void main() int n; long y; printf(請輸入n的值:n); scanf(%d,&n); if(n0) printf(ny) z=x; else z=y; return z;void main() extern int a,b; /* 全局變量聲明 */ printf(請輸入a,b的值:n); scanf(%d,%d,&a,
19、&b); printf(max=%dn,mymax(a,b); int a,b; /* 全局變量定義 */ The C Programming Language Chapter 6 Function全局變量全局變量q (2)在同一個源文件中,允許全局變量與局部變量同名。在局部變量的作用范圍內(nèi),全局變量被“屏蔽”,即它不起作用。【例6.10】 全局變量與局部變量同名。#include stdio.hint a=3,b=5; /* a,b為全局變量 */int mymax(int a,int b) /* a,b,c為局部變量 */ int c; c=ab?a:b; return(c);vo
20、id main() int a=8; /* a為局部變量 */ printf(%dn,mymax(a,b);運行結果為:8 The C Programming Language Chapter 6 Function全局變量全局變量q (3)如果沒有全局變量,函數(shù)只能通過參數(shù)與外界發(fā)生數(shù)據(jù)聯(lián)系,有了全局變量以后,增加了一條與外界傳遞數(shù)據(jù)的渠道。這種方法有利有弊?!纠?.11】 全局變量的副作用。#include stdio.hint i;void main() void prt(); for (i=0;i5;i+) prt();void prt() for (i=0;i5;i+) printf(
21、%c,*); printf(n);運行結果為:* The C Programming Language Chapter 6 Function6.5 變量的存儲屬性變量的存儲屬性q1.用戶程序的存儲分配用戶程序的存儲分配動態(tài)存儲區(qū)動態(tài)存儲區(qū) 動態(tài)存儲區(qū)是在函數(shù)調(diào)用過程中進行動態(tài)分配的動態(tài)存儲區(qū)是在函數(shù)調(diào)用過程中進行動態(tài)分配的靜態(tài)存儲區(qū)靜態(tài)存儲區(qū) 靜態(tài)存儲區(qū)是在程序開始執(zhí)行時就分配的固定存儲單元,如全局變靜態(tài)存儲區(qū)是在程序開始執(zhí)行時就分配的固定存儲單元,如全局變量量程序區(qū)程序區(qū) 程序區(qū)用于存放程序;程序區(qū)用于存放程序;q 2.變量的存儲類型變量的存儲類型 每一個變量和函數(shù)都有兩個屬性:操作屬性和存
22、儲屬性。數(shù)據(jù)類型是變量的操作屬性,變量的存儲屬性包括變量的存儲器類型、變量的生存期和變量的作用域。從變量值存在的作用時間(即生存期)角度來分,可以分為:永久存儲 采用永久存儲的變量在編譯時分配存儲單元,程序執(zhí)行開始后這種變量即被創(chuàng)建,程序執(zhí)行結束才被撤銷。這種變量的生存期為程序執(zhí)行的整個過程,在該過程中占有固定的存儲空間。動態(tài)存儲 而采用動態(tài)存儲的變量只在程序執(zhí)行的某一段時間內(nèi)存在。 The C Programming Language Chapter 6 Function6.5.1 自動變量(自動變量(auto) q自動變量為局部變量,用說明符auto進行說明。q如下形式進行說明:auto
23、數(shù)據(jù)類型 變量名= 初值表達式,;其中,方括號表示可省略。如果省略auto,系統(tǒng)隱含認為此變量為auto。過去使用的變量,實際上都是auto類型的變量。 The C Programming Language Chapter 6 Function自動變量自動變量q 說明:q (1)自動變量是局部變量。自動變量的作用域僅限于定義該變量的個體內(nèi)。在函數(shù)中定義的自動變量,只在該函數(shù)內(nèi)有效。在復合語句中定義的自動變量只在該復合語句中有效。q (2)自動變量屬于動態(tài)存儲,只有在使用它,即定義該變量的函數(shù)被調(diào)用時才給它分配存儲單元,開始它的生存期。函數(shù)調(diào)用結束,釋放存儲單元,結束生存期。因此函數(shù)調(diào)用結束之后
24、,自動變量的值不能保留。在復合語句中定義的自動變量,在退出復合語句后也不能再使用,否則將引起錯誤。q (3)由于自動變量的作用域和生存期都局限于定義它的個體內(nèi)(函數(shù)或復合語句內(nèi)),因此不同的個體中允許使用同名的變量而不會混淆。即使在函數(shù)內(nèi)定義的自動變量也可與該函數(shù)內(nèi)部的復合語句中定義的自動變量同名?!纠?.12】 有下列函數(shù):#include stdio.hvoid main()/* */ int x=1; /* */ void prt(); int x=3; prt(); printf(2nd x=%dn,x); /* */ printf(1st x=%dn,x);/* */void prt
25、()/* */ int x=5; printf(3th x=%dn,x);/* */在main函數(shù)中定義的變量x在到范圍內(nèi)有效,可以被引用。當程序執(zhí)行到時,又定義了一個x變量,它的作用域為該復合語句內(nèi),即到。在到復合語句內(nèi)輸出的x的值是3,而main函數(shù)中最后一個語句輸出x的值為1。prt函數(shù)中定義的變量x只在該函數(shù)中有效,它與前面兩個x互不相干。程序運行結果如下:程序運行結果如下:3th x=52nd x=31st x=1 The C Programming Language Chapter 6 Functionq(4)在對自動變量賦值之前,它的值是不確定的?!纠?.13】 使用未賦初值的自
26、動變量。#include stdio.hvoid main() int i; printf(i=%dn,i);運行結果如下:運行結果如下:i=62 The C Programming Language Chapter 6 Function6.5.2 寄存器變量(寄存器變量(register) q 寄存器變量具有與自動變量完全相同的性質(zhì)。q 為了提高效率,C語言允許將局部變量的值放在CPU的寄存器中,這種變量叫“寄存器變量”,用關鍵字register聲明?!纠?.14】 使用寄存器變量。#include stdio.hint fac(int n) register int i,f=1; /* 定
27、義寄存器變量 */ for (i=1;i=n;i+) f=f*i; return(f);void main() int i; for (i=0;i=5;i+) printf(%d!=%dn,i,fac(i);說明:說明:(1)只有局部自動變量和形式參數(shù)可以作為寄存器變量。(2)一個計算機系統(tǒng)中的寄存器數(shù)目有限,不能定義任意多個寄存器變量。 The C Programming Language Chapter 6 Function6.5.3 靜態(tài)變量(靜態(tài)變量(static) q 有時希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結束后不消失而保留原值,這時就應該指定局部變量為“靜態(tài)局部變量”,用關鍵字st
28、atic進行聲明。q 靜態(tài)變量的定義采用下面的格式:static 數(shù)據(jù)類型 變量名= 初始化常量表達式,;q 說明:說明:(1)靜態(tài)變量的存儲空間在程序的整個運行期間是固定的。(2)靜態(tài)變量的初始化是在編譯時進行的。在定義時只能使用常量或常量表達式進行顯式初始化。未顯式初始化時,編譯時將把它們初始化為0(對int型)或0.0(對float型)。(3)在函數(shù)多次被調(diào)用的過程中,靜態(tài)局部變量的值具有可繼承性?!纠?.15】 考察靜態(tài)局部變量的值。#include stdio.hint f(int a) auto int b=0; static int c=3; /* 靜態(tài)變量 */ b=b+1;
29、c=c+1; return(a+b+c);void main() int a=2,i; for (i=0;iy?x:y; return(z);void main() extern a,b; printf(%dn,mymax(a,b);int a=13,b=-8; The C Programming Language Chapter 6 Functionq說明:說明:q (1)還可以將外部變量的作用域擴充到其他文件。這時在需要用到這些外部變量的文件中,對變量用extern作聲明即可。q (2)限定本文件的外部變量只在本文件中使用。如果有的外部變量只允許本文件使用而不允許其他文件使用,則可以在此外
30、部變量前加一個static,使其有限局部化,稱作靜態(tài)外部變量。 file1.c file2.cint x,y; extern int x,y;char ch; extern char ch; void main() f1() printf(%d,%dn,x,y); x=12; y=24; ch=a; f1(); printf(%c,ch); static int a=3,b=5;void main() void f1() void f() 全局局部或全局局部作用域永久存儲動態(tài)存儲生存期主存寄存器存儲位置externstaticautoregister存儲屬性 The C Programming
31、 Language Chapter 6 Function6.6 編譯預處理編譯預處理q 編譯預處理是在編譯前對源程序進行的一些預處理。q 預處理由編譯系統(tǒng)中的預處理程序按源程序中的預處理命令進行。q C語言的預處理命令均以“#”打頭,末尾不加分號,以區(qū)別于C語句。q 它們可以出現(xiàn)在程序中的任何位置,其作用域是自出現(xiàn)點到所在源程序的末尾。 The C Programming Language Chapter 6 Function6.6.1 宏定義宏定義q 在C語言源程序中允許用一個標識符來表示一個字符串,稱為“宏”。q 被定義為“宏”的標識符稱為“宏名”。q 在編譯預處理時,對程序中所有出現(xiàn)的“
32、宏名”,都用宏定義中的字符串去代換,這稱為“宏代換”或“宏展開”。q 宏定義是由源程序中的宏定義命令完成的,宏代換是由預處理程序自動完成的。q 在C語言中,“宏”分為有參數(shù)和無參數(shù)兩種。 The C Programming Language Chapter 6 Function宏定義宏定義q1無參宏定義q無參宏的宏名后不帶參數(shù)。其定義的一般形式為:#define 宏名 字符串其中,作為宏名的標識符習慣上用有意義且易理解的大寫字母來表示,“字符串”可以是常數(shù)、表達式或格式串等。宏定義一般寫在文件開頭函數(shù)體的外面,有效范圍是從定義宏命令之后到遇到終止宏定義命令#undef為止,否則其作用域?qū)⒁恢钡?/p>
33、源文件結束。例如:例如:#define PI 3.1415926 The C Programming Language Chapter 6 Functionq 對于宏定義還要說明以下幾點:q (1)宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單的代換,字符串中可以含任何字符,可以是常數(shù),也可以是表達式,預處理程序?qū)λ蛔魅魏螜z查。如有錯誤,只能在編譯已被宏展開后的源程序時發(fā)現(xiàn)。q (2)如果在一行中寫不下整個宏定義,需要用兩行或更多行來書寫時,只需在每行的最后一個字符的后面加上反斜桿“”,并在下一行的最開始接著寫即可。q (3)宏定義必須寫在函數(shù)之外,其作用域為
34、宏定義命令起到源程序結束。如要終止其作用域可使用#undef命令。q (4)宏名在源程序中若用引號括起來,則預處理程序不對其作宏代換。q (5)宏定義允許嵌套,在宏定義的字符串中可以使用已經(jīng)定義的宏名。在宏展開時由預處理程序?qū)訉哟鷵Q。#define PI 3.14159void main()#undef PIf1()表示PI只在main函數(shù)中有效,在f1中無效。printf(PI=,PI);在預處理時,將只對第二個PI進行代換,而對第一個雙引號中的PI,系統(tǒng)并不對其作代換。執(zhí)行該語句會輸出:PI=3.1415926#define R 5.6#define PI 3.1415926#define
35、 L 2*PI*R#define S PI*R*R /* PI,R是已定義的宏名*/在宏展開時,編譯器會把程序中的R用5.6來代換,把PI用3.1415926來代換,而將S用3.1415926*5.6*5.6來代換?!纠?.17】 已知半徑為5.0,計算以此為半徑的圓的周長和面積,以及圓球體的體積。#include stdio.h#define R 5.0#define PI 3.1415926#define S PI*R*R#define V 4.0/3.0*PI*R*R*Rvoid main() printf(L=%fnS=%fnV=%fn,L,S,V) ;程序運行結果如下:程序運行結果如
36、下:L=31.415926S=78.539815V=523.598767 The C Programming Language Chapter 6 Functionq帶參宏定義 C語言允許宏帶有參數(shù)。在宏定義中的參數(shù)稱為形式參數(shù),在宏調(diào)用中的參數(shù)稱為實際參數(shù)。對帶參數(shù)的宏,在調(diào)用中,不僅要進行宏展開,而且要用實參去代換形參。q帶參宏定義的一般形式為:#define 宏名(形參表列) 字符串在字符串中含有各個形參。q帶參宏調(diào)用的一般形式為:宏名(實參表列);#define M(y) y*y+3*y /*宏定義*/k=M(5); /*宏調(diào)用*/ 在宏調(diào)用時,用實參5去代替形參y,經(jīng)預處理宏展開后的
37、語句為:k=5*5+3*5;宏展開后該語句為:宏展開后該語句為:mymax=(xy)?x:y;宏定義宏定義【例6.18】 求兩數(shù)中較大者。#include stdio.h#define MAX(a,b) (ab)?a:bvoid main() int x,y,mymax; printf(請輸入x,y的值:n); scanf(%d,%d,&x,&y); mymax=MAX(x,y); printf(max=%dn,mymax); The C Programming Language Chapter 6 Function說明:說明: (1)帶參宏定義中,宏名和形參表之間不能有空格出
38、現(xiàn)。#define MAX (a,b) (ab)?a:b將被認為是無參宏定義,宏名MAX代表字符串 (a,b) (ab)?a:b。宏展開時,宏調(diào)用語句:mymax=MAX(x,y);將變?yōu)椋簃ymax=(a,b)(ab)?a:b(x,y);(2)在帶參宏定義中,形式參數(shù)不分配內(nèi)存單元,因此不必作類型定義。而宏調(diào)用中的實參有具體的值,要用它們?nèi)ゴ鷵Q形參,因此必須作類型說明。(3)在宏定義中的形參是標識符,而宏調(diào)用中的實參可以是表達式。#define SQ(y) (y)*(y) sq=SQ(a+1); 得到如下語句:得到如下語句:sq=(a+1)*(a+1);(4)在宏定義中,字符串內(nèi)的形參通常要
39、用括號括起來以避免出錯。 33) 1()(xxxf【例6.19】計算下列函數(shù)值:計算函數(shù)值的C程序?qū)懗扇缦拢?include #define F(x) x*x*xmain() double f,x;printf(input x:);scanf(%lf,&x);f=F(x)+F(x+1);printf(f=%fn,f);33) 1()(xxxf將上述程序改為:#include #define F(x) (x)*(x)*(x)main() double f,x;printf(input x:);scanf(%lf,&x);f=F(x)+F(x+1);printf(f=%fn,f);
40、經(jīng)編譯預處理后等價于下面的程序:#include main() double f,x;printf(input x:);scanf(%lf,&x);f=(x)*(x)*(x)+(x+1)*(x+1)*(x+1);printf(f=%fn,f); The C Programming Language Chapter 6 Function(5)帶參的宏和帶參函數(shù)很相似,但有本質(zhì)上的不同,除上面已講到的幾點外,把同一表達式用函數(shù)處理與用宏處理兩者的結果有可能是不同的?!纠?.21】 用用戶自定義函數(shù)求n2。#include stdio.hvoid main() int i=1; while
41、(i=5) printf(%dn,sq(i+);int sq(int y) return(y)*(y);運行結果為:1491625【例6.22】 用宏定義函數(shù)求n2。#include stdio.h#define SQ(y) (y)*(y)void main() int i=1; while (i=5) printf(%dn,SQ(i+);運行結果為:21230 The C Programming Language Chapter 6 Function6.6.2 文件包含文件包含q 文件包含命令行的一般形式為:#include 文件名文件包含命令的功能是把指定的文件插入該命令行位置取代該命令行
42、,從而把指定的文件和當前的源程序文件連成一個源文件。q 說明:(1)文件包含命令中的文件名可以用雙引號括起來,也可以用尖括號括起來。 (2)一個include命令只能指定一個被包含文件,若有多個文件要包含,則需用多個include命令。(3)文件包含允許嵌套,即在一個被包含的文件中又可以包含另一個文件?!纠?.23】 將求圓球體體積的函數(shù)作為頭文件,并在其他程序中使用該函數(shù)。將以下程序源代碼保存到文件sphere.h中:#define PI 3.1415926float volumn(float r) float v; v=4.0/3.0*PI*r*r*r; return v;程序如下:#in
43、clude sphere.h#include stdio.hvoid main() float r,v; printf(r=); scanf(%f,&r); v=volumn(r); printf(PI=%fnvolumn=%fn,PI,v);運行結果為:運行結果為:r=3PI=3.1415926volumn=113.097336 The C Programming Language Chapter 6 Function6.6.3 條件編譯條件編譯q預處理程序提供了條件編譯的功能。q可以按不同的條件去編譯不同的程序部分,因而產(chǎn)生不同的目標代碼文件。 The C Programming
44、Language Chapter 6 Function條件編譯條件編譯q(1)第一種形式:#ifdef 標識符 程序段1#else 程序段2#endif其中,標識符是指已用宏命令#define定義的宏名,而程序段可以是編譯預處理命令行,也可以是C語言組。它的功能是:如果標識符已被 #define命令定義過則對程序段1進行編譯;否則對程序段2進行編譯?!纠?.24】 條件編譯命令的使用。#include stdio.h#define REAL floatvoid main() #ifdef REAL REAL a; printf(輸入一個實數(shù):); scanf(%f,&a); print
45、f(這個實數(shù)是:%fn,a); #else float a; printf(輸入一個單精度浮點數(shù):); scanf(%f,&a); printf(這個單精度浮點數(shù)是:%fn,a); #endif 運行結果為:運行結果為:輸入一個實數(shù):4.56這個實數(shù)是:4.560000經(jīng)過編譯預處理后,上述程序變成如下形式:void main() REAL a; printf(輸入一個實數(shù):); scanf(%f,&a); printf(這個實數(shù)是:%fn,a); The C Programming Language Chapter 6 Function條件編譯條件編譯q(2)第二種形式:#i
46、fndef 標識符 程序段1 #else 程序段2 #endifq它的功能是:如果標識符未被#define命令定義過則對程序段1進行編譯,否則對程序段2進行編譯。 The C Programming Language Chapter 6 Function條件編譯條件編譯q(3)第三種形式:#if表達式 程序段1#else 程序段2#endifq它的功能是:如表達式的值為“真”(非0),則對程序段1進行編譯,否則對程序段2進行編譯。q因此可以使程序在不同條件下完成不同的功能。 The C Programming Language Chapter 6 Function6.7應用舉例應用舉例【例6.
47、25】編寫一個程序完成“菜單”功能:提供三種選擇途徑:其一是秋水仙花數(shù)(所謂水仙花數(shù)是指3為整數(shù)的各位上數(shù)字的立方和等于該整數(shù)本身。例如153就是一個水仙花數(shù):153=13+53+33)。找出100999之間的水仙花數(shù)。其二是查找素數(shù),找出2n之間的素數(shù)。其三是求Faibonacci數(shù)列前n項的值。#include#include#includevoid main() int m,xz;void narcissus(); /*聲明求水仙花數(shù)的函數(shù)*/void prime(); /*聲明查找素數(shù)的函數(shù)*/void faibonacci(); /*聲明求Faibonacci數(shù)列前n項的函數(shù)*/sy
48、stem(cls);m=0;while(m=0) printf(n); printf(1 求水仙花數(shù)n); printf(2 查找素數(shù)n); printf(3 求Faibonacci數(shù)列前n項n); printf(輸入了非法的數(shù)據(jù),退出!n); printf(n); printf(請輸入13中的一個數(shù)字:); scanf(%d,&xz); switch(xz) /*用開關語句switch進行選擇*/ case 1:narcissus();break; /*若選擇1,求水仙花數(shù)*/ case 2:prime();break; /*若選擇2,求素數(shù)*/ case 3:faibonacci(
49、);break;/*若選擇3,求Faibonacci數(shù)列前n項的值*/ default:m=1; /*若選擇其他講m置1,循環(huán)結束*/ void narcissus() /*此函數(shù)用于求水仙花數(shù)*/ int k,a,b,c,d;for (k=100;k1000;k+) a=k/100; b=k/100/10; c=k%10; d=a*a*a+b*b*b+c*c*c; if(d=k) printf(%dn,k); void prime() /*此函數(shù)用于查找素數(shù)*/ int i,j,k,n,m=0;printf(請輸入一個數(shù):);scanf(%d,&n);for(i=2;i=n;i+)
50、j=sqrt(i); for(k=2;kj) m+; printf(%3d,i); if(m%10=0) printf(n); void faibonacci() /*此函數(shù)用于求Faibonacci數(shù)列前n項的值*/ long int f,f1=1,f2=1; int i,n; printf(請輸入n: ); scanf(%d,&n); printf(%8ld%8ld,f1,f2); for(i=3;i=n;i+) f=f1+f2; f1=f2; /*存放第一個數(shù)*/ f2=f; /*存放第二個數(shù)*/ printf (%8ld,f); if(i%6=0) /*為打印整齊,一行打印6個
51、數(shù),滿6個數(shù)換行*/ printf(n); The C Programming Language Chapter 6 Function【例6.26】 編制程序,解決萬年歷問題。整個程序的功能概括如下:(1)輸入一個年份,輸出全年的日歷。(2)輸入年份、月份,輸出該月的日歷。(3)輸入年月日,計算出這天是星期幾。某一年是閏年的條件為:該年份能被4整除但不能被100整除,或者能被400整除。根據(jù)這個條件,可以寫出判斷閏年的函數(shù)如下:int isleap(int year)return (year%4=0&year%100!=0|year%400=0);確定一年的第一天是星期幾的函數(shù)如下:i
52、nt day(int year) long a,b;if(year=2000) /*年份在2000年之前*/ a=2000-year; b=6-(a+a/4-a/100+a/400)%7; return b; else /*年份在2000年之后*/ a=year-2000; b=(a+(a-1)/4-(a-1)/100+(a-1)/400)%7; return b; 源程序如下:(1)首先建立頭文件wnl.h,如下所示:# include stdio.h# define D Sum Mon Tue Wed Thu Fri Satvoid print(int n) /*顯示n個空格*/ int
53、i;for(i=0;in;i+)printf( );int day (int year) /*確定年份year的第一天是星期幾*/long a,b;if(year=2000) /*年份在2000年之前*/ a=2000-year; b=6-(a+a/4-a/100+a/400)%7; return b; else /*年份在2000年之后*/ a=year-2000; b=(a+(a-1)/4-(a-1)/100+(a-1)/400)%7; return b; int isleap(int year) /*判斷閏年*/return (year%4=0&year%100!=0|year%
54、400=0); The C Programming Language Chapter 6 Function(2)顯示一年的日歷,定義文件year.c如下:void oneyear() int a13=0,31,28,31,30,31,30,31,31,30,31,30,31; /*每個月的天數(shù)*/int i,j,k,m,n,f1,f2,year,d;clrscr();printf (請輸入年份:n) ;scanf(%d,&year);printf (你所輸入的年份是:%dn,year);d=day(year); /*確定該年的第一天是星期幾,用變量d表示*/if (isleap(yea
55、r) a2+; /*如果是閏年則2月份的天數(shù)加1*/for(i=1;i=12;i+=2)m=n=f1=f2=0;switch (i) /*顯示月份*/case 1 :printf(January 1);break;case 3 :printf(March 3);break;case 5 :printf(May 5);break;case 7 :printf(July 7);break;case 9 :printf(September 9);break;case 11:printf(November 11);break; print (21);switch (i+1) /*顯示月份*/case
56、2 :printf(February 2);break;case 4 :printf(April 4);break;case 6 :printf(June 6);break;case 8 :printf(August 8);break;case 10:printf(October 10);break;case 12:printf(December 12);break;printf(n);printf(D);print(6);printf(D);printf(n); /*顯示日歷的表頭*/for(j=0;j6;j+) /*顯示每一天的日期*/if(j=0) /*第一行*/print(d*4) ;
57、for(k=0;k7-d;k+)printf(%4d,+m);print(6);d=d+ai%7;d%=7; /*確定下個月的第一天是星期幾*/print (d*4);for(k=0;k7-d;k+)printf(%4d,+n);printf(n);else /*其他行*/for(k=0;k7;k+) if (mai) printf(%4d,+m); print(4); if(m=ai) f1=1; /*該月顯示完畢*/ print(6);for(k=0;k7;k+)if(nai+1) printf(%4d,+n); else print(4); if(n=ai+1) f2=1; /*該月顯示
58、完畢*/ printf(n);if(f1&f2) break; /*兩個月顯示完畢*/d=d+ai+1%7;d%=7; /*確定下個月的第一天是星期幾*/ printf ();for(k=0;k27;k+) printf(=); /*顯示分隔符*/ print(7); for(k=0;k27;k+) printf(=); /*顯示分隔符*/ printf(n); if(i=5) getch(); clrscr();getch(); The C Programming Language Chapter 6 Function(3)顯示每個月的日歷,定義文件month.c如下:void on
59、emonth()int a13=0,31,28,31,30,31,30,31,31,30,31,30,31; /*每個月的天數(shù)*/int i,j,k,m,flag,year,month,d;clrscr(); /*清屏*/printf(請你輸入年份和月份);scanf(%d%d,&year,&month); /*輸入年份和月份*/printf(nThe calendar of %dn,year); /*輸出表頭*/switch(month) case 1 :printf(January 1);break; case 2 :printf(February 2);break;case 3 :printf(March 3);break;case 4 :printf(April 4);break;case 5 :printf(May 5);break;case 6 :printf(June 6);break;case 7 :printf(July 7);break;case 8 :printf(August 8);break;case 9 :printf(September 9);break;case 10 :printf(October 10
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 高效率的中級社會工作者試題及答案
- 大專生運營面試題及答案
- 中級社會工作者工作評估方法試題及答案
- 重點復習內(nèi)容初級社會工作者試題及答案
- 發(fā)票知識競賽試題及答案
- 安徽會考試題及答案
- 熒光pcr管理制度
- 汽車電池車間管理制度
- 企業(yè)理財管理制度
- 村級集體組織管理制度
- 九年級上冊《道德與法治》教案
- 2025陜西建工控股集團限公司招聘12人易考易錯模擬試題(共500題)試卷后附參考答案
- 配電室巡檢培訓
- 混凝土工程施工質(zhì)量控制培訓材料
- 《工程勘察設計收費標準》(2002年修訂本)
- 裝飾圖案知到智慧樹章節(jié)測試課后答案2024年秋齊魯工業(yè)大學
- 2024草原承包合同書
- 鋼結構閣樓合同范例
- 廣東惠州人文介紹
- 初三中考英語高頻詞匯單選題100道及答案解析
- 全國扶貧開發(fā)信息系統(tǒng)業(yè)務管理子系統(tǒng)用戶操作手冊20171110(升級版)
評論
0/150
提交評論