版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
函數(shù)的定義和調(diào)用函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的作用域和生存期編譯預(yù)處理多源文件C程序的組織方法第4章函數(shù)與程序結(jié)構(gòu)模塊化程序設(shè)計(jì)技術(shù)就是通過開發(fā)和維護(hù)一些小的程序塊(即模塊)的方法構(gòu)建一個(gè)大型程序,是人類解決較大的復(fù)雜問題所采用的一種“分而治之”的策略。本章主要討論C語言實(shí)現(xiàn)模塊化程序設(shè)計(jì)技術(shù)的手段以及在模塊化實(shí)現(xiàn)過程中所遇到的一系列問題。第4章函數(shù)與程序結(jié)構(gòu)C程序的一般結(jié)構(gòu)C程序源文件1…源文件i源文件n函數(shù)1預(yù)處理語句函數(shù)m說明/定義部分執(zhí)行語句部分圖4.1C程序的一般結(jié)構(gòu)……第4章函數(shù)與程序結(jié)構(gòu)在C語言程序中的若干個(gè)函數(shù)中必須有一個(gè)且只能有一個(gè)函數(shù)成為主函數(shù)。C程序的執(zhí)行從main函數(shù)開始,調(diào)用其它函數(shù)后流程回到main函數(shù),在main函數(shù)中結(jié)束整個(gè)程序的運(yùn)行。在一個(gè)函數(shù)中可以使用另一個(gè)函數(shù)的功能,這稱為函數(shù)調(diào)用。4.1函數(shù)的定義和調(diào)用
使用函數(shù)首先要對(duì)函數(shù)定義。函數(shù)定義中必須描述出函數(shù)的三個(gè)特征,即函數(shù)的名字、函數(shù)形式的參數(shù)表以及函數(shù)的返回值類型。C語言函數(shù)定義的形式如下:
4.1.1函數(shù)的定義和聲明返回值類型函數(shù)名(形式參數(shù)列表){函數(shù)體return;}
下面以定義實(shí)現(xiàn)求階乘功能函數(shù)為例了解一個(gè)函數(shù)的具體定義過程.根據(jù)前面所學(xué)知識(shí)知道,求階乘的C程序如下所示:
#include<stdio.h>voidmain(){ int i,n; longfact=1; printf("Inputn:"); scanf("%d",&n); for(i=1;i<=n;i++) fact*=i;printf("%d!=%ld\n",n,fact);}程序?qū)崿F(xiàn)了計(jì)算從鍵盤輸入一個(gè)整數(shù)n,并求其階乘的功能。如果在今后的應(yīng)用中,需要將求某數(shù)階乘的功能作為程序中相對(duì)獨(dú)立的一個(gè)部分(功能),則需要將上述功能用自編函數(shù)的方式實(shí)現(xiàn)
4.1.1函數(shù)的定義和聲明(1)函數(shù)的命名函數(shù)的名字在程序設(shè)計(jì)中有兩個(gè)作用:一是使用該名字調(diào)用這個(gè)函數(shù);二是應(yīng)該見名知意,符合c語言的規(guī)則。對(duì)于實(shí)現(xiàn)本功能的函數(shù),命名factorial。
(2)函數(shù)執(zhí)行結(jié)果的返回和返回值類型的確定
函數(shù)執(zhí)行的結(jié)果如果是一個(gè)具體的表達(dá)式,當(dāng)函數(shù)執(zhí)行完成時(shí)用關(guān)鍵字return組成形如:return<表達(dá)式>;的C語句將函數(shù)執(zhí)行的結(jié)果返回給調(diào)用函數(shù)者。注意函數(shù)執(zhí)行結(jié)果的數(shù)據(jù)類型不是由返回的表達(dá)式數(shù)據(jù)類型來決定的,而是用類型名作為關(guān)鍵字在函數(shù)的頭部予以確定?;谏鲜鰞牲c(diǎn),可以寫出實(shí)現(xiàn)階乘功能的函數(shù)factorial4.1.1函數(shù)的定義和聲明long為函數(shù)返回值類型Return語句將n!返回給調(diào)用函數(shù)花括號(hào)給函數(shù)確定了邊界區(qū)域longfactorial(){ int i,n; longfact=1;
printf("Inputn:"); scanf("%d",&n); for(i=1;i<=n;i++) fact*=i; returnfact;}4.1.1函數(shù)的定義和聲明(3)函數(shù)的參數(shù)表設(shè)計(jì)在上面定義的函數(shù)factorial中,函數(shù)用到的數(shù)據(jù)是從鍵盤輸入獲取的,如果需要從對(duì)函數(shù)的調(diào)用者(使用者)處獲取所需要的數(shù)據(jù),就必須對(duì)函數(shù)的形式參數(shù)表進(jìn)行設(shè)計(jì)。此時(shí)需要兩個(gè)步驟來實(shí)現(xiàn):一是將函數(shù)內(nèi)部用于從鍵盤上接收數(shù)據(jù)的數(shù)據(jù)對(duì)象定義移到函數(shù)的形式參數(shù)表中;二是刪去函數(shù)中從鍵盤獲取數(shù)據(jù)的語句。函數(shù)factorial可以改造為如下形式:longfactorial(intn){ int i; longfact=1; for(i=1;i<=n;i++) fact*=i; returnfact;}n的值函數(shù)調(diào)用者(使用者)處獲取,不再從程序中獲取。4.1.1函數(shù)的定義和聲明
通過對(duì)函數(shù)factorial定義過程的討論,可以理解C函數(shù)定義一般形式中各個(gè)函數(shù)組成成分的確切含義:(1)返回值類型說明符 用以制定函數(shù)返回值的數(shù)據(jù)類型,可以是C語言中任何合法的基本數(shù)據(jù)類型和構(gòu)造體數(shù)據(jù)類型。如果要表示一個(gè)函數(shù)不需要向調(diào)用者返回值,則函數(shù)的返回值數(shù)據(jù)類型應(yīng)該定義為void,如前面章節(jié)的主函數(shù)main。(2)函數(shù)的名字 遵循C語言標(biāo)識(shí)符的命名規(guī)則。盡量做到“見名知意”。(3)形式參數(shù)表 函數(shù)的形式參數(shù)表用圓括號(hào)括起來的、由零個(gè)到多個(gè)形式參數(shù)的定義組成,兩個(gè)形式參數(shù)定義之間用逗號(hào)分隔。若一個(gè)函數(shù)沒有形式參數(shù),作為函數(shù)運(yùn)算符使用的圓括號(hào)也不能省略。4.1.1函數(shù)的定義和聲明(4)return<表達(dá)式>;語句如果函數(shù)定義中指定的返回值數(shù)據(jù)類型不是void,則函數(shù)定義中必須有用關(guān)鍵字return構(gòu)成的return<表達(dá)式>;語句。當(dāng)函數(shù)執(zhí)行到該C語句時(shí),先計(jì)算該語句中的表達(dá)式的值,然后再將該值強(qiáng)制轉(zhuǎn)化為指定的函數(shù)返回值的數(shù)據(jù)類型,返回到主調(diào)函數(shù)中。如果函數(shù)定義時(shí)指定的返回值類型是void,則函數(shù)定義中可以沒有用return構(gòu)成的語句,若函數(shù)定義的執(zhí)行流程需要使用return語句,則其形式只能是:return;。4.1.1函數(shù)的定義和聲明例如:我們定義一個(gè)求兩個(gè)數(shù)中最大值的函數(shù):4.1.1函數(shù)的定義和聲明intmax(intx,inty){inttemp;/*函數(shù)體的局部變量*/
temp=x>y?x:y;/*函數(shù)體的執(zhí)行部分*/
returntemp;/*返回函數(shù)值*/
}
函數(shù)返回類型函數(shù)名形式參數(shù)C語言中規(guī)定,函數(shù)不能嵌套定義。這個(gè)規(guī)定保證了每個(gè)函數(shù)都是一個(gè)相對(duì)獨(dú)立的程序模塊。在由多個(gè)函數(shù)組成的C程序中,各個(gè)函數(shù)的定義是并列的并且順序是任意的,函數(shù)在一個(gè)C程序中的定義順序與該C程序運(yùn)行時(shí)函數(shù)的執(zhí)行順序無關(guān)。函數(shù)定義好后,就可以使用了,稱為函數(shù)的調(diào)用。C語言規(guī)定,在調(diào)用函數(shù)之前必須向系統(tǒng)描述所調(diào)用函數(shù)的基本特征,稱為函數(shù)的聲明。C語言中的函數(shù)分為標(biāo)準(zhǔn)庫函數(shù)和用戶自定義函數(shù)兩大類。下面分別介紹他們的聲明方法。
4.1.1函數(shù)的定義和聲明(1)標(biāo)準(zhǔn)庫函數(shù)的聲明方式#include<頭文件名>當(dāng)使用尖括號(hào)時(shí),指定系統(tǒng)首先查找C編譯系統(tǒng)配置的頭文件路徑(include路徑);#include“頭文件名”當(dāng)使用雙引號(hào)時(shí),指定系統(tǒng)首先查找當(dāng)前目錄。(2)用戶自定函數(shù)的聲明方式如果被調(diào)用函數(shù)(稱為被調(diào)函數(shù))與調(diào)用它的函數(shù)(稱為主調(diào)函數(shù))在同一源文件中,需要在函數(shù)調(diào)用之前對(duì)被調(diào)函數(shù)進(jìn)行聲明。形式為:
返回值類型函數(shù)名(形式參數(shù)表);4.1.1函數(shù)的定義和聲明/*Name:ex04-01.cpp*/#include<stdio.h>voidmain(){ longfactorial(intn); intnum; printf("Inputthenum:"); scanf("%d",&num); printf("%d!=%ld\n",num,factorial(num));}longfactorial(intn)//函數(shù)factorial的定義,最后沒有分號(hào){ int i; longfact=1; for(i=1;i<=n;i++) fact*=i; returnfact;}函數(shù)聲明告訴編譯系統(tǒng)factorial是一個(gè)返回值是long,只有一個(gè)int參數(shù)的函數(shù),注意最后分號(hào)不可少!程序演示形式參數(shù)(簡稱形參)實(shí)際參數(shù)(簡稱實(shí)參)在上面程序中,主函數(shù)中的longfactorial(intn);語句就是對(duì)函數(shù)factorial的聲明。C程序中,對(duì)被調(diào)函數(shù)的聲明也可以書寫在主調(diào)函數(shù)定義之前,這種方式下函數(shù)聲明語句之后的所有函數(shù)都能對(duì)被聲明函數(shù)進(jìn)行調(diào)用,如下面的程序段所示:#include<stdio.h>longfactorial(intn);//對(duì)函數(shù)factorial的聲明,該程序中其它函數(shù)均可以調(diào)用它。voidmain(){ … }4.1.1函數(shù)的定義和聲明在函數(shù)的聲明語句中,形參的名字是無關(guān)緊要的(可以與函數(shù)定義中的不同甚至可以缺?。?,函數(shù)聲明語句的關(guān)鍵是形參的類型、個(gè)數(shù)和次序必須與定義對(duì)應(yīng)。例如上面對(duì)函數(shù)factorial的聲明語句還可以寫成為如下兩種形式:⑴longfactorial(int);/*對(duì)函數(shù)factorial的聲明中無形參名,表示默認(rèn)*/⑵longfactorial(intx);/*對(duì)函數(shù)factorial的聲明中形式參數(shù)名與函數(shù)定義不同,但意義一樣*/4.1.1函數(shù)的定義和聲明C語言規(guī)定在下列情況下可以不對(duì)被調(diào)函數(shù)進(jìn)行聲明:1.被調(diào)函數(shù)的返回值數(shù)據(jù)類型是整型或字符型在這種情況下,系統(tǒng)自動(dòng)按整型進(jìn)行隱式聲明。但從現(xiàn)代程序設(shè)計(jì)技術(shù)的觀點(diǎn)出發(fā),對(duì)任何類型的函數(shù)在調(diào)用之前都必須聲明,所以許多較現(xiàn)代的C編譯系統(tǒng)在這種情況下仍然強(qiáng)制要求對(duì)被調(diào)函數(shù)進(jìn)行聲明。2.被調(diào)函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前在這種情況下,系統(tǒng)在執(zhí)行程序中的函數(shù)調(diào)用語句之前已知道了被調(diào)函數(shù)的所有特征。
4.1.1函數(shù)的定義和聲明/*Name:ex04-02.cpp*/#include<stdio.h>longfactorial(intn)//函數(shù)factorial的定義出現(xiàn)在主調(diào)函數(shù)main的前面{ int i; longfact=1; for(i=1;i<=n;i++) fact*=i; returnfact;}voidmain() //主函數(shù)中沒有對(duì)函數(shù)factorial進(jìn)行聲明的語句{ intnum;//longfactorial(intn); printf("Inputthenum:"); scanf("%d",&num); printf("%d!=%ld\n",num,factorial(num));}程序演示4.1.1函數(shù)的定義和聲明什么是函數(shù)的調(diào)用?先看下列程序/*計(jì)算S=2!-3!+4!*/
#include<stdio.h>voidmain(){floatqsn(int
x);//函數(shù)的聲明
floats;s=qsn(2)-qsn(3)+qsn(4);/*直接調(diào)用qsn函數(shù)進(jìn)行計(jì)算*/printf(“S=%f\n”,s);}
floatqsn(intn)/*定義函數(shù)qsn為階乘*/{intk;floatqsn;qsn=1;for(k=1;k<=n;k++)qsn*=k;return(qsn);}4.1.2值參數(shù)傳遞的函數(shù)調(diào)用函數(shù)調(diào)用的一般形式為:
函數(shù)名(實(shí)際參數(shù)列表)C程序中對(duì)函數(shù)的調(diào)用方式有三種:
⑴函數(shù)語句方式 把函數(shù)調(diào)用作為一個(gè)語句來使用。例如:for(k=0;k<5);k++)printline();//函數(shù)調(diào)用部分,無參函數(shù)
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用
⑵函數(shù)表達(dá)式方式 在函數(shù)調(diào)用的這種方式下,函數(shù)調(diào)用出現(xiàn)在一個(gè)表達(dá)式中,這個(gè)表達(dá)式亦稱為函數(shù)表達(dá)式。此時(shí)要求函數(shù)被調(diào)用后必須要返回一個(gè)確定的值以參加表達(dá)式運(yùn)算。例如:
s=qsn(2)-qsn(3)+qsn(4);
⑶函數(shù)參數(shù)方式在函數(shù)調(diào)用的這種方式下,函數(shù)調(diào)用作為另外一個(gè)函數(shù)調(diào)用的實(shí)際參數(shù)出現(xiàn)。此時(shí)要求函數(shù)被調(diào)用后必須要返回一個(gè)確定的值以作為其外層函數(shù)調(diào)用的實(shí)際參數(shù)。例如:
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用
/*函數(shù)參數(shù).cpp*/
#include<stdio.h>
intmax(intx,inty)/*函數(shù)定義*/{return(x>y?x:y);}main(){inta,b,c;/*定義3個(gè)整型變量,保存需要保存的三個(gè)數(shù)*/
intMAX;/*保存最大值*/
printf(“請(qǐng)輸入三個(gè)數(shù)\n”);
scanf(“%d,%d,%d”,&a,&b,&c);
MAX=max(a,max(b,c));/*求三個(gè)數(shù)的最大值,函數(shù)max作為實(shí)參*/
printf(“3個(gè)數(shù)中的最大值是:%d\n”,MAX);
}//n個(gè)數(shù)的最大值可以兩兩相求,例如4個(gè)數(shù)中的最大值max(max(a,b),max(c,d)4.1.2值參數(shù)傳遞的函數(shù)調(diào)用當(dāng)被調(diào)函數(shù)是有參函數(shù)時(shí),函數(shù)的調(diào)用必然伴隨著參數(shù)傳遞。在C程序函數(shù)調(diào)用的數(shù)據(jù)傳遞中,傳遞的是實(shí)際參數(shù)所具有的值。當(dāng)實(shí)際參數(shù)是常量、變量或函數(shù)調(diào)用時(shí),傳遞的數(shù)據(jù)就是這些數(shù)據(jù)對(duì)象所具有的內(nèi)容,這種方式亦稱為傳數(shù)據(jù)值方式。如果函數(shù)調(diào)用時(shí)所傳遞的實(shí)際參數(shù)是數(shù)據(jù)對(duì)象在內(nèi)存中存儲(chǔ)的首地址值,則稱之為傳地址值方式,對(duì)于指針參數(shù)和數(shù)組參數(shù)就是使用的傳地址值調(diào)用方式,將分別在本章的4.1.3和4.1.4小節(jié)中予以討論。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用無論函數(shù)調(diào)用時(shí)的傳遞是數(shù)值值還是地址值,函數(shù)調(diào)用的執(zhí)行過程都可以分為下面四個(gè)步驟:(1)系統(tǒng)為被調(diào)函數(shù)中的局部變量分配存儲(chǔ);(2)如果是有參函數(shù)調(diào)用則進(jìn)行參數(shù)傳遞,主調(diào)函數(shù)將實(shí)參值傳遞給被調(diào)函數(shù)的形參,傳遞時(shí)要保證參數(shù)的個(gè)數(shù)、類型、位置等一一對(duì)應(yīng);(3)程序執(zhí)行的控制流程轉(zhuǎn)移到被調(diào)函數(shù)執(zhí)行;(4)執(zhí)行完被調(diào)函數(shù)后,程序執(zhí)行的控制流程以及被調(diào)函數(shù)的執(zhí)行結(jié)果返回到主調(diào)函數(shù)中的調(diào)用點(diǎn)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用例4.3的程序討論函數(shù)調(diào)用的執(zhí)行過程,為了討論方便為程序加上行號(hào)。1 /*ex04-03.cpp*/2 #include<stdio.h>3 voidmain()4 { voidswap(intx,inty);5 inta=3,b=5;6 printf("swap調(diào)用前:a=%d,b=%d\n",a,b);7 swap(a,b);8 printf("swap調(diào)用后:a=%d,b=%d\n",a,b);9 }10 voidswap(intx,inty)11 { intt;12 t=x,x=y,y=t;13 printf("swap調(diào)用中:x=%d,y=%d\n",x,y);14 }4.1.2值參數(shù)傳遞的函數(shù)調(diào)用C程序執(zhí)行時(shí),函數(shù)在被調(diào)用之前其形參和函數(shù)體中定義的普通變量在系統(tǒng)中都是不存在的,它們?cè)谙到y(tǒng)中出現(xiàn)或消失與函數(shù)調(diào)用的過程有著密切的關(guān)系,在例4.3程序執(zhí)行到第7行之前,函數(shù)swap中的形參x和y以及函數(shù)體中定義的變量t在系統(tǒng)中均不存在,參見圖4.2a)。
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用函數(shù)swap傳數(shù)據(jù)值調(diào)用的過程如下:(1)系統(tǒng)為被調(diào)函數(shù)中的局部變量分配存儲(chǔ)。如在例4.3程序中,程序執(zhí)行到第7行時(shí)系統(tǒng)才會(huì)創(chuàng)建變量x、y和t(即為這些變量分配存儲(chǔ)),參見圖4.2b)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用(2)參數(shù)傳遞。傳遞參數(shù)值實(shí)質(zhì)上是將實(shí)參的內(nèi)容拷貝給形參,一旦拷貝完成則實(shí)參與形參就沒有任何關(guān)系。在例4.3程序中,傳遞參數(shù)時(shí)將實(shí)參a的值拷貝給形參x,實(shí)參b的值拷貝給形參y,拷貝完成后實(shí)參變量a、b與形參變量x、y就斷開聯(lián)系,參見圖4.2c)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用(3)控制流程轉(zhuǎn)移到被調(diào)函數(shù)執(zhí)行。在例4.3程序中,參數(shù)調(diào)用完成后程序的控制流程(執(zhí)行順序)就從第7行轉(zhuǎn)移到第12行開始執(zhí)行函數(shù)swap,參見圖4.2c)d)e)。4.1.2值參數(shù)傳遞的函數(shù)調(diào)用(4)控制流程返回主調(diào)函數(shù)。在例4.3程序中,程序執(zhí)行到第14行時(shí)將控制流程返回到第7行的函數(shù)調(diào)用點(diǎn)后。與此同時(shí),調(diào)用swap函數(shù)時(shí)創(chuàng)建的變量x、y和t都自動(dòng)被系統(tǒng)撤消。程序控制流程執(zhí)行到被調(diào)函數(shù)中的return語句或函數(shù)體的函數(shù)的最后一個(gè)右花括號(hào)“}”時(shí),將程序執(zhí)行的控制流程以及被調(diào)函數(shù)的執(zhí)行結(jié)果返回到主調(diào)函數(shù)中的調(diào)用點(diǎn)。特別需要注意的是,隨著程序控制流程的返回,系統(tǒng)會(huì)自動(dòng)收回為被調(diào)函數(shù)的形式參數(shù)和局部變量分配的存儲(chǔ)單元,即在函數(shù)被調(diào)用時(shí)創(chuàng)建的形式參數(shù)和局部變量會(huì)自動(dòng)撤銷。
4.1.2值參數(shù)傳遞的函數(shù)調(diào)用程序執(zhí)行的結(jié)果如下所示:swap調(diào)用前:a=3,b=5swap調(diào)用中:x=5,y=3swap調(diào)用后:a=3,b=5從輸出結(jié)果看到main中a和b的值并沒有交換,原因就是在調(diào)用函數(shù)時(shí),只是把參數(shù)a和b的值拷貝給了x和y。在swap中,只是對(duì)局部變量x、y的值進(jìn)行了交換,并不影響主調(diào)函數(shù)中作為參數(shù)變量a和b。如果需要在被調(diào)函數(shù)中對(duì)主調(diào)函數(shù)中實(shí)際參數(shù)進(jìn)行操作,則需要將主調(diào)函數(shù)中實(shí)際參數(shù)在內(nèi)存中存放的地址起始值傳遞給被調(diào)函數(shù)對(duì)應(yīng)的形式參數(shù),這就是“傳地址調(diào)用”的方法。通過這種方法可以做到“函數(shù)中對(duì)參數(shù)的修改將影響主調(diào)函數(shù)中參數(shù)值”。這就好比在兩個(gè)函數(shù)間開了一個(gè)通道,讓一個(gè)函數(shù)可以操作另外一個(gè)函數(shù)的局部變量。程序演示4.1.2值參數(shù)傳遞的函數(shù)調(diào)用本小節(jié)主要討論指針變量的基本用法和實(shí)際參數(shù)值是地址值時(shí)的函數(shù)調(diào)用問題1)指針和指針變量的概念程序中的任何數(shù)據(jù)對(duì)象在運(yùn)行過程中一旦被使用,就會(huì)對(duì)應(yīng)計(jì)算機(jī)系統(tǒng)內(nèi)存中的一個(gè)地址。由于系統(tǒng)內(nèi)存儲(chǔ)器是按字節(jié)編址的,一個(gè)數(shù)據(jù)對(duì)象有可能占用一至若干個(gè)字節(jié)的存儲(chǔ)單元,在程序設(shè)計(jì)語言中一般將數(shù)據(jù)對(duì)象的名字與其所占用的存儲(chǔ)單元的首地址相對(duì)應(yīng)。在計(jì)算機(jī)系統(tǒng)中,內(nèi)存單元的地址是用有序整型數(shù)進(jìn)行編址的,所以存儲(chǔ)系統(tǒng)的地址序號(hào)本質(zhì)上就是無符號(hào)的整型數(shù)據(jù)。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用什么是指針?我們知道存放在內(nèi)存中的數(shù)據(jù)有些占4字節(jié)(整型),有些占8字節(jié),也就是說只要知道數(shù)據(jù)的起始位置和數(shù)據(jù)類型,計(jì)算機(jī)就可以準(zhǔn)確的訪問這個(gè)數(shù)據(jù)。把起始地址記為數(shù)據(jù)的“地址”,如圖:
4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用A19233.141596.02e+23101……105地址內(nèi)存空間10010110510911720502046char型,占1字節(jié)bint型,占4字節(jié)cfloat型,占4字節(jié)ddouble型,占8字節(jié)pq2046存放的是整數(shù)1923的地址p,2050存放的是浮點(diǎn)數(shù)3.14159的地址q,這就需要我們用一種新的數(shù)據(jù)表示存儲(chǔ)的數(shù)據(jù)是地址而不是其他的數(shù)值。在C中,除了在前面介紹的各種普通數(shù)據(jù)類型之外,還有另外一種特殊性質(zhì)的變量,即指針變量,簡稱指針。
指針是存放一個(gè)數(shù)據(jù)或變量地址的變量。它和普通變量一樣占用一定的存儲(chǔ)空間,不同之處在于:指針存儲(chǔ)的不是普通數(shù)據(jù),而是一個(gè)數(shù)據(jù)或變量的地址。怎么能知道一個(gè)變量的地址呢?
使用運(yùn)算符&!假設(shè)定義一個(gè)整型指針變量,名字是p,定義x為普通整型變量,對(duì)x取地址,&x的值就是變量x的地址。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用intx;int*p;/*變量前加*,表示該變量是指針變量*/p=&x;4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用變量x的地址被裝入指針p的存儲(chǔ)區(qū)域,即p的內(nèi)容就是變量x的地址。如圖示:變量x應(yīng)當(dāng)和指針變量p的類型保持一致。101指針p地址101變量x(a)將x的地址裝入p(b)指針p指向變量x指針p地址101變量xp=&x稱*p為指針p的目標(biāo)變量,也就是變量x,指針除了可以指向變量外,還可以指向內(nèi)存中其它任何一種數(shù)據(jù)結(jié)構(gòu),如數(shù)組、結(jié)構(gòu)體類型和函數(shù)等。指針的定義:例如: int*p,*y; 定義了兩個(gè)整型的指針變量p和y,注意指針變量是p和y,而不是*p和*y 如果有需要,指針變量也可以和同類型的普通變量混合定義。 例如: charch1,ch2,*p; 定義了兩個(gè)字符變量ch1、ch2以及一個(gè)指針變量4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用類型標(biāo)識(shí)符*指針名指針變量賦值的方法有兩種:一種是;(1)使用賦值號(hào)的一般形式為:
指針變量名=地址值;(2)另外一種是指針變量在定義時(shí)進(jìn)行初始化,一般形式為:
數(shù)據(jù)類型符*指針變量名=初始化地址值;
4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用
例如:intx,*y=&x;
/*定義了變量x和指針變量y,并將x的首地址賦值給y*/或
intx,*y; /*定義變量x和指針變量y*/ y=&x;/*將變量x的首地址賦值給指針變量y*/(假設(shè)x的值為100,X對(duì)應(yīng)的存儲(chǔ)單元的首地址是25000,則指針變量y和它指向的變量x之間的關(guān)系如圖)2500025000100xy10025000xya)b)圖4.3指針變量y與變量x的存儲(chǔ)關(guān)系圖4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用深入理解指針運(yùn)算符*和地址運(yùn)算符&如前例:*y是y所指向的變量,即x,*是一個(gè)指針運(yùn)算符,y是運(yùn)算對(duì)象,下列賦值語句結(jié)果一樣:
對(duì)整型變量x取地址,下列操作等同*(&x)表示的含義呢?表示x本身4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用x=8;或*y=8;&x或&(*y)在C程序設(shè)計(jì)中,對(duì)于指針變量的理解和使用時(shí)還應(yīng)該特別注意以下幾點(diǎn):⑴在指針變量的定義形式中,星號(hào)(*)只是一個(gè)標(biāo)志,表示其后面的變量是指針變量。例如,在指針變量定義語句intx,*y;中,y是指針變量。⑵一個(gè)指針變量只能指向與它同類型的普通變量,即只有數(shù)據(jù)類型相同時(shí)普通變量才能將自己存儲(chǔ)單元的首地址賦值給指針變量,其原因是不同類型的變量所占存儲(chǔ)單元的字節(jié)數(shù)是不同的。intx;float*ptr;ptr=&x;/*錯(cuò)誤,指針變量沒有指向合適的數(shù)據(jù)對(duì)象*/但在這種情況下有一個(gè)特例,可以將任何數(shù)據(jù)類型對(duì)象的存儲(chǔ)首地址賦值給void類型(空類型)的指針變量,例如:intx; void*p=&x; /*將整型變量x的存儲(chǔ)首地址賦值給空類型指針變量p*/4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用⑶指針變量只能在有確定的指向后才能正常使用,也就是說指針變量中必須要有確定的地址。沒有確定指向的指針稱為“空指針”或稱為“懸掛指針”,使用這種指針變量有可能引起不可預(yù)知的錯(cuò)誤。⑷指針變量中只能存放地址值,不能把除NULL外的整型常數(shù)直接賦給指針變量。例如,下面的指針變量的賦值是錯(cuò)誤的:int*ptr;ptr=100;/*錯(cuò)誤,整型常數(shù)值直接賦給指針變量*/
以下是正確的:
float*p=NULL;/*定義實(shí)型指針變量p并將其初始化為常量NULL*/ 或者float*p;
/*定義實(shí)型指針變量p*/
p=NULL;
/*將符號(hào)常量NULL賦值給指針變量p*/4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用3.指針變量的引用怎樣用指針運(yùn)算符來處理數(shù)據(jù)呢?設(shè)變量x、y同類型,把x復(fù)制到y(tǒng)中,可采取下列方法:直接賦值: y=x;使用指針:設(shè)指針變量p用于保存x的地址: p=&x;再執(zhí)行語句 y=*p;例如下列程序段
intx=20,y,*ptr;ptr=&x;y=*ptr;該程序段的意思為:定義整型變量x(初值為20),y和指針*ptr,將變量x的地址賦給指針變量ptr,然后以指針變量ptr的值為內(nèi)存單元地址,將該單元的數(shù)據(jù)取出賦給變量y,相當(dāng)于語句y=x;例如有語句序列為:
intx,*y;y=&x;此時(shí)&x等價(jià)于y,而*y則等價(jià)于變量x。在這種情況下,有下面的等價(jià)關(guān)系的:scanf("%d",&x);等價(jià)于scanf("%d",y);printf(“%d\n”,x);等價(jià)于printf("%d\n",*y);在編寫程序過程,注意的幾個(gè)概念:設(shè)有指針變量pP指針變量,它的內(nèi)容是地址值。*p指針的目標(biāo)變量,它的內(nèi)容是數(shù)據(jù)(p地址的數(shù)據(jù))。&p指針變量的地址,即“地址的地址”。NULL空指針,表示指針內(nèi)容為0p=NULL;/*等價(jià)于p=0*/4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用例4.4取地址運(yùn)算符(&)和指針運(yùn)算符(*)的使用示例。/*Name:ex04-04.cpp*/#include<stdio.h>voidmain(){ intx=200,*y; y=&x; *y=300; printf("%x:%d,%d\n",y,x,*y);}程序執(zhí)行的結(jié)果為:13ff7c:300,300(注意變量y的十六進(jìn)制值在不同的機(jī)器上可能是不同的)。程序演示4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用以16進(jìn)制形式輸出無符號(hào)整數(shù)4.地址值參數(shù)傳遞調(diào)用
函數(shù)調(diào)用時(shí)如果被調(diào)函數(shù)的形參用指針型參數(shù)(即某種數(shù)據(jù)類型的指針變量作為函數(shù)的形式參數(shù)),則主調(diào)函數(shù)中的實(shí)參就必須是指針值(地址)。這種在函數(shù)調(diào)用過程中傳遞主調(diào)函數(shù)實(shí)際參數(shù)的指針(即實(shí)際參數(shù)存儲(chǔ)單元的首地址)的方式提供了在被調(diào)函數(shù)中操作主調(diào)函數(shù)中實(shí)際參數(shù)的可能性。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用例4.5地址值參數(shù)傳遞函數(shù)調(diào)用示例。/*Name:ex04-05.cpp*/#include<stdio.h>voidmain(){ voidswap(int*x,int*y);/*函數(shù)聲明中形參是指針變量*/ inta=3,b=5; printf("swap函數(shù)調(diào)用前:a=%d,b=%d\n",a,b);
swap(&a,&b);/*實(shí)參也必須為地址*/ printf("swap函數(shù)調(diào)用后:a=%d,b=%d\n",a,b);}voidswap(int*x,int*y)/*函數(shù)定義中形參是指針變量*/{ intt;/*注意t不是指針變量,是被指針指向的變量*/ t=*x; *x=*y; *y=t;}4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用執(zhí)行過程如圖:3510002000xyabta)參數(shù)傳遞過程中3510002000xyabtb)參數(shù)傳遞完成后35100020003xyabtc)t=*x執(zhí)行后55100020003xyabtd)*x=*y執(zhí)行后53100020003xyabte)*y=t執(zhí)行后圖4.4地址值傳遞函數(shù)調(diào)用時(shí)參數(shù)的變化情況4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用程序執(zhí)行后的輸出結(jié)果為:swap函數(shù)調(diào)用前:a=3,b=5swap函數(shù)調(diào)用后:a=5,b=3從上面程序執(zhí)行的過程可以得出使用地址傳送方式在函數(shù)之間傳遞數(shù)據(jù)的特點(diǎn)是:數(shù)據(jù)在主調(diào)函數(shù)和被調(diào)函數(shù)中均使用同一存儲(chǔ)單元,所以在被調(diào)函數(shù)中對(duì)形參數(shù)據(jù)任何的變動(dòng)必然會(huì)反映到主調(diào)函數(shù)中來。5.指針變量與被指針指向變量的區(qū)別從上面程序執(zhí)行的過程t=*x;*x=*y;*y=t;可以看出在操作的對(duì)象是被指針指向變量。而下面這個(gè)例子是交換的對(duì)象是指針變量本身,體會(huì)它們的不同之處。程序演示4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用例4.6地址值參數(shù)傳遞函數(shù)調(diào)用示例。/*Name:ex04-06.cpp*/#include<stdio.h>voidmain(){ voidswap(int*x,int*y); inta=3,b=5; printf("swap函數(shù)調(diào)用前:a=%d,b=%d\n",a,b); swap(&a,&b); printf("swap函數(shù)調(diào)用后:a=%d,b=%d\n",a,b);}voidswap(int*x,int*y){ int*t;/*t是指針變量*/ t=x; x=y; y=t;}4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用執(zhí)行過程如圖:3510002000xyabta)參數(shù)傳遞過程中3510002000xyabtb)參數(shù)傳遞完成后35100020001000xyabtc)t=x執(zhí)行后35200020001000xyabtd)x=y執(zhí)行后35200010001000xyabte)y=t執(zhí)行后圖4.5地址值傳遞函數(shù)調(diào)用時(shí)參數(shù)的變化情況4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用程序執(zhí)行的結(jié)果并沒使得主函數(shù)中的實(shí)參變量a和b交換內(nèi)容。程序執(zhí)行的結(jié)果為:swap函數(shù)調(diào)用前:a=3,b=5swap函數(shù)調(diào)用后:a=3,b=5程序演示4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用雖然在被調(diào)用函數(shù)中使用指針型參數(shù)就提供了在被調(diào)函數(shù)中操作主調(diào)函數(shù)中實(shí)際參數(shù)的可能性。但并不是用了指針變量作函數(shù)的形式參數(shù)就一定可以在被調(diào)函數(shù)中操作或修改主調(diào)函數(shù)中的實(shí)參。在被調(diào)函數(shù)中是否能夠操作或修改主調(diào)函數(shù)中實(shí)參值還要取決于在被調(diào)函數(shù)中對(duì)指針形參的操作方式,操作指針形參變量指向的對(duì)象(即實(shí)參本身)則可以達(dá)到在被調(diào)函數(shù)中操作或修改主調(diào)函數(shù)實(shí)參的目的;但若操作的是指針形參變量本身則不能實(shí)現(xiàn)在被調(diào)函數(shù)中操作或修改主調(diào)函數(shù)實(shí)際參數(shù)的目的。4.1.3指針基本概念和地址值參數(shù)傳遞函數(shù)調(diào)用
在C程序設(shè)計(jì)中,既可以用數(shù)組的元素作為函數(shù)的參數(shù),也可以將數(shù)組看成一個(gè)整體作為函數(shù)的參數(shù)。
使用數(shù)組元素作為參數(shù)傳遞,其用法都與普通變量用法一樣,實(shí)現(xiàn)的是函數(shù)間的傳值調(diào)用。而用數(shù)組名作為實(shí)參,是傳遞的是數(shù)組地址。
例如4.7程序在執(zhí)行中,對(duì)于主函數(shù)中傳遞過來的一維數(shù)組a和二維數(shù)組b的每一個(gè)數(shù)組元素,利用自定義函數(shù)myprint進(jìn)行輸出。4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用程序演示/*Name:ex04-07.cpp*/#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5voidmain(){ voidmyprint(intx); inta[N],b[N][N],i,j; srand(time(NULL)); printf("下面是數(shù)組a的數(shù)據(jù)...\n"); for(i=0;i<N;i++) { a[i]=rand()%100;
myprint(a[i]); }printf("\n下面是數(shù)組b的數(shù)據(jù)...\n");for(i=0;i<N;i++){for(j=0;j<N;j++){b[i][j]=rand()%100;
myprint(b[i][j]);}printf("\n");
}}voidmyprint(intx){ printf("%4d",x);}4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用將數(shù)組看成一個(gè)整體作為函數(shù)參數(shù)時(shí),用數(shù)組名作為函數(shù)的形式參數(shù)或?qū)嶋H參數(shù),實(shí)現(xiàn)的是函數(shù)間的傳地址值調(diào)用。先認(rèn)識(shí)指針與數(shù)組的關(guān)系:intarray[9],*ptr;ptr=array;或者intarray[9],*ptr;ptr=&array[0]/*表示指針ptr指向了數(shù)組array的首地址*/補(bǔ)充:為何數(shù)組名是一個(gè)(首)地址ptrarrayarray[0]*ptrarray[i]array[1]array[2]array[3]*(ptr+1)*(ptr+2)*(ptr+3)*(ptr+i)如圖:數(shù)組與指針的關(guān)系,當(dāng)數(shù)組名傳給函數(shù)時(shí),傳送的是數(shù)組的起始位置
1.一維數(shù)組名作為函數(shù)參數(shù)實(shí)現(xiàn)的是“傳地址值調(diào)用”,其本質(zhì)是將它的全部存儲(chǔ)區(qū)域或者部分存儲(chǔ)區(qū)域提供給形式參數(shù)數(shù)組共享,即形參數(shù)組與實(shí)參數(shù)組是同一存儲(chǔ)區(qū)域或者形參數(shù)組是實(shí)參數(shù)組存儲(chǔ)區(qū)域的一部分。存儲(chǔ)關(guān)系如下圖:實(shí)參數(shù)組a…形參數(shù)組b[]注:形參數(shù)組b本質(zhì)上是指針變量圖4.6數(shù)組存儲(chǔ)區(qū)域全部共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用需要把實(shí)參數(shù)組中從某個(gè)元素值后的部分傳遞給被調(diào)函數(shù)中的形參數(shù)組,則使用實(shí)參數(shù)組某個(gè)元素的地址(參見圖4.7)。
實(shí)參數(shù)組&a[2]…形參數(shù)組b[]注:形參數(shù)組b本質(zhì)上是指針變量圖4.7數(shù)組存儲(chǔ)區(qū)域部分共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用例4.8編制求和函數(shù)并通過該函數(shù)求數(shù)組的元素值和。intsum(intv[],intn){ inti,s=0; for(i=0;i<n;i++) s+=v[i]; returns;}/*Name:ex04-08.cpp*/#include<stdio.h>#defineN10voidmain(){intsum(intv[],intn);/*v表示一維數(shù)組,n表示其長度*/inta[N]={1,2,3,4,5,6,7,8,9,10},total;total=sum(a,N);/*調(diào)用時(shí)將數(shù)組名a作為實(shí)參傳遞給形參v,首地址默認(rèn)為0,也可以寫作&a[0]*/printf("total=%ld\n",total);}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用例4.9編制求和函數(shù)并通過該函數(shù)求數(shù)組自某一元素后的所有元素值和,起始點(diǎn)元素序號(hào)從鍵盤上輸入。/*Name:ex04-09.cpp*/#include<stdio.h>#defineN10voidmain(){intsum(intv[],intn);inta[N]={1,2,3,4,5,6,7,8,9,10},total,pos;printf("請(qǐng)輸入求和起始元素序號(hào):");scanf("%d",&pos);
total=sum(&a[pos],N-pos);/*調(diào)用時(shí)將數(shù)組a[pos]作為實(shí)參首地址傳遞給形參v,*/printf("total=%ld\n",total);}intsum(intv[],intn){ inti,s=0; for(i=0;i<n;i++) s+=v[i]; returns;}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用比較例4.8和例4.9的程序,可以發(fā)現(xiàn)函數(shù)sum沒有任何改變,程序中有所改變的是主調(diào)函數(shù)中的調(diào)用表達(dá)式:sum(&a[pos],N-pos),其中,參數(shù)&a[pos]表示將數(shù)組a自a[pos]元素以后的元素全部提供給形參數(shù)組共享,N-pos是傳遞到函數(shù)total中共享的數(shù)組元素個(gè)數(shù)。4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用2.二維數(shù)組作函數(shù)的參數(shù)
數(shù)組a的起始地址數(shù)組的起始地址表示方法a 表示平面的起始地址(二級(jí)地址)&a[0][0]表示線性的起始地址(一級(jí)地址)a[0]表示線性的起始地址(一級(jí)地址)*a表示線性的起始地址(一級(jí)地址)圖4.8二維數(shù)組起始地址的表示方法示意
二維數(shù)組在存儲(chǔ)時(shí)也是有序地占用一片連續(xù)的內(nèi)存區(qū)域,數(shù)組的名字表示這段存儲(chǔ)區(qū)域的首地址。需要特別注意的是,二維數(shù)組起始地址有多種表示方法,而且這些表示方法在物理含義上還有表示平面起始地址和表示線性起始地址之分,所以在使用二維數(shù)組的起始地址使必須注意區(qū)分需要用哪一種起始地址。
4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用(1)用二維數(shù)組名字作為實(shí)際參數(shù)實(shí)參用a,形參用b[][5]圖4.9實(shí)際參數(shù)為二維數(shù)組名字,用二維數(shù)組名作為函數(shù)參數(shù)實(shí)現(xiàn)的是“傳地址值調(diào)用”,其本質(zhì)仍然是在函數(shù)調(diào)用期間實(shí)際參數(shù)數(shù)組將它的全部存儲(chǔ)區(qū)域提供給形式參數(shù)數(shù)組共享,即形參數(shù)組與實(shí)參數(shù)組是同一存儲(chǔ)區(qū)域。實(shí)參用a形參用b[][5]圖4.9實(shí)際參數(shù)為二維數(shù)組名字4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用用二維數(shù)組名字作為實(shí)際參數(shù)傳地址調(diào)用例4.10編制求二維矩陣最大元素的函數(shù)(假定矩陣為3行4列),用相應(yīng)主函數(shù)進(jìn)行測試。/*Name:ex04-10.cpp*/#include<stdio.h>#defineM3#defineN4voidmain(){ intmax(intv[][N]); inta[M][N]={38,23,56,9,56,2,789,45,76,7,45,34}; printf("Maxvalueis:%d\n",max(a));}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用intmax(intv[][N]) //注意數(shù)組參數(shù)只能省略最高維的長度指定{ inti,j,maxv; maxv=v[0][0]; for(i=0;i<M;i++) for(j=0;j<N;j++) if(v[i][j]>maxv) maxv=v[i][j]; returnmaxv;}程序演示4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用例4.10程序的函數(shù)max中使用了二維數(shù)組樣式的形式參數(shù)接收從主調(diào)函數(shù)中傳遞過來的二維數(shù)組首地址,使得形參數(shù)組v共享實(shí)參數(shù)組a的存儲(chǔ)區(qū)域;然后通過對(duì)形參數(shù)組v的操作達(dá)到操作是參數(shù)a的目的,即在形參數(shù)數(shù)組v中尋找最大值實(shí)質(zhì)上是在實(shí)參數(shù)組a中尋找最大值,程序執(zhí)行的結(jié)果為:Maxvalueis:789。該函數(shù)雖然能求出矩陣的最大元素,但有一個(gè)致命弱點(diǎn),它只能求出3行4列矩陣的最大元素。其根本原因是:使用高維數(shù)組名作函數(shù)的形參時(shí),必須要制定除最高維以外的所有維的長度。為編制較通用的函數(shù),可以使用一維數(shù)組名作形參,此時(shí),可以不制定長度,但仍然要注意一下2點(diǎn):(1)調(diào)用時(shí)的實(shí)參必須是一維數(shù)組的地址(指針)形式。如圖4.8的一級(jí)地址。(2)在函數(shù)中每一行的長度由程序員自己控制,應(yīng)該從主調(diào)函數(shù)中傳遞過來。4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用(2)用二維數(shù)組起始地址的一級(jí)地址形式作為實(shí)際參數(shù)使用一維數(shù)組樣式的形式參數(shù)接收二維數(shù)組實(shí)參,數(shù)組存儲(chǔ)區(qū)域全部共享或部分共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系如圖4.10所示。
4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用實(shí)參數(shù)組a…形參數(shù)組b[]注:形參數(shù)組b本質(zhì)上是指針變量圖4.6數(shù)組存儲(chǔ)區(qū)域全部共享時(shí)形參數(shù)組與實(shí)參數(shù)組的關(guān)系例4.11重新編制例4.10中的函數(shù)max,使其能夠處理任意行列的二維數(shù)組。/*Name:ex04-11.cpp*/#include<stdio.h>#defineM3#defineN4voidmain(){ intmax(intv[],intm,intn); inta[M][N]={38,23,56,9,56,2,789,45,76,7,45,34}; printf("Maxvalueis:%d\n",max(a[0],M,N));}4.1.4數(shù)組參數(shù)傳遞函數(shù)調(diào)用intmax(intv[],intm,intn){ inti,j,maxv; maxv=v[0]; for(i=0;i<m;i++) for(j=0;j<n;j++) if(v[i*n+j]>maxv) maxv=v[i*n+j]; returnmaxv;}程序中函數(shù)max用一維數(shù)組形參v來接收從主調(diào)函數(shù)中傳遞過來的二維數(shù)組首地址,注意到二維數(shù)組的名字表示的是二級(jí)地址,所以被傳遞的二維數(shù)組的首地址不能直接用二維數(shù)組名表示而應(yīng)該使用3種一級(jí)地址形式,本示例中使用的是a[0],還可以使用&a[0][0]和*a形式。在被調(diào)函數(shù)中將傳遞過來的二維數(shù)組當(dāng)作一維數(shù)組處理,其元素對(duì)應(yīng)關(guān)系應(yīng)該是:a[i][j]→v[i*n+j]。程序執(zhí)行的結(jié)果為:Maxvalueis:789。程序演示函數(shù)的定義和調(diào)用函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的作用域和生存期編譯預(yù)處理多源文件C程序的組織方法第4章函數(shù)與程序結(jié)構(gòu)4.2.1函數(shù)的嵌套調(diào)用在C程序中函數(shù)不能嵌套定義。但C語言允許函數(shù)嵌套調(diào)用,所謂函數(shù)的嵌套調(diào)用就是一個(gè)函數(shù)在自己被調(diào)用的過程中又調(diào)用了另外的函數(shù)。一個(gè)兩層嵌套函數(shù)調(diào)用的過程如圖4.10。主函數(shù)函數(shù)fun1函數(shù)fun2程序運(yùn)行結(jié)束調(diào)用函數(shù)fun1調(diào)用函數(shù)fun2fun1執(zhí)行結(jié)束fun2執(zhí)行結(jié)束圖4.10兩層函數(shù)嵌套調(diào)用示意圖4.2函數(shù)的嵌套調(diào)用和遞歸調(diào)用例4.12編程序計(jì)算要求對(duì)n項(xiàng)的求和以及每一項(xiàng)ik的計(jì)算都用獨(dú)立的函數(shù)實(shí)現(xiàn),k和n的值在主函數(shù)中從鍵盤輸入。程序設(shè)計(jì)思路:可以把問題分解為兩個(gè)模塊:求冪次方模塊和求和模塊,在求和模塊中要包含求冪模塊。f1()函數(shù)的參數(shù)為n和k,其返回值是n的k次方。f2()函數(shù)的參數(shù)為n和k,返回值是冪次方的累加和。4.2.1函數(shù)的嵌套調(diào)用#include<stdio.h>longf1(intn,intk)
{longpower=n;inti;for(i=1;i<k;i++)power*=n;returnpower;}longf2(intn,intk) {longsum=0;inti;for(i=1;i<=n;i++)sum+=f1(i,k);returnsum;}voidmain(){intn,k;
scanf(“%d,%d”,&n,&k);printf("Sumof%dpowersofintegersfrom1to%d=",k,n);printf("%d\n",f2(n,k));}輸入:4,5結(jié)果:Sumof5powersofintegersfrom1to4=1300該程序中,main()中調(diào)用了f2()函數(shù),而f2()函數(shù)中又調(diào)用了f1()函數(shù),這就是函數(shù)的嵌套調(diào)用。程序演示4.2.1函數(shù)的嵌套調(diào)用
一個(gè)函數(shù)直接地或間接地自己調(diào)用自己,稱為函數(shù)的遞歸調(diào)用。特點(diǎn)為:(1)遞歸調(diào)用中每次嵌套調(diào)用的函數(shù)都是該函數(shù)本身;(2)遞歸調(diào)用不會(huì)無限制進(jìn)行下去,即這種特殊的自己對(duì)自己的嵌套調(diào)用總會(huì)在某種條件下結(jié)束。(3)遵從”先進(jìn)后出“規(guī)則。遞歸調(diào)用的實(shí)現(xiàn)依靠系統(tǒng)提供一個(gè)特殊部件(堆棧)存放未完成的操作。計(jì)算機(jī)系統(tǒng)的堆棧是一段先進(jìn)后出(FILO)的存儲(chǔ)區(qū)域,系統(tǒng)在遞歸調(diào)用時(shí)將在遞歸過程中應(yīng)該執(zhí)行而未執(zhí)行的操作依次從堆棧棧底開始存放,當(dāng)遞歸結(jié)束回溯時(shí)再依存放時(shí)相反的順序?qū)⑺鼈儚亩褩V腥〕鰜韴?zhí)行,在壓棧和出棧操作中,系統(tǒng)使用堆棧指針指示出應(yīng)該存入和取出數(shù)據(jù)的位置。4.2.2函數(shù)的遞歸調(diào)用例4.13函數(shù)遞歸調(diào)用示例(使用遞歸調(diào)的方法反向輸出字符串)。1 /*Name:ex04-13.cpp*/2 #include<stdio.h>3 voidmain()4 { voidreverse();5 printf("輸入一個(gè)字符串,以'#'作為結(jié)束字符:");6 reverse();7 printf("\n");8 }9 voidreverse()10 { charch;11 ch=getchar();12 if(ch=='#')13 putchar(ch);14 else15 { reverse();16 putchar(ch);17 }18 }執(zhí)行如下圖4.2.2函數(shù)的遞歸調(diào)用所以程序執(zhí)行時(shí)輸入數(shù)據(jù)為字符串:abc#,則輸出數(shù)據(jù)為字符串:#cba。topa)空棧topputchar(‘a(chǎn)’)topc)putchar(‘a(chǎn)’)putchar(‘b’)topd)
putchar(‘a(chǎn)’)putchar(‘b’)putchar(‘c’)tope)
putchar(‘a(chǎn)’)putchar(‘b’)topputchar(‘a(chǎn)’)b)
f)
topg)空棧圖4.11遞歸調(diào)用時(shí)系統(tǒng)堆棧數(shù)據(jù)的變化示意圖程序演示4.2.2函數(shù)的遞歸調(diào)用例4.14編程序使用遞歸方式求n!。/*Name:ex04-14.cpp*/#include<stdio.h>voidmain(){ longfac(longn); longn,result; printf("Inputthen:"); scanf("%ld",&n);
result=fac(n); printf("%ld!=%ld\n",n,result);}longfac(longn){ if(n<=1) return1; else returnfac(n-1)*n;}4.2.2函數(shù)的遞歸調(diào)用fac(5)等于120執(zhí)行如下:程序演示4.2.2函數(shù)的遞歸調(diào)用fac(4)*5fac(3)*4*5fac(2)*3*4*5fac(1)*2*3*4*5調(diào)用返回fac(5)fac(5)等于120fac(5)→fac(4)*5fac(4)→fac(3)*4fac(3)→fac(2)*3fac(2)→fac(1)*2fac(1)→1遞歸壓棧方向fac(2)→fac(1)*2→1*2→2fac(3)→fac(2)*3→2*3→6fac(4)→fac(3)*4→6*4→24fac(5)→fac(4)*5→24*5→120遞歸回溯方向圖4.12函數(shù)遞歸調(diào)用過程示意圖執(zhí)行如下:程序演示4.2.2函數(shù)的遞歸調(diào)用
遞歸是程序設(shè)計(jì)中一種非常重要的技術(shù),與程序設(shè)計(jì)中其它控制方法策略相比較,遞歸程序設(shè)計(jì)的難度在于遞歸在人類社會(huì)的現(xiàn)實(shí)生活中沒有直接對(duì)應(yīng)的概念存在,而必須通過推理分析才能理解遞歸思想進(jìn)而實(shí)現(xiàn)遞歸程序設(shè)計(jì)。在實(shí)際設(shè)計(jì)遞歸函數(shù)程序時(shí),我們可以將重點(diǎn)放在分析遞推公式和遞歸終止條件上,可以忽略系統(tǒng)的具體執(zhí)行過程,只要算法和遞推公式正確,結(jié)論一定是正確的。4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)遞歸的實(shí)質(zhì)是一種簡化復(fù)雜問題求解的方法,它將問題逐步簡化直至趨于已知條件。在簡化的過程中必須保證問題的性質(zhì)不發(fā)生變化,即在簡化的過程中必須保證兩點(diǎn):一是問題簡化后具有同樣的形式;二是問題簡化后必須趨于比原問題簡單一些。具體使用遞歸技術(shù)時(shí),必須能夠?qū)栴}簡化分解為遞歸方程(即問題的形式)和遞歸結(jié)束條件(即最簡單的解)兩個(gè)部分。如例4.14求n的階乘,可以分解得到遞歸方程:n*(n-1)!和遞歸結(jié)束條件:n<=1時(shí)階乘為1。4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)例4.15求菲波拉契數(shù)列。已知一對(duì)小兔出生一個(gè)月后變成一對(duì)成兔,兩個(gè)月后這對(duì)成兔就會(huì)生出一對(duì)小兔,三個(gè)月后這對(duì)成兔將生出第二對(duì)小兔,而第一對(duì)小兔又長大變成一對(duì)成兔,即一月成熟,二月生育,如此類推。請(qǐng)用計(jì)算機(jī)求解一對(duì)小兔經(jīng)n月后將繁衍成多少對(duì)兔子?4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)可以分析出如下遞歸關(guān)系:按照上面分析得到的遞歸方程和結(jié)束條件,求菲波拉契數(shù)列的遞歸算法可以設(shè)計(jì)為如圖4.13所示。n=0或者n=1fib(n)retuan1returnfib(n-1)+fib(n-2)TF圖4.13菲波拉契數(shù)列的遞歸算法4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)/*Name:ex04-15.cpp*/#include<stdio.h>voidmain(){ intm; floatfib(intn); printf("請(qǐng)輸入月份數(shù)"); scanf("%d",&m); printf("經(jīng)過%d個(gè)月后,兔子有%.0f對(duì)。\n",m,fib(m));}floatfib(intn){ if(n==0||n==1) return1; else returnfib(n-1)+fib(n-2);}程序演示4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)
例4.16編程序用遞歸方法求兩個(gè)正整數(shù)的最大公約數(shù)。 可以分析得出如下遞歸關(guān)系:r=m%n=0gcd(n)retuannreturn
gcd(n,r)TF圖4.14最大公約數(shù)的遞歸算法4.2.2函數(shù)的遞歸調(diào)4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)/*Name:ex04-16.cpp*/#include<stdio.h>voidmain(){ intGcd(intm,intn); intnum1,num2; printf("請(qǐng)輸入兩個(gè)正整數(shù):"); scanf("%d,%d",&num1,&num2); if(num1<num2) num1=num1+num2,num2=num1-num2,num1=num1-num2; printf("%d與%d的最大公約數(shù)是:%d\n",num1,num2,Gcd(num1,num2));}intGcd(intm,intn){ intr; if((r=m%n)==0) returnn; else returnGcd(n,r);}程序演示4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)通過上面兩個(gè)示例的分析,遞歸方式的實(shí)現(xiàn)也是基于語言的條件控制結(jié)構(gòu)。遞歸函數(shù)設(shè)計(jì)的基本框架是相對(duì)固定的,其一般形式可以描述如下:if遞歸結(jié)束條件成立Return已知結(jié)果else將問題轉(zhuǎn)化為同性質(zhì)的較簡單子問題;以遞歸方式求解子問題(遞歸方程);4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)例4.17漢諾塔(TowerofHanoi)問題。有A、B、C三根桿,最左邊桿上自下而上、由大到小順序串有64個(gè)金盤呈一塔形。現(xiàn)要把左邊A桿上的金盤全部移到右邊C桿上,條件是一次只能移動(dòng)一個(gè)盤,且不允許大盤壓在小盤的上面??梢詫h諾塔問題分解為下面三步遞歸求解:第一步:把a(bǔ)桿上的n-1個(gè)盤子設(shè)法借助b桿放到c桿,記做hanoi(n-1,a,c,b);第二步:把第n個(gè)盤子從a桿移動(dòng)到b桿;第三步:把c桿上的n-1個(gè)盤子借助a桿移動(dòng)到b桿,記做hanoi(n-1,c,b,a);4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)/*Name:ex04-17.cpp*/#include<stdio.h>voidmain(){intn; voidhanoi(intn,chara,charb,charc); printf("\nPleaseinputthenumberofdiskstobemoved:"); scanf("%d",&n); hanoi(n,'a','b','c');}voidhanoi(intn,chara,charb,charc){ if(n==1) printf("\nMovedisc%dfrompile%cto%c",n,a,b); else { hanoi(n-1,a,c,b); printf("\nMovedisc%dfrompile%cto%c",n,a,b); hanoi(n-1,c,b,a); }}程序演示4.2.3遞歸函數(shù)設(shè)計(jì)初步(*)函數(shù)的定義和調(diào)用函數(shù)的嵌套調(diào)用和遞歸調(diào)用變量的作用域和生存期編譯預(yù)處理多源文件C程序的組織方法第4章函數(shù)與程序結(jié)構(gòu)
變量的作用域是指其有效范圍。變量的生存期是指變量存在的時(shí)間。⑴一個(gè)變量在某個(gè)函數(shù)、某個(gè)源程序文件或某幾個(gè)源程序文件范圍內(nèi)是有效的,則稱其有效的范圍為該變量的作用域,在此范圍內(nèi)可以訪問或引用該變量。如果從變量的作用域角度來考慮,變量可分為全局變量和局部變量。⑵一個(gè)變量的值在某一時(shí)刻是存在的,則認(rèn)為這一時(shí)刻屬于該變量的“生存期”,或稱其在此時(shí)刻“存在”。如果從變量的生存期來考慮,變量可分為靜態(tài)存儲(chǔ)變量和動(dòng)態(tài)存儲(chǔ)變量。4.3變量的作用域和生存期從變量作用域概念上將變量分為“全局變量”和“局部變量”兩類。C語言使用extern和auto來表示變量的作用域?qū)傩浴?.全局變量指在所有函數(shù)之外定義的變量,全局變量也稱為外部變量。其作用域(作用范圍)是從定義位置開始直到本源文件結(jié)束為止。定義的一般形式如下:
[extern]<數(shù)據(jù)類型符>變量表;定義全局變量時(shí)一般將extern省略。使用extern,目的是對(duì)程序中定義的全局變量進(jìn)行重新聲明,這種聲明方法的意義和使用方法牽涉到多源程序文件,將在4.5節(jié)中予以討論。在定義全局變量時(shí),也可以對(duì)其進(jìn)行初始化工作。如果在定義全局變量時(shí)沒有顯式初始化,C的編譯系統(tǒng)會(huì)自動(dòng)將其初始化為0(若是字符類數(shù)據(jù)則初始化為’\0’)。4.3.1變量的作用域例4.18全局變量的作用域示例 /*Name:ex04-18.cpp*/2 #include<stdio.h>3 voidincrea();4 voidincreb();5 intx;6 voidmain()7 { x++;8 increa();9 increb();10 printf("x=%d\n",x); 11 }12 voidincrea()13 {14 x+=5;15 }16 voidincreb()17 {18 x-=2;19 }
程序在第5行定義了整型變量,由于變量x定義在所有函數(shù)的外面,所以變量x是全局變量,其作用范圍(作用域)從第5行開始至第19行結(jié)束。同時(shí)由于在定義全局變量x時(shí)沒有對(duì)其顯式初始化。該程序運(yùn)行的結(jié)果為:x=4。
程序演示4.3.1變量的作用域
全局變量X的作用范圍例全局變量的作用域示例 #include<stdio.h>charc1,c2;/*全局變量*/charf1(inta,intb)/*定義函數(shù)f1*/{inti,j;……}inta=5,b=10;/*全局變量*/intf2(intp)/*定義函數(shù)f2*/{intx=a,y=b;……}main()/*主函數(shù)*/{floata,b;/*ab為主函數(shù)內(nèi)的局部變量*/……}
c1、c2、a、b、雖然都是全局變量,但作用的范圍不一樣。c1、c2在開始定義,所以在f1(),f2(),主函數(shù)內(nèi)都有效,而a、僅僅在f2(),主函數(shù)內(nèi)都有效。在主函數(shù)中又定義了2個(gè)局部變量a、b。這時(shí)全局變量不起作用。即當(dāng)全局變量和局部變量同名時(shí),在局部變量作用范圍內(nèi),全局變量不起作用。4.3.1變量的作用域全局變量ab的作用范圍全局變量c1c2的作用范圍例全局變量的使用實(shí)例 #include<stdio.h>intx=3,y=5;intmax(inta,intb){return(a>b?a:b);}main(){intx=8;printf(“max(%d,%d)=%d\n”,x,y,max(x,y));}輸出結(jié)果:max(8,5)=8思考:主函數(shù)中如果沒有intx=8,結(jié)果是多少?如果全局變量x=-3,結(jié)果又是多少?如果要將全局變量作用域擴(kuò)展到其他源文件,在變量定義前加exterm。例如extermintx=3,y=5;4.3.1變量的作用域2.局部變量指定義在函數(shù)內(nèi)部的變量,也稱為自動(dòng)變量。局部變量的作用域有三個(gè),它們是:①函數(shù)形式參數(shù)表部分;②函數(shù)體內(nèi)部;③復(fù)合語句內(nèi)部{}。一般形式:[auto]<數(shù)據(jù)類型符>變量表;auto類型符是局部變量默認(rèn)的存儲(chǔ)類型,一般省略。如果局部變量在定義時(shí)沒有對(duì)其進(jìn)行顯式的初始化則其初始值是隨機(jī)的數(shù)值。局部變量的建立和撤消都是系統(tǒng)自動(dòng)進(jìn)行的,如在某個(gè)函數(shù)中定義了自動(dòng)變量,只有當(dāng)這個(gè)函數(shù)被調(diào)用時(shí)系統(tǒng)才會(huì)為這些局部變量分配存儲(chǔ)單元;當(dāng)函數(shù)執(zhí)行完畢,程序控制流程離開這個(gè)函數(shù)時(shí),自動(dòng)變量被系統(tǒng)自動(dòng)撤銷,其所占據(jù)的存儲(chǔ)單元被系統(tǒng)自動(dòng)收回。4.3.1變量的作用域例4.19局部變量在函數(shù)調(diào)用時(shí)的特征示例。/*Name:ex04-19.cpp*/#include<stdio.h>voidmain(){ intincre(); printf("x=%d\n",incre()); printf("x=%d\n",incre());}intincre(){intx=20; x+=5; returnx;}函數(shù)incre在第一次被調(diào)用時(shí),會(huì)創(chuàng)建局部變量x并賦初值為20,然后對(duì)其進(jìn)行加5的操作并將結(jié)果25返回到主函數(shù)中輸出(注意:隨著函數(shù)執(zhí)行完成后控制流程的返回,函數(shù)中定義的局部變量(自動(dòng)變量)x被系統(tǒng)自動(dòng)撤銷)。當(dāng)函數(shù)incre第二次被調(diào)用時(shí),會(huì)重新創(chuàng)建局部變量x并賦初值為20,然后對(duì)其進(jìn)行加5的操作并將結(jié)果25返回到主函數(shù)中輸出,所以程序執(zhí)行的結(jié)果為:x=25x=25⑴函數(shù)的每次調(diào)用都是使用不同局部變量組。程序演示4.3.1變量的作用域⑵局部變量即使名字相同,互相也無關(guān)系。例4.20編制程序輸出如下所示的字符圖形(每行15個(gè)星號(hào),共輸出5行)。***************************************************************************圖4.15字符圖形/*Name:ex04-20.cpp*/#include<stdio.h>voidmain(){ voidmyprint(); inti; for(i=0;i<5;i++) myprint();}voidmyprint(){ inti; for(i=0;i<15;i++) putchar('*'); printf("\n");}程序演示4.3.1變量的作用域局部變量i的作用范圍局部變量i的作用范圍局部變量只在本函數(shù)或本復(fù)合語句內(nèi)才能使用,main()函數(shù)也不例外,主函數(shù)main定義了變量a,b,只在主函數(shù)有效,c在復(fù)合語句內(nèi)有效,在主函數(shù)其他地方無效?!?main(){floata,b;
……{floatc;c=a*b;
……}}4.3.1變量的作用域局部變量C的作用范圍局部變量a、b的作用范圍3.同名全局變量與局部變量作用域重疊問題在某些特定的情況下,可能會(huì)出現(xiàn)全局變量和局部變量同名,C規(guī)定按“定義就近原則”來使用的變量。⑴在函數(shù)中如果定義有與全局變量同名的局部變量,則當(dāng)程序的控制流程進(jìn)入到函數(shù)的作用范圍時(shí),程序使用在函數(shù)內(nèi)部(包括形式參數(shù)表和函數(shù)體)定義的局部同名變量。⑵在程序的一個(gè)更小局部范圍(復(fù)合語句)中如果定義有與較大范圍(函數(shù)局部或全局)變量同名的變量,則當(dāng)程序的控制流程進(jìn)入到這個(gè)小的(復(fù)合語句)局部范圍時(shí),使用在該小局部范圍內(nèi)所定義的局部同名變量;4.3.1變量的作用域intx;voidmain(){ x++; …}voidf1(){intx=1;{intx=2;x++;}x++;}voidf2(){x++;…}全局變量x的作用域圖4.16全局變量與局部變量作用域重疊示意圖復(fù)合語句內(nèi)部定義的局部變量x的作用域①函數(shù)內(nèi)部定義的局部變量x的作用域②③4.3.1變量的作用域例3-26程序的執(zhí)行結(jié)果為(注意輸出順序): 復(fù)合語句中:x=20主函數(shù)中:x=10函數(shù)f1中:x=0 /*全局變量x沒有顯式初始化,默認(rèn)的初始化值為0*/程序演示4.3.1變量的作用域
變量的生存期即是指變量存在的時(shí)間。從變量的生存期來看,變量可以分為靜態(tài)存儲(chǔ)變量和動(dòng)態(tài)存儲(chǔ)變量。數(shù)據(jù)的這種存儲(chǔ)方法稱之為變量的存儲(chǔ)類型。靜態(tài)存儲(chǔ)變量:程序運(yùn)行時(shí)分配固定存儲(chǔ)空間的變量;動(dòng)態(tài)存儲(chǔ)變量:在程序運(yùn)行期間,根據(jù)需要進(jìn)行動(dòng)態(tài)的分配存儲(chǔ)空間的變量。動(dòng)態(tài)存儲(chǔ)變量能夠提高內(nèi)存的使用效率。4.3.2變量的生存期用戶區(qū)程序區(qū)靜態(tài)存儲(chǔ)區(qū)動(dòng)態(tài)存儲(chǔ)區(qū)變量的存儲(chǔ)區(qū)存放全局變量、局部變量函數(shù)形參變量、局部變量等一個(gè)完整的變量定義格
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 會(huì)計(jì)實(shí)習(xí)期工作總結(jié)
- 會(huì)計(jì)個(gè)人述職報(bào)告怎么寫
- 三千字軍訓(xùn)感言(5篇)
- 醫(yī)師先進(jìn)事跡材料
- 書法協(xié)會(huì)工作計(jì)劃書(11篇)
- 書法活動(dòng)宣傳的標(biāo)語(130句)
- 上課打瞌睡檢討書
- 七夕節(jié)活動(dòng)策劃方案范文15篇
- 個(gè)人的收入證明(6篇)
- 白螞蟻課件教學(xué)課件
- CNAS-CL01:2018(ISO17025:2017)改版后實(shí)驗(yàn)室首次內(nèi)審及管理評(píng)審資料匯總
- 護(hù)理不良事件-PPT課件
- 商業(yè)銀行兩地三中心數(shù)據(jù)容災(zāi)備份方案建議書
- 體育運(yùn)動(dòng)中的二次函數(shù)
- 修改留言條(課堂PPT)
- 銅排載流量表
- 2014121085852風(fēng)力發(fā)電機(jī)組出質(zhì)保期驗(yàn)收標(biāo)準(zhǔn)
- 中南大學(xué)湘雅醫(yī)院特色專病門診和多學(xué)科聯(lián)合門診管理辦法
- 乒乓球比賽分組對(duì)陣表(8人、16人、32人)
- 消防控制室記錄表
- 小學(xué)三年級(jí)下冊(cè)道德與法治課件-8.大家的朋友-部編版(15張)課件
評(píng)論
0/150
提交評(píng)論