大學(xué)C語言程序設(shè)計第二版(電子工業(yè))第6章_第1頁
大學(xué)C語言程序設(shè)計第二版(電子工業(yè))第6章_第2頁
大學(xué)C語言程序設(shè)計第二版(電子工業(yè))第6章_第3頁
大學(xué)C語言程序設(shè)計第二版(電子工業(yè))第6章_第4頁
大學(xué)C語言程序設(shè)計第二版(電子工業(yè))第6章_第5頁
已閱讀5頁,還剩85頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第6章函數(shù)與編譯預(yù)處置6.1函數(shù)概述6.2函數(shù)的定義和闡明6.3函數(shù)的調(diào)用6.4函數(shù)的參數(shù)6.6變量的存儲類型6.7內(nèi)部函數(shù)和外部函數(shù)6.8編譯預(yù)處置命令6.5函數(shù)的嵌套調(diào)用與遞歸調(diào)用

6.1函數(shù)概述

★函數(shù)是封裝了一定功能的模塊

★C言語是函數(shù)驅(qū)動式言語〔一個源程序文件由一個或多個函數(shù)組成〕#include“stdio.h〞voidmain()//函數(shù)頭{inta=8;printf(“a=%d〞,a);}//函數(shù)體★一個C源程序必需有且只能有一個主函數(shù)main(

)。C程序總是從main(

)函數(shù)開場執(zhí)行,最后終了于main(

)函數(shù),其他函數(shù)是經(jīng)過main(

)直接或間接調(diào)用完成其功能的。#include<stdio.h>intadd(intx,inty){ints;s=x+y;returns;}main(){inta=1,b=2,c;c=add(a,b);printf("%d\n",c);}kj61一、函數(shù)定義二、函數(shù)聲明三、函數(shù)調(diào)用#include<stdio.h>main(){inta=1,b=2,c;intadd(intx,inty);c=add(a,b);printf("%d\n",c);}intadd(intx,inty){ints;s=x+y;returns;}函數(shù)概述〔1〕一個C程序由一個或多個源〔程序〕文件組成——可分別編寫、編譯和調(diào)試?!?〕一個源文件由一個或多個函數(shù)組成,可為多個C程序公用?!?〕C言語是以源文件為單位而不以函數(shù)為單位進(jìn)展編譯的?!?〕在C言語中,一切函數(shù)〔包括主函數(shù)main(

)〕都是平行的。一個函數(shù)的定義,可以放在程序中的恣意位置,主函數(shù)main(

)之前或之后。但在一個函數(shù)的函數(shù)體內(nèi),只能調(diào)用其他函數(shù),不能再定義另一個函數(shù),即不能嵌套定義?!?〕主函數(shù)名main是系統(tǒng)定義的,是運轉(zhuǎn)時首先被調(diào)用的函數(shù),它可以調(diào)用其他函數(shù),但不能被其他函數(shù)調(diào)用;其他函數(shù)間可以相互調(diào)用,也允許嵌套調(diào)用?!?〕從函數(shù)定義的角度看,函數(shù)可分為庫函數(shù)和用戶定義函數(shù)兩種。①庫函數(shù):由C系統(tǒng)提供,用戶無須定義,也不用在程序中進(jìn)展類型闡明,只需在程序前寫出包含有該函數(shù)原型的頭文件即可在程序中直接調(diào)用。在前面各章的例題中反復(fù)用到的printf(

)、scanf(

)、getchar(

)、putchar(

)、gets(

)、puts(

)等函數(shù)均在頭文件stdio.h中,sqrt(),fabs(),pow()等函數(shù)均在頭文件math.h中。②用戶定義函數(shù):由用戶按需求編寫的函數(shù)。對于用戶自定義函數(shù),不僅要在程序中定義函數(shù)本身,而且還必需在主調(diào)函數(shù)模塊中對該被調(diào)函數(shù)進(jìn)展類型闡明,然后才干運用?!?〕從主調(diào)函數(shù)和被調(diào)函數(shù)之間數(shù)據(jù)傳送角度看,函數(shù)又可分為無參函數(shù)和有參函數(shù)兩種。〔8〕C言語的函數(shù)兼有其他言語中的函數(shù)和過程兩種功能,從這個角度看,又可把函數(shù)分為有前往值函數(shù)和無前往值函數(shù)兩種。6.2.1函數(shù)定義C言語函數(shù)定義格式如下:[函數(shù)前往值的類型名]函數(shù)名([類型名方式參數(shù)1,類型名方式參數(shù)2,…])/*函數(shù)頭*/{[闡明部分;]/*函數(shù)體*/[語句部分;]}其中[]內(nèi)為可選項。留意:函數(shù)名、一對圓括號和花括號不能??!6.2函數(shù)的定義和闡明1.無參函數(shù)無參函數(shù)的普通方式函數(shù)前往值的類型名函數(shù)名(void){[闡明語句部分;][可執(zhí)行語句部分;]}例:構(gòu)造一個輸出一行〞*〞的函數(shù):voidprintstar(void){printf(“******************\n〞);}

kj622.有參函數(shù)例:編寫函數(shù)交換2個數(shù);kj63voidswap(inta,intb){inttemp;temp=a;a=b;b=temp;}

不能寫成:voidswap(inta,b){inttemp;temp=a;a=b;b=temp;}函數(shù)前往值類型函數(shù)名參數(shù)類型闡明及參數(shù)列表6.2.2函數(shù)的前往值函數(shù)分為有前往值函數(shù)和無前往值函數(shù)。return語句的格式:return(表達(dá)式);或return表達(dá)式;或return;功能:1、把return后面“表達(dá)式〞的值帶給調(diào)用函數(shù);2、把控制轉(zhuǎn)向調(diào)用函數(shù);格式return;只需功能2例:編寫函數(shù),前往2個整數(shù)的最大公約數(shù)?!草氜D(zhuǎn)相除法〕kj64intf(intx,inty){intr,t;if(x<y){t=x;x=y;y=t;} while((r=x%y)!=0) {x=y;y=r;}returny;}

留意:(1)聲明為void型的函數(shù)中不能包括帶值的return語句;主函數(shù)體內(nèi)普通不用return語句。(2)當(dāng)函數(shù)沒有return語句時,以終了函數(shù)的大括號}作為前往點。但這時并不闡明函數(shù)沒有前往值,這時的前往值是系統(tǒng)給的不確定值。(3)在同一函數(shù)內(nèi),可根據(jù)需求在多處出現(xiàn)return語句,但函數(shù)第一次遇到return時就立刻停頓執(zhí)行,并前往到主調(diào)函數(shù);(4)return語句中前往值表達(dá)式的類型應(yīng)該和函數(shù)類型一致。假設(shè)不一致,那么以函數(shù)類型為準(zhǔn),由系統(tǒng)自動進(jìn)展轉(zhuǎn)換。假設(shè)缺省函數(shù)類型,那么系一致概按int類型處置。intf(chars1,chars2){if(s1==s2)return1; return0;}kj65

例:計算兩數(shù)之和#include<stdio.h>doubleadd(doublex,doubley){doubles;s=x+y;returns;}main(){doublea,b,c;a=10.5;b=20.3;c=add(a,b);printf("%lf",add(a,b));add(a,b);}Kj66運轉(zhuǎn)結(jié)果為:30.8改成:intadd(doublex,doubley)?6.2.3函數(shù)闡明1.函數(shù)闡明的方式函數(shù)闡明也稱為函數(shù)聲明,運用函數(shù)闡明語句可以讓C編譯程序了解函數(shù)前往值類型被調(diào)用函數(shù)闡明普通格式如下:函數(shù)類型函數(shù)名(數(shù)據(jù)類型[參數(shù)名1][,數(shù)據(jù)類型[參數(shù)名2]…]);函數(shù)闡明語句其實就是函數(shù)定義中的函數(shù)首部加上分號,這些內(nèi)容稱為函數(shù)原型。如:doublemax(doublex,doubley);voidswap(inta,intb);例:計算兩數(shù)之和#include<stdio.h>main(){doublea,b,c;a=10.5;b=20.3;c=add(a,b);printf("%lf",add(a,b));add(a,b);}doubleadd(doublex,doubley){doubles;s=x+y;returns;}kj67doubleadd(doublex,doubley);doubleadd(doublex,doubley);留意:有三種情況不需闡明:a、函數(shù)前往值為整型或字符型;b、被調(diào)用函數(shù)定義出如今主調(diào)函數(shù)之前;c、已在一切的函數(shù)定義之前〔即文件的開頭〕闡明了函數(shù)類型。

6.3函數(shù)的調(diào)用1、調(diào)用方式:函數(shù)名〔實參表列〕;實參與形參個數(shù)相等,類型一致。調(diào)用函數(shù)時兩者按順序一一對應(yīng)傳送數(shù)據(jù)。main(){inta=1,b,f(int,int);b=f(a,++a);printf("%d",b);}intf(intx,inty){intz;if(x>y)z=1;elseif(x==y)z=0;elsez=-1;return(z);}例:參數(shù)求值順序main(){inta=1,b,f(int,int);b=f(a,a++);printf("%d",b);}intf(intx,inty){intz;if(x>y)z=1;elseif(x==y)z=0;elsez=-1;return(z);}運轉(zhuǎn)結(jié)果:0運轉(zhuǎn)結(jié)果:12、調(diào)用方式:按函數(shù)在程序中出現(xiàn)的位置來分有三種方式。①函數(shù)語句。只完成一個操作,并不要求函數(shù)帶回值。如:printstar();scanf(“%d〞,&a);②函數(shù)表達(dá)式。出如今表達(dá)式中,函數(shù)值參與表達(dá)式運算。如:c=2*max(a,b);y=x+power(x,3);③函數(shù)參數(shù)。函數(shù)調(diào)用作為一個函數(shù)的實參。如:m=max(a,max(b,c));printf(“%8.2f\n〞,power(x,3));課堂練習(xí):下面程序的輸出結(jié)果是〔〕。#include<stdio.h>func(inta,intb){intc;c=a+b;returnc;}main(){intx=6,y=7,z=8,r;r=func((x--,y+=2,x+y),z);printf("%d\n",r);}A.11 B.20 C.21 D.22課堂練習(xí):假設(shè)有以下函數(shù)調(diào)用語句:fun(a+b,(x,y),fun(n+k,d,(a,b)));fun函數(shù)參數(shù)的個數(shù)是A〕3B〕4C〕5D〕66.4函數(shù)的參數(shù)形參與實參方式參數(shù):定義函數(shù)時函數(shù)名后面括號中的變量名。實踐參數(shù):調(diào)用函數(shù)時函數(shù)名后面括號中的表達(dá)式。例:編寫程序?qū)崿F(xiàn)從兩整數(shù)中求較大數(shù)。#include<stdio.h>floatmax(floatx,floaty); /*函數(shù)闡明*/main(

){floata,b;floatc;scanf("%f,%f",&a,&b);c=max(a,b); /*調(diào)用函數(shù)語句,a,b為實參*/printf("a=%f,b=%f\nmax=%f\n",a,b,c);}floatmax(floatx,floaty) /*函數(shù)定義,x,y為形參*/{floatz;z=x>y?x:y;printf(“x=%f,y=%f\nz=%f\n〞,x,y,z);return(z);}xy形參ab實參闡明:實參必需有確定的值,形參必需指定類型形參與實參類型一致,個數(shù)一樣假設(shè)形參與實參類型不一致,自動按形參類型轉(zhuǎn)換——函數(shù)調(diào)用轉(zhuǎn)換值傳送方式形參在函數(shù)被調(diào)用前不占內(nèi)存;函數(shù)調(diào)用時,為形參分配單元,并將實參的值復(fù)制到形參中;調(diào)用終了,形參單元被釋放,實參單元仍保管并維持原值特點:形參與實參占用不同的內(nèi)存單元單向傳送例:計算x的立方#include<stdio.h>floatcube(floatx){return(x*x*x);}main(){floata,product;scanf("%f",&a);product=cube(a);printf(〞%.4f%.4f\n",a,product);}xaproduct××××1.21.21.7281030x:y:調(diào)用前:調(diào)用終了:1030x:y:例:交換兩個數(shù)#include<stdio.h>main(){intx=10,y=30;printf("%d,%d\n",x,y);printf("swapped:\n");swap(x,y);printf("%d,%d\n",x,y);}swap(inta,intb){inttemp;temp=a;a=b;b=temp;}調(diào)用:1030a:b:1030x:y:swap:1030x:y:3010a:b:temp普通函數(shù)調(diào)用main()調(diào)用函數(shù)a終了a函數(shù)執(zhí)行2134566.5函數(shù)的嵌套調(diào)用和遞歸調(diào)用6.5.1函數(shù)的嵌套調(diào)用函數(shù)的嵌套調(diào)用是指,在執(zhí)行被調(diào)用函數(shù)時,被調(diào)用函數(shù)又調(diào)用了其它函數(shù)。這與其它言語的子程序嵌套調(diào)用的情形是類似的,其關(guān)系可表示如右圖所示。例:求三個數(shù)中最大數(shù)和最小數(shù)的差值intmax(intx,inty,intz)/*定義函數(shù)max求x,y,z中最大值*/{intr;r=x>y?x:y;return(r>z?r:z);}intmin(intx,inty,intz)/*定義函數(shù)min,求x,y,z中最小值*/{intr;r=x<y?x:y;return(r<z?r:z);}intdif(intx,inty,intz) /*定義函數(shù)dif*/{returnmax(x,y,z)-min(x,y,z); /*嵌套調(diào)用*/}voidmain(){inta,b,c,d;scanf("%d%d%d",&a,&b,&c);d=dif(a,b,c); /*調(diào)用函數(shù)dif*/printf("Max-Min=%d\n",d);}假設(shè)輸入2、3,求以下程序的運轉(zhuǎn)結(jié)果,分析嵌套調(diào)用的執(zhí)行過程。#include<stdio.h>intf(intn){intrtn=0;inti;for(i=1;i<=n;i++)rtn*=i;return(rtn);}longsum(inta,intb){longc1,c2;c1=f(a);c2=f(b);return(c1+c2);}main(){intn1=5,n2=10,a;a=sum(n1,n2);printf("a=%d",a);}6.5.2函數(shù)的遞歸調(diào)用在調(diào)用一個函數(shù)的過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸調(diào)用。遞歸調(diào)用方式如下:(1)直接遞歸voida(){...…a();/*本人調(diào)用本人,直接遞歸*/...…}函數(shù)a()

調(diào)用函數(shù)a()(2)間接遞歸voida(){...…b();/*調(diào)用函數(shù)b*/...…}voidb(){......a();/*調(diào)用函數(shù)a,間接遞歸*/……}

調(diào)b調(diào)aa()b()以上是無終止的函數(shù)調(diào)用,因此,一個正確的遞歸調(diào)用的函數(shù)必需滿足以下條件:1、一個問題轉(zhuǎn)化成一個新問題,解題方法類似,只是所處置的對象的值有規(guī)律的遞增或遞減。2、可以運用這個轉(zhuǎn)換過程使問題得到處理。3、必需有明確的終了遞歸的條件;分析問題2種方法:遞推和遞歸遞推:從一個知的現(xiàn)實出發(fā),按一定的規(guī)律推出下一個現(xiàn)實。通常利用迭代公式法,經(jīng)過循環(huán)構(gòu)造實現(xiàn),循環(huán)的終值是問題的結(jié)果。遞歸:從要求的結(jié)果出發(fā),歸納出后一個結(jié)果和前一個結(jié)果存在的關(guān)系,直到一個知值為止〔即反推法〕。通常設(shè)計函數(shù)〔遞歸函數(shù)〕,不斷運用下一級值調(diào)用本身,直到一個知的值〔遞歸出口〕。0!=11!=0!*1…………….n!=(n-1)!*n例:求n的階乘n!遞推公式:1n=0sn=sn-1*nn>0程序段為:#include<stdio.h>main(){intm=1,i,n;scanf("%d",&n);for(i=1;i<=n;i++)m=m*i;printf("theresultis%10d",m);}例:求n的階乘n!遞歸方法求n!由于n!=n*(n-1)!是遞歸定義所以求n!〔n-1〕!

(n-1)!〔n-2〕!

(n–2)!〔n-3〕!

……

1!0!的問題,

知條件為:0!=1。

遞歸函數(shù):1n=0f(n)=f(n-1)*nn>0遞歸函數(shù)普通方式:函數(shù)名f〔參數(shù)〕{if〔n==初值〕結(jié)果=….;else結(jié)果=含f(n-1)的表達(dá)式;return(前往結(jié)果);}#include<stdio.h>intf(intx){intt;if(x==0)t=1;/*遞歸出口*/elset=f(x-1)*x;;/*遞歸公式*/return(t);}main(){intn=0,s;scanf("%d",&n);s=f(n);printf("%d!=%10d",n,s);}f函數(shù)在回推階段被調(diào)用了4次,遞歸調(diào)用了3次,到終止條件才有確定的值,然后再遞推出每一次調(diào)用的值,最后得到所求的結(jié)果。例:求Fibonacci數(shù)列:打印1,1,2,3,5,8,……的前40個數(shù)。#include<stdio.h>main(){longf1,f2;inti;f1=1;f2=1;for(i=1;i<20;i++){printf("%12ld%12ld",f1,f2);if(i%2==0)printf("\n");f1=f1+f2;f2=f2+f1;}}方法1:用循環(huán)構(gòu)造來實現(xiàn)#include<stdio.h>intfib(intn){intf; if(n==1||n==2)f=1; elsef=fib(n-1)+fib(n-2); returnf;}main(){inti;for(i=1;i<=40;i++){printf("%15d",fib(i));if(i%4==0) printf("\n");}}方法2:用遞歸函數(shù)來實現(xiàn)例:反向輸出一個整數(shù)#include<stdio.h>main(){intn; scanf("%d",&n); if(n<0) {n=-n; printf("-"); } while(n!=0) {printf("%d",n%10); n=n/10; }}方法1:用循環(huán)構(gòu)造來實現(xiàn)#include<stdio.h>voidmain(){voidprintn(intx);intn;scanf("%d",&n);if(n<0){ n=-n;putchar('-'); }printn(n);}voidprintn(intx) /*反向輸出整數(shù)x*/{if(x>=0&&x<=9) /*假設(shè)x為一位整數(shù)*/printf("%d",x); /*那么輸出整數(shù)x*/else /*否那么*/{ printf("%d",x%10); /*輸出x的個位數(shù)字*/ printn(x/10);/*將x中的個位數(shù)字去掉,構(gòu)成新的x后,繼續(xù)遞歸操作*/}}方法2:用遞歸函數(shù)來實現(xiàn)輸出一個正整數(shù)的遞歸算法為:if(n為一位整數(shù)) 輸出n; else {輸出n的個位數(shù)字; 對剩余數(shù)字組成的新整數(shù)反復(fù)"反向輸出"操作; }例:漢諾塔問題。

初始形狀:有3個塔,每個都堆放假設(shè)干個盤子。開場時,一切盤子均在塔a上,并且,盤子從上到下,按直徑增大的次序放置。要求處理問題:設(shè)計一個盤子挪動的序列,使得塔a上的一切盤子借助于塔b挪動到塔c上。兩個限制:1〕一次只能挪動一個盤子;2〕任何時候都不能把盤子放在比它小的盤子的上面。

假設(shè)塔a有n個盤子知條件:假設(shè)只需一個盤子,那么是直接從1移到3〔遞歸出口〕算法設(shè)計如下:第一步:把n-1個盤子按照標(biāo)題中的規(guī)那么從塔a〔源塔〕借助于塔c〔中間塔〕搬到塔b〔目的塔〕。第二步:將剩下的一只盤〔也就是最大的一只〕直接從塔a〔源塔〕搬到那個依然空著的塔c〔目的塔〕。第三步:再次將b塔〔源塔〕上的n-1個盤子借助于塔a〔中間塔〕搬到塔c〔目的塔〕。這一步是沒有問題的,由于c塔上僅有一只最大的盤。函數(shù)hanoi(intn,inta,intb,intc)設(shè)計:1.假設(shè)(n==1)那么ac;2.否那么執(zhí)行3步2-1調(diào)用函數(shù)hanoi(n-1,a,c,b);2-2ac;2-3調(diào)用函數(shù)hanoi(n-1,b,a,c);例Hanoi問題#include<stdio.h>voidhanoi(intn,inta,intb,intc){if(n==1)printf("%d->%d\n",a,c);else{hanoi(n-1,a,c,b); printf("%d->%d\n",a,c); hanoi(n-1,b,a,c);}}main(){intn;printf("Inputn:");scanf("%d",&n);hanoi(n,1,2,3);}

運轉(zhuǎn)情況如下:inputn:3↙thestep:1-->31-->23-->21-->32-->12-->31-->3先看一個例子,錯在那里?:#include"stdio.h"voidf1(){intt=2;a*=t;b/=t;}main(){inta,b;scanf("%d,%d",&a,&b);f1();//調(diào)用函數(shù)f1()printf("a=%d,b=%d",a,b);}1編譯程序會提示出錯:Undefinedsymbol‘a(chǎn)’和Undefinedsymbol‘b’。為什么?6.6變量的存儲類型6.6.1變量的生存期和作用域生存期:變量在某一時辰存在-------靜態(tài)變量與動態(tài)變量作用域:變量在某區(qū)域內(nèi)有效-------部分變量與全局變量(文件、函數(shù)、復(fù)合語句)6.6.2變量的存儲類型(特性)1.c言語中每一個變量有兩個屬性:數(shù)據(jù)類型,存儲類型。完好的變量定義:[存儲類型][數(shù)據(jù)類型]變量名;2.變量的存儲類型(特性)自動型auto靜態(tài)型static存放器型register外部型extern程序區(qū)靜態(tài)存儲區(qū)動態(tài)存儲區(qū)2.靜態(tài)存儲類型的變量的生存期為程序執(zhí)行的整個過程,在該過程中占有固定的存儲空間,稱它們?yōu)橛谰么鎯?。staticextern動態(tài)存儲類型變量只生存在某一段時間內(nèi)。例如,函數(shù)的形參和函數(shù)體內(nèi)定義的變量,只是在程序進(jìn)入該函數(shù)時才分配存儲空間,當(dāng)該函數(shù)執(zhí)行完后,變量對應(yīng)的存儲空間又被撤銷了。atuoregister部分變量與全局變量部分變量---內(nèi)部變量定義:在函數(shù)內(nèi)或復(fù)合語句定義闡明:main〔函數(shù)〕中定義的變量只在main〔函數(shù)〕中有效。復(fù)合語句中定義的變量只在復(fù)合語句中有效。不同函數(shù)中同名變量,占不同內(nèi)存單元。形參屬于部分變量。部分變量可用存儲類型:autoregister。static〔默以為auto〕floatf1(inta){intb,c;…….}charf2(intx,inty){inti,j;……}main(){intm,n;…….}a,b,c有效x,y,i,j有效m,n有效#include<stdio.h>sub(){inta,b;a=6;b=7;printf("sub:a=%d,b=%d\n",a,b);}main(){autointa,b;a=3;b=4;sub();printf("main:a=%d,b=%d\n",a,b);}31.自動變量部分靜態(tài)變量值具有可承繼性部分靜態(tài)變量的初始化只在編譯時進(jìn)展一次,每次調(diào)用他們所在的函數(shù)時,不再重新賦初值;如定義但不初始化,自動賦0或‘\0’1.靜態(tài)部分變量static數(shù)據(jù)類型變量名staticinti=1;#include<stdio.h>main(){voidin(void);in();in();in();}voidin(void){intx=0;x++;printf(“%d\n〞,x);}4運轉(zhuǎn)結(jié)果:111#include<stdio.h>main(){voidin(void);in();in();in();}voidin(void){staticintx=0;x++;printf(“%d\n〞,x);}5運轉(zhuǎn)結(jié)果:1231.靜態(tài)部分變量例:分析執(zhí)行結(jié)果f(inta){intb=0;staticintc=3;b++;c++;printf("%5d%5d%5d\n",a,b,c);return(a+b+c);}main(){inta=2,k;for(k=0;k<3;k++)printf("%5d\n",f(a));}6靜態(tài)變量只初始化一次結(jié)果:214〔a,b,c)7(f(a))21582169(3)register(存放器)型將運用頻率高的變量定義為register型,可以提高運轉(zhuǎn)速度。存放器變量只限于整型、字符型、指針型的部分變量。存放器變量是動態(tài)變量,而且數(shù)目有限,普通僅允許闡明兩個存放器變量,過多的存放器變量的編譯器能夠把它看成Auto類型。例如:registerintd;registercharc;全局變量---外部變量定義:在函數(shù)外定義,可為本文件一切函數(shù)共用有效范圍:從定義變量的位置開場到根源文件終了,及有extern闡明的其它源文件外部變量闡明:外部變量定義與外部變量闡明不同假設(shè)外部變量與部分變量同名,那么外部變量被屏蔽外部變量可用存儲類型:缺省或static#include<stdio.h>externinta,b;voidswap(){intt;t=a;a=b;b=t;printf(“swap:a=%d,b=%d\n〞,a,b);}inta,b;main(){printf(“Entera,b:〞);scanf(“%d,%d〞,&a,&b);swap();printf(“main:a=%d,b=%d〞,a,b);}7Entera,b:5,3↙swap:a=3,b=5main:a=3,b=5運轉(zhuǎn)結(jié)果全局變量有兩個問題:其一:當(dāng)全局變量定義在后,援用它的函數(shù)在前時,如何運用該全局變量?這就需求把該全局變量的作用域延伸至該函數(shù);其二:能否使在某文件中定義的全局變量,在其它文件中無須再次定義而直接運用它呢?這就需求把全局變量的作用域進(jìn)展延伸。C言語可經(jīng)過外部變量闡明到達(dá)此目的。定義闡明次數(shù):只能1次可闡明多次位置:一切函數(shù)之外函數(shù)內(nèi)或函數(shù)外分配內(nèi)存:分配內(nèi)存,可初始化不分配內(nèi)存,不可初始化外部變量闡明:extern數(shù)據(jù)類型變量表;外部變量定義與外部變量闡明不同假設(shè)外部變量與部分變量同名,那么外部變量被屏蔽例外部變量定義與闡明運轉(zhuǎn)結(jié)果:max=13#include<stdio.h>externinta,b;//外部變量闡明intmax(intx,inty);//函數(shù)闡明main(){printf("max=%d",max(a,b));}inta=13,b=-8;//外部變量定義intmax(intx,inty)//函數(shù)定義{intz;z=x>y?x:y;return(z);}#include<stdio.h>inta=7,b=9;//a,b為全局變量voidf1(intx){intt1;t1=b*x;printf("f1:t1=%d,a=%d,b=%d\n",t1,3*a,3*b);}main(){f1(2);//調(diào)用函數(shù)f1()printf("main:a=%d,b=%d\n",a,b);}t8#include<stdio.h>inta,b;/*a,b為全局變量*/voidf1(intx){intt1,a;//重新定義a,沒重新定義b,a值傳不過去。a=x*4;t1=b*3;b=10;printf("f1:t1=%d,a=%d,b=%d\n",t1,a,b);}main(){a=2;b=4;/*此a,b是全局變量,賦值*/f1(2);/*調(diào)用函數(shù)f1()*/printf("main:a=%d,b=%d",a,b);}9f1:t1=12,a=8,b=10main:a=2,b=10結(jié)論:全局變量與部分變量同名時,部分變量起作用,全局變量被屏蔽〔不影響〕變量存儲類型小結(jié)靜態(tài)動態(tài)存儲方式程序整個運轉(zhuǎn)期間函數(shù)調(diào)用開場至終了生存期編譯時賦初值,只賦一次每次函數(shù)調(diào)用時賦初值自動賦初值0或空字符不確定未賦初值靜態(tài)存儲區(qū)動態(tài)區(qū)存儲區(qū)存放器部分變量外部變量作用域定義變量的函數(shù)或復(fù)合語句內(nèi)本文件其它文件部分變量默以為auto型register型變量個數(shù)受限,且不能為long,double,float型部分static變量具有全局壽命和部分可見性部分static變量具有可承繼性extern不是變量定義,可擴(kuò)展外部變量作用域register部分staticauto外部static外部存儲類別6.7內(nèi)部函數(shù)、外部函數(shù)C言語根據(jù)函數(shù)能否被其它源文件中的函數(shù)調(diào)用,將函數(shù)分為內(nèi)部函數(shù)和外部函數(shù)。6.7.1內(nèi)部函數(shù)〔又稱靜態(tài)函數(shù)〕假設(shè)一個函數(shù),只能被本文件中的函數(shù)調(diào)用,而不能被同一程序其它文件中的函數(shù)調(diào)用,那么稱為內(nèi)部函數(shù)。定義一個內(nèi)部函數(shù),只需在函數(shù)類型前再加一個“static〞關(guān)鍵字即可,定義格式如下:static函數(shù)類型函數(shù)名(函數(shù)參數(shù)表){……}如staticintfun(a,b,c){……}6.7.1外部函數(shù)在定義函數(shù)時,假設(shè)沒有加關(guān)鍵字“static〞,或者冠以“extern〞,那么表示此函數(shù)是外部函數(shù),其定義格式為:[extern]函數(shù)類型函數(shù)名(函數(shù)參數(shù)表){……}調(diào)用外部函數(shù)時,必需對被調(diào)用的外部函數(shù)進(jìn)展闡明。例/*FILE1*/#include<stdio.h>inti;/*在FILE1中定義外部變量i*/voidfunc();/*外部函數(shù)闡明*/main(){ i=5; printf("file1:%d\n",i); func();}/*FILE2*/externinti;/*外部變量闡明,F(xiàn)ILE2援用FILE1中定義的外部變量i*/voidfunc(){ printf("file2:%d\n",i);}該程序的運轉(zhuǎn)結(jié)果是:file1:5file2:56.8編譯預(yù)處置“編譯預(yù)處置〞是C言語編譯系統(tǒng)的一個組成部分。是在編譯前由編譯系統(tǒng)中的預(yù)處置程序?qū)υ闯绦虻念A(yù)處置命令進(jìn)展加工。源程序中的預(yù)處置命令均以“#〞開頭,終了不加分號,以區(qū)別源程序中的語句,它們可以寫在程序中的任何位置,作用域是自出現(xiàn)點到源程序的末尾。預(yù)處置命令包括執(zhí)行宏定義(宏交換)、包含文件和條件編譯。一.宏定義簡單宏定義1.普通方式為:#define宏名串(宏體)如:#definePI3.14159/*定義后,可以用PI來替代串3.14159*/2.宏定義的作用在宏定義之后,該程序中宏名就代表了該字符串。闡明:占單獨書寫行語句尾不加分號3.闡明①可以用#undef命令終止宏定義的作用域。例如:#undefPI②宏定義的嵌套運用#defineR3.0#definePI3.1415926#defineL2*PI*R/*宏體是表達(dá)式*/#defineSPI*R*Rmain(){printf("L=%f\nS=%f\n",2*PI*R,PI*R*R);/*2*PI*R交換L,PI*R*R交換S*/}t6-1程序運轉(zhuǎn)結(jié)果如下:L=18.849556S=28.274333③雙引號內(nèi)與宏同名的字母不作宏展開.main(){printf("L=%f\nS=%f\n",L,S);}t6-1#defineX5#defineYX+1#defineZY*X/2main(){inta=Y;printf("%d\n",Z);printf("%d\n",--a);}t6-2//Z=Y*X/2=5+1*5/2=7運轉(zhuǎn)結(jié)果:75帶參數(shù)的宏定義1.帶參數(shù)的宏定義的普通方式為#define宏名(參數(shù)表〕字符串#defineS(a,b)((a)*(b))2.帶實參的宏名被展開宏名被所定義的宏體交換,宏體中的形參按從左到右的順序被實參交換。例如:area=S(3,2);展開為:area=((3)*(2));宏體及各形參外普通應(yīng)加括號〔〕

普通寫成:#definePOWER(x)((x)*(x))x=4;y=6;z=POWER(x+y);宏展開:z=((x+y)*(x+y));例#definePOWER(x)x*xx=4;y=6;z=POWER(x+y);宏展開:z=x+y*x+y;結(jié)果為:100結(jié)果為:34課堂練習(xí):#include<stdio.h>#defineMIN(x,y)(x)<(y)?(x):(y)main(){inti,j,k;i=10;j=15;k=10*MIN(i,j);printf("%d\n",k);}A)15B)100C)10D)150//10*i<j?10*10<15?(10):(15)運用宏交換應(yīng)留意的問題(1)宏名與宏體之間用空格相隔,宏名和參數(shù)之間不能有空格;如有宏定義:#definef(x)((x)–1)/*宏名f(x)中有空格*/(2)宏名雖然是字符串,但不能用引號括起來(3)在宏定義中結(jié)尾不能有分號〞;〞(4)宏定義中的參數(shù)盡量用圓括號括起來以免錯誤.(5)較長的宏定義在一行中寫不下時,要在本行結(jié)尾運用反斜杠表示續(xù)行。如:#defineOUTPUTprintf(“Thisisaninteresting\programwhichteachespepolehowtousedefine\command〞)t6-3這是比較特殊的,由于在C言語中普通情況下不需求有續(xù)行的標(biāo)識,而預(yù)處置是個例外。(6)宏定義可以寫在程序中的任何地方,但因其作用域為從定義之處到文件未尾,所以一定要寫在程序援用該宏之前,通常寫在一個文件之首。#defineMAX(x,y)(x)>(y)?(x):(y)…….main(){inta,b,c,d,t;…….t=MAX(a+b,c+d);……}t6-4宏展開:t=(a+b)>(c+d)?(a+b):(c+d);例用宏定義和函數(shù)實現(xiàn)同樣的功能intmax(intx,inty){r

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論