在結(jié)構(gòu)化程序設(shè)計(jì)中函數(shù)是將任務(wù)進(jìn)行模塊劃分的基本單位
《在結(jié)構(gòu)化程序設(shè)計(jì)中函數(shù)是將任務(wù)進(jìn)行模塊劃分的基本單位》由會(huì)員分享,可在線閱讀,更多相關(guān)《在結(jié)構(gòu)化程序設(shè)計(jì)中函數(shù)是將任務(wù)進(jìn)行模塊劃分的基本單位(109頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、 在結(jié)構(gòu)化程序設(shè)計(jì)中,函數(shù)是將任務(wù)進(jìn)行模塊劃分的基在結(jié)構(gòu)化程序設(shè)計(jì)中,函數(shù)是將任務(wù)進(jìn)行模塊劃分的基本單位。一個(gè)函數(shù)實(shí)現(xiàn)一項(xiàng)功能。本單位。一個(gè)函數(shù)實(shí)現(xiàn)一項(xiàng)功能。 在面向?qū)ο笤诿嫦驅(qū)ο蟪绦蛟O(shè)計(jì)中,程序設(shè)計(jì)中,函數(shù)是對(duì)數(shù)據(jù)的一項(xiàng)操作,也函數(shù)是對(duì)數(shù)據(jù)的一項(xiàng)操作,也是實(shí)現(xiàn)一項(xiàng)功能。是實(shí)現(xiàn)一項(xiàng)功能。第三章第三章 函數(shù)函數(shù) 要掌握函數(shù)的使用,必須理解函數(shù)調(diào)用時(shí)的內(nèi)部實(shí)現(xiàn)機(jī)要掌握函數(shù)的使用,必須理解函數(shù)調(diào)用時(shí)的內(nèi)部實(shí)現(xiàn)機(jī)制,以及與此相關(guān)的內(nèi)存分配機(jī)制、變量生命期和作用域。制,以及與此相關(guān)的內(nèi)存分配機(jī)制、變量生命期和作用域。 本章還將介紹關(guān)于函數(shù)重載的概念,介紹遞歸算法本章還將介紹關(guān)于函數(shù)重載的概念,介紹遞歸算
2、法、內(nèi)聯(lián)函數(shù)、默認(rèn)參數(shù)函數(shù)以及多文件組織、編譯預(yù)處、內(nèi)聯(lián)函數(shù)、默認(rèn)參數(shù)函數(shù)以及多文件組織、編譯預(yù)處理、工程文件的概念和運(yùn)行庫函數(shù)。理、工程文件的概念和運(yùn)行庫函數(shù)。 練習(xí):編寫程序,輸入練習(xí):編寫程序,輸入x x,根據(jù)下面,根據(jù)下面y y和和x x的關(guān)的關(guān)系,計(jì)算系,計(jì)算y y值并輸出值并輸出3x-11 (x10)x (x1)2x-1 (1xx; cinx; if(x1) y=x; if(x1) y=x; else if(1=x10) y=2 else if(1=x10) y=2* *x-1;x-1; else y=3 else y=3* *x-11;x-11; couty; coutx; ci
3、nx; if(x1) y=x; if(x1) y=x; else if(1=x&x10) y=2 else if(1=x&x10) y=2* *x-1;x-1; else y=3 else y=3* *x-11;x-11; couty; coutx; cinx; if(x1) y=x; if(x1) y=x; else if(1 else if(1x10) y=2x10) y=2* *x-1;x-1; else y=3 else y=3* *x-11;x-11; couty; coutx; cinx; x=10?y=3x-11:y=2x-1 x=10?y=3x-11:y=2x-1 couty;
4、 coutx; cinx; if(x1) y=x; if(x1) y=x; else if(x10) y=2 else if(x10) y=2* *x-1;x-1; else y=3 else y=3* *x-11;x-11; couty; couty; 第三章第三章 函數(shù)函數(shù) 3.1 函數(shù)的定義與調(diào)用函數(shù)的定義與調(diào)用 3. 5 作用域與標(biāo)識(shí)符的可見性作用域與標(biāo)識(shí)符的可見性 3.4 函數(shù)調(diào)用機(jī)制函數(shù)調(diào)用機(jī)制 3.3 全局變量和局部變量全局變量和局部變量 3.2 函數(shù)的參數(shù)傳遞函數(shù)的參數(shù)傳遞,返回值及函數(shù)聲明返回值及函數(shù)聲明 3.10 編譯預(yù)處理編譯預(yù)處理 3.9 頭文件與多文件結(jié)構(gòu)頭文件與多文
5、件結(jié)構(gòu) 3.6 存儲(chǔ)類型與標(biāo)識(shí)符的生命期存儲(chǔ)類型與標(biāo)識(shí)符的生命期 3.8 函數(shù)的一些高級(jí)議題函數(shù)的一些高級(jí)議題 3.7 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用 3.1 函數(shù)的定義與調(diào)用函數(shù)的定義與調(diào)用3.1.1 函數(shù)概述函數(shù)概述3.1.2 函數(shù)的定義函數(shù)的定義3.1.3 函數(shù)的調(diào)用函數(shù)的調(diào)用 3.1.1 函數(shù)概述函數(shù)概述函數(shù)是函數(shù)是C+C+程序的基本組成模塊。程序的基本組成模塊。通過函數(shù),可以把一個(gè)復(fù)雜任務(wù)分解成為若干通過函數(shù),可以把一個(gè)復(fù)雜任務(wù)分解成為若干個(gè)易于解決的小任務(wù)。充分體現(xiàn)逐步細(xì)化的設(shè)計(jì)思個(gè)易于解決的小任務(wù)。充分體現(xiàn)逐步細(xì)化的設(shè)計(jì)思想。想。組成組成C+C+程序的若干函數(shù)中,有一個(gè)稱為程序的若
6、干函數(shù)中,有一個(gè)稱為main()main()(Winmain()Winmain())函數(shù),是程序執(zhí)行的入口,它可以)函數(shù),是程序執(zhí)行的入口,它可以調(diào)調(diào)用其他函數(shù),但不可以被調(diào)用用其他函數(shù),但不可以被調(diào)用。而其他一般。而其他一般函數(shù)既可函數(shù)既可以調(diào)用也可以被調(diào)用。以調(diào)用也可以被調(diào)用。函數(shù)概念的引入:函數(shù)概念的引入:入口函數(shù):入口函數(shù):3.1.1 函數(shù)概述函數(shù)概述main ( )fun2( )fun1( )fun3( )funa( )funb( )func( )圖圖3.1 3.1 函數(shù)調(diào)用層次關(guān)系函數(shù)調(diào)用層次關(guān)系3.1.1 函數(shù)概述函數(shù)概述3.1.1結(jié)束結(jié)束庫函數(shù)和自定義函數(shù):庫函數(shù)和自定義函數(shù):
7、 庫函數(shù)庫函數(shù)或或標(biāo)準(zhǔn)函數(shù)標(biāo)準(zhǔn)函數(shù),是由編譯系統(tǒng)預(yù)定義的,是由編譯系統(tǒng)預(yù)定義的,如一些常用的數(shù)學(xué)計(jì)算函數(shù)、字符串處理函數(shù)、圖如一些常用的數(shù)學(xué)計(jì)算函數(shù)、字符串處理函數(shù)、圖形處理函數(shù)、標(biāo)準(zhǔn)輸入輸出函數(shù)等。形處理函數(shù)、標(biāo)準(zhǔn)輸入輸出函數(shù)等。 庫函數(shù)都按功能分類,集中說明在不同的頭文庫函數(shù)都按功能分類,集中說明在不同的頭文件中件中。用戶只需在自己的程序中包含某個(gè)頭文件,。用戶只需在自己的程序中包含某個(gè)頭文件,就可直接使用該文件中定義的函數(shù)。就可直接使用該文件中定義的函數(shù)。 用戶根據(jù)需要將某個(gè)具有相對(duì)獨(dú)立功能的程序用戶根據(jù)需要將某個(gè)具有相對(duì)獨(dú)立功能的程序定義為函數(shù),稱定義為函數(shù),稱自定義函數(shù)自定義函數(shù)。四
8、個(gè)要素:四個(gè)要素:返回值類型,函數(shù)名,參數(shù)列表和函數(shù)體返回值類型,函數(shù)名,參數(shù)列表和函數(shù)體3.1.2 函數(shù)的定義函數(shù)的定義無參函數(shù)定義格式為:無參函數(shù)定義格式為:數(shù)據(jù)類型數(shù)據(jù)類型函數(shù)名函數(shù)名( (voidvoid)函數(shù)體函數(shù)體 說明:說明: 數(shù)據(jù)類型指函數(shù)數(shù)據(jù)類型指函數(shù)返回值類型返回值類型,可以是任一種數(shù)據(jù)類型。,可以是任一種數(shù)據(jù)類型。沒有返回值應(yīng)將返回值類型定義為沒有返回值應(yīng)將返回值類型定義為voidvoid。 函數(shù)名函數(shù)名采用合法標(biāo)識(shí)符表示。采用合法標(biāo)識(shí)符表示。 對(duì)無參函數(shù),參數(shù)括號(hào)中的對(duì)無參函數(shù),參數(shù)括號(hào)中的voidvoid通常省略,但括號(hào)不通常省略,但括號(hào)不能省略。能省略。 函數(shù)體由一
9、系列語句組成。函數(shù)體由一系列語句組成。函數(shù)體函數(shù)體可以為空,稱為空可以為空,稱為空函數(shù)。函數(shù)。 3.1.2 函數(shù)的定義函數(shù)的定義例例: 打印一個(gè)表頭打印一個(gè)表頭void TableHead ( ) cout*endl;cout* example *endl;cout*=b?a:b; return(x); 有參函數(shù)的參數(shù)表中列出所有有參函數(shù)的參數(shù)表中列出所有形式參數(shù)形式參數(shù)的類型和參數(shù)名的類型和參數(shù)名稱。各參數(shù)即使類型相同也必須分別加以說明。稱。各參數(shù)即使類型相同也必須分別加以說明。 形式參數(shù)簡(jiǎn)稱形參,形式參數(shù)簡(jiǎn)稱形參,只能是變量名只能是變量名,不允許是常量或表,不允許是常量或表達(dá)式。達(dá)式。 W
10、hy?找錯(cuò)誤int f()string s;.return s;f2(int i).int f(int v1,int v2).double square(double x)return x*x;問題:?jiǎn)栴}:定義函數(shù)時(shí)究竟哪些變量應(yīng)當(dāng)作為函數(shù)的參數(shù)?哪些定義函數(shù)時(shí)究竟哪些變量應(yīng)當(dāng)作為函數(shù)的參數(shù)?哪些應(yīng)當(dāng)定義在函數(shù)體內(nèi)?應(yīng)當(dāng)定義在函數(shù)體內(nèi)?原則原則:函數(shù)在使用時(shí)被看成函數(shù)在使用時(shí)被看成 “ “黑匣子黑匣子”,除了輸入輸出外,除了輸入輸出外,其他部分可不必關(guān)心其他部分可不必關(guān)心。從函數(shù)的定義看出,函數(shù)頭正是用來。從函數(shù)的定義看出,函數(shù)頭正是用來反映函數(shù)的功能和使用接口,它所定義的是反映函數(shù)的功能和使
11、用接口,它所定義的是“做什么做什么”。即。即明確了明確了“黑匣子黑匣子”的輸入輸出部分,的輸入輸出部分,輸出就是函數(shù)的返回值,輸出就是函數(shù)的返回值,輸入就是參數(shù)輸入就是參數(shù)。因此,只有那些功能上起自變量作用的變量。因此,只有那些功能上起自變量作用的變量才必須作為參數(shù)定義在參數(shù)表中;函數(shù)體中具體描述才必須作為參數(shù)定義在參數(shù)表中;函數(shù)體中具體描述“如何如何做做”,因此除參數(shù)之外的為實(shí)現(xiàn)算法所需用的變量應(yīng)當(dāng)定義,因此除參數(shù)之外的為實(shí)現(xiàn)算法所需用的變量應(yīng)當(dāng)定義在函數(shù)體內(nèi)。在函數(shù)體內(nèi)。 C+C+中不允許函數(shù)的嵌套定義,即在一個(gè)函數(shù)中定義另一中不允許函數(shù)的嵌套定義,即在一個(gè)函數(shù)中定義另一個(gè)函數(shù)。個(gè)函數(shù)。提
12、示提示3.1.3 函數(shù)的調(diào)用函數(shù)的調(diào)用函數(shù)調(diào)用:函數(shù)調(diào)用: 所謂函數(shù)調(diào)用,就是使程序轉(zhuǎn)去執(zhí)行函數(shù)體。所謂函數(shù)調(diào)用,就是使程序轉(zhuǎn)去執(zhí)行函數(shù)體。 在在C+C+中,除了主函數(shù)外,其他任何函數(shù)都不能單獨(dú)作中,除了主函數(shù)外,其他任何函數(shù)都不能單獨(dú)作為程序運(yùn)行。任何函數(shù)功能的實(shí)現(xiàn)都是通過被主函數(shù)直接或?yàn)槌绦蜻\(yùn)行。任何函數(shù)功能的實(shí)現(xiàn)都是通過被主函數(shù)直接或間接調(diào)用進(jìn)行的。間接調(diào)用進(jìn)行的。 無參函數(shù)的調(diào)用格式:無參函數(shù)的調(diào)用格式: 函數(shù)名函數(shù)名( )( ) 有參函數(shù)的調(diào)用格式:有參函數(shù)的調(diào)用格式: 函數(shù)名函數(shù)名( (實(shí)際參數(shù)表實(shí)際參數(shù)表) )其中實(shí)際參數(shù)簡(jiǎn)稱其中實(shí)際參數(shù)簡(jiǎn)稱實(shí)參實(shí)參,用來將實(shí)際參數(shù)的值傳遞給形參
13、,用來將實(shí)際參數(shù)的值傳遞給形參,因此因此可以是常量、具有值的變量或表達(dá)式可以是常量、具有值的變量或表達(dá)式?!纠纠?.1】 輸入兩個(gè)實(shí)數(shù),輸出其中較大的數(shù)輸入兩個(gè)實(shí)數(shù),輸出其中較大的數(shù) 函數(shù)的調(diào)用規(guī)則1、調(diào)用函數(shù)時(shí),函數(shù)名必須與調(diào)用處的函數(shù)名完全一致。2、實(shí)參的個(gè)數(shù)必須與形參的個(gè)數(shù)一致。3、函數(shù)必須先聲明或定義,后調(diào)用。4、函數(shù)可以直接或間接地自己調(diào)用自己,稱為遞歸調(diào)用。int main() int add(int x, int y); int a=100,b=200,c ; c =add(a,b); .int add (int x, int y ) int z ; z=x+y; return
14、(z);錯(cuò)誤:c=ad(a,b);c=add(a);int add(int , int );3.2 函數(shù)的參數(shù)傳遞、返回值及函數(shù)的參數(shù)傳遞、返回值及函數(shù)聲明函數(shù)聲明 321 函數(shù)的參數(shù)傳遞及傳值調(diào)用函數(shù)的參數(shù)傳遞及傳值調(diào)用 323 函數(shù)聲明函數(shù)聲明322 函數(shù)返回值函數(shù)返回值 參數(shù)傳遞:參數(shù)傳遞: 函數(shù)調(diào)用首先要進(jìn)行參數(shù)傳遞,參數(shù)傳遞的方向是函數(shù)調(diào)用首先要進(jìn)行參數(shù)傳遞,參數(shù)傳遞的方向是由實(shí)由實(shí)參傳遞給形參參傳遞給形參。 傳遞過程是,傳遞過程是,先計(jì)算實(shí)參表達(dá)式的值,再將該值傳遞給先計(jì)算實(shí)參表達(dá)式的值,再將該值傳遞給對(duì)應(yīng)的形參變量對(duì)應(yīng)的形參變量。一般情況下,。一般情況下,實(shí)參和形參的個(gè)數(shù)和排列順
15、實(shí)參和形參的個(gè)數(shù)和排列順序應(yīng)一一對(duì)應(yīng),并且對(duì)應(yīng)參數(shù)應(yīng)類型匹配序應(yīng)一一對(duì)應(yīng),并且對(duì)應(yīng)參數(shù)應(yīng)類型匹配(賦值兼容)(賦值兼容), ,即即實(shí)參的類型可以轉(zhuǎn)化為形參類型。而對(duì)應(yīng)參數(shù)的參數(shù)名則不實(shí)參的類型可以轉(zhuǎn)化為形參類型。而對(duì)應(yīng)參數(shù)的參數(shù)名則不要求相同。要求相同。 3.2.1 函數(shù)的參數(shù)傳遞及傳值調(diào)用函數(shù)的參數(shù)傳遞及傳值調(diào)用 傳值調(diào)用和引用調(diào)用:傳值調(diào)用和引用調(diào)用:按照參數(shù)形式的不同,按照參數(shù)形式的不同,C+有兩種調(diào)用方式:有兩種調(diào)用方式:傳值調(diào)用傳值調(diào)用和和引引用調(diào)用用調(diào)用。傳值調(diào)用傳遞的是實(shí)參的值,本章介紹傳值調(diào)用。傳值調(diào)用傳遞的是實(shí)參的值,本章介紹傳值調(diào)用。在調(diào)用函數(shù)時(shí),一般在主調(diào)函數(shù)和被調(diào)用函數(shù)
16、之間有 信息傳遞 這是由函數(shù)中的參數(shù)參數(shù)來完成的。調(diào)用函數(shù)和被調(diào)用函數(shù)之間的參數(shù)傳遞實(shí)際參數(shù)實(shí)際參數(shù) 形式參數(shù)形式參數(shù)主調(diào)用函數(shù)中的參數(shù)被調(diào)用函數(shù)中的參數(shù)(實(shí)參實(shí)參)(形參形參)int main() int a=5,b=10, c ; c=max(a,b); printf(“c=%dn”, c); return 0;int max(int x, int y) int t; if (xy) t=x; else t=y; return(t); yxa5b10510ct101010int main() int a=5,b=10, c ; c=max(a,b); printf(“c=%dn”, c);
17、 return 0; int max(int x, int y) int t; if (xy) t=x; else t=y; return(t); 信息傳遞原則:信息傳遞原則:實(shí)參到形參實(shí)參到形參單向值傳遞單向值傳遞特點(diǎn):實(shí)參與形參各占用不同的內(nèi)存單元 3.2.1 函數(shù)的參數(shù)傳遞及傳值調(diào)用函數(shù)的參數(shù)傳遞及傳值調(diào)用 傳值調(diào)用:傳值調(diào)用:將實(shí)參的值復(fù)制給形參,在函數(shù)中參加運(yùn)算的將實(shí)參的值復(fù)制給形參,在函數(shù)中參加運(yùn)算的是形參,而實(shí)參不會(huì)發(fā)生任何改變。傳值調(diào)用是形參,而實(shí)參不會(huì)發(fā)生任何改變。傳值調(diào)用起了一種隔離作用。起了一種隔離作用?!纠纠?.2】 實(shí)參和形參對(duì)應(yīng)關(guān)系的示例。實(shí)參和形參對(duì)應(yīng)關(guān)系的示例
18、。注意:注意:【例【例1.3】中調(diào)用函數(shù)】中調(diào)用函數(shù)strcpy(s3, s2),卻實(shí)現(xiàn)了字符數(shù),卻實(shí)現(xiàn)了字符數(shù)組組s2的內(nèi)容復(fù)制到字符數(shù)組的內(nèi)容復(fù)制到字符數(shù)組s3中。這是因?yàn)閿?shù)組名實(shí)際中。這是因?yàn)閿?shù)組名實(shí)際上代表存儲(chǔ)數(shù)組的內(nèi)存的首地址,復(fù)制給形參的是實(shí)參數(shù)上代表存儲(chǔ)數(shù)組的內(nèi)存的首地址,復(fù)制給形參的是實(shí)參數(shù)組的首地址,結(jié)果參加運(yùn)算的是實(shí)參數(shù)組。數(shù)組作為參數(shù)組的首地址,結(jié)果參加運(yùn)算的是實(shí)參數(shù)組。數(shù)組作為參數(shù),定義時(shí)形參用數(shù)組名加一對(duì)方括號(hào),調(diào)用時(shí)實(shí)參只用數(shù),定義時(shí)形參用數(shù)組名加一對(duì)方括號(hào),調(diào)用時(shí)實(shí)參只用數(shù)組名組名 100aFFC2200bFFC4int add (int x, int y) in
19、t z ; z=(+x)+(+y) ; return(z); int main() int a=100,b=200,c ; c =add(a,b); coutcendl; return 0; 100 xFFA2200yFFA4101201302z1094302cFFC6 當(dāng)形參值在函 數(shù)中發(fā)生變化時(shí), 且不影響調(diào)用它的 實(shí)參值的變化。 用途 采用這種數(shù)據(jù)復(fù)制的參數(shù)傳遞方式,每次每個(gè)參數(shù)只能傳遞一個(gè)數(shù)據(jù)。缺點(diǎn)add (a , b) ;int add ( x, y ) A) 11 B) 20 C) 21 D) 31請(qǐng)寫出下列程序的運(yùn)行結(jié)果 main() int x=6,y=7,z=8,r ; r=
20、f (x-,y+,x+y),z-); coutr=ry) t=x; else t=y; return(t); 下面是一個(gè)使用結(jié)構(gòu)化程序設(shè)計(jì)思想開發(fā)的企業(yè)管理下面是一個(gè)使用結(jié)構(gòu)化程序設(shè)計(jì)思想開發(fā)的企業(yè)管理報(bào)表程序的框架。它使用了報(bào)表程序的框架。它使用了函數(shù)聲明函數(shù)聲明。void menu_print();void account_report();void engineering_report();void marketing_report();int main() int choice; do menu_print();cinchoice; while(choice=4); switch(ch
21、oice) case 1: account_report(); break; case 2: engineering_report(); break; case 3: marketing_report(); break; return 0;void menu_print() cout”系統(tǒng)功能:系統(tǒng)功能:”endl; cout”1 財(cái)務(wù)報(bào)表財(cái)務(wù)報(bào)表”endl; cout”2 工程報(bào)表工程報(bào)表”endl; cout”3 市場(chǎng)報(bào)表市場(chǎng)報(bào)表”endl; cout”選擇業(yè)務(wù)序號(hào):選擇業(yè)務(wù)序號(hào):”; void account_report() /生成財(cái)務(wù)報(bào)表生成財(cái)務(wù)報(bào)表void engineering_
22、report() /生成工程報(bào)表生成工程報(bào)表 void marketing_report() /生成市場(chǎng)報(bào)表;生成市場(chǎng)報(bào)表;3.2.3 函數(shù)聲明函數(shù)聲明【例【例3.4】 輸出所有滿足下列條件的正整數(shù)輸出所有滿足下列條件的正整數(shù)m:10m1000且且m、m2、m3均為回文數(shù)。均為回文數(shù)。分析:分析:回文指左右對(duì)稱的序列。如回文指左右對(duì)稱的序列。如121、353等就是回等就是回文數(shù)。判斷整數(shù)是否回文數(shù)用函數(shù)實(shí)現(xiàn),其思想是將文數(shù)。判斷整數(shù)是否回文數(shù)用函數(shù)實(shí)現(xiàn),其思想是將該數(shù)各位拆開后反向組成新的整數(shù),如果該整數(shù)與原該數(shù)各位拆開后反向組成新的整數(shù),如果該整數(shù)與原數(shù)相等則為回文數(shù)。數(shù)相等則為回文數(shù)。m
23、m*m m*m*m11 121 1331101 10201 1030301111 12321 1367631 運(yùn)行結(jié)果:運(yùn)行結(jié)果:3.3 全局變量和局部變量全局變量和局部變量 3.3.1 變量的存儲(chǔ)機(jī)制與變量的存儲(chǔ)機(jī)制與C+的內(nèi)存布局的內(nèi)存布局自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū) ( (動(dòng)態(tài)數(shù)據(jù)動(dòng)態(tài)數(shù)據(jù)) )棧區(qū)(函數(shù)局部數(shù)據(jù))棧區(qū)(函數(shù)局部數(shù)據(jù))(main()main()函數(shù)局部數(shù)據(jù))函數(shù)局部數(shù)據(jù))全局?jǐn)?shù)據(jù)區(qū)全局?jǐn)?shù)據(jù)區(qū)( (全局、靜態(tài)全局、靜態(tài)) )代碼區(qū)(程序代碼)代碼區(qū)(程序代碼) 操作系統(tǒng)為一個(gè)操作系統(tǒng)為一個(gè)C+C+程序的運(yùn)行所分配的內(nèi)程序的運(yùn)行所分配的內(nèi)存分為四個(gè)區(qū)域,如圖存分為四個(gè)區(qū)域,如圖3.3
24、3.3 所示:所示:存儲(chǔ)區(qū)域說明:存儲(chǔ)區(qū)域說明:(1)代碼區(qū)()代碼區(qū)(Code area):存放程序代碼,即程序):存放程序代碼,即程序中各個(gè)函數(shù)的代碼塊;中各個(gè)函數(shù)的代碼塊;(2)全局?jǐn)?shù)據(jù)區(qū)()全局?jǐn)?shù)據(jù)區(qū)(Data area):存放全局?jǐn)?shù)據(jù)和靜):存放全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù);態(tài)數(shù)據(jù);分配該區(qū)時(shí)內(nèi)存全部清零分配該區(qū)時(shí)內(nèi)存全部清零,結(jié)果變量的所有字,結(jié)果變量的所有字節(jié)自動(dòng)初始化為零。節(jié)自動(dòng)初始化為零。(3)棧區(qū)()棧區(qū)(Stack area):存放局部變量,如函數(shù)中):存放局部變量,如函數(shù)中的變量等;的變量等;分配棧區(qū)時(shí)不處理內(nèi)存分配棧區(qū)時(shí)不處理內(nèi)存,即變量取隨機(jī)值。,即變量取隨機(jī)值。(4)自由存
25、儲(chǔ)區(qū)(自由存儲(chǔ)區(qū)(Free store area):):存放與指針相存放與指針相關(guān)的動(dòng)態(tài)數(shù)據(jù)。關(guān)的動(dòng)態(tài)數(shù)據(jù)。分配分配自由存儲(chǔ)自由存儲(chǔ)區(qū)時(shí)不處理內(nèi)存區(qū)時(shí)不處理內(nèi)存。參見第。參見第七章。七章。3.3.1 變量的存儲(chǔ)機(jī)制與變量的存儲(chǔ)機(jī)制與C+的內(nèi)存布局的內(nèi)存布局 3.3.2 全局變量全局變量 在所有函數(shù)之外定義的變量稱為在所有函數(shù)之外定義的變量稱為全局變量全局變量。全局變量在全局變量在編譯時(shí)編譯時(shí)建立在全局?jǐn)?shù)據(jù)區(qū),在未給建立在全局?jǐn)?shù)據(jù)區(qū),在未給出初始化值時(shí)系統(tǒng)自動(dòng)出初始化值時(shí)系統(tǒng)自動(dòng)初始化為全初始化為全0。全局變量可定義在程序開頭,也可定義在中間全局變量可定義在程序開頭,也可定義在中間位置,該全局變
26、量位置,該全局變量在定義處之后在定義處之后的任何位置都是可的任何位置都是可以訪問的,稱為可見的。以訪問的,稱為可見的。【例【例3.5】 多個(gè)函數(shù)使用全局變量的例子。多個(gè)函數(shù)使用全局變量的例子。全局變量引入:全局變量引入:3.3.3 局部變量局部變量 定義在函數(shù)內(nèi)或塊內(nèi)的變量稱為定義在函數(shù)內(nèi)或塊內(nèi)的變量稱為局部變量局部變量。程序中使用的絕大多數(shù)變量都是局部變量。程序中使用的絕大多數(shù)變量都是局部變量。局部變量在局部變量在程序運(yùn)行程序運(yùn)行到它所在的塊時(shí)建立在棧中,到它所在的塊時(shí)建立在棧中,該塊執(zhí)行完畢局部變量占有的空間即被釋放。該塊執(zhí)行完畢局部變量占有的空間即被釋放。局部變量在定義時(shí)可加修飾詞局部變
27、量在定義時(shí)可加修飾詞auto,但通常省略。但通常省略。局部變量在定義時(shí)若未初始化,其值為隨機(jī)數(shù)。局部變量在定義時(shí)若未初始化,其值為隨機(jī)數(shù)。局部變量引入:局部變量引入:【例【例3.6】 使用局部變量的例子。使用局部變量的例子。思考:如果定義思考:如果定義一個(gè)對(duì)象一個(gè)對(duì)象/變量為變量為全局模式還是局全局模式還是局部模式?部模式? 1、主函數(shù)中定義的變量也只用在主函數(shù)中有效;關(guān)于局部變量使用的幾點(diǎn)說明 2、不同函數(shù)中可以使用相同的變量名,且它們代 表不同的存儲(chǔ)單元,互不干擾; 3、形式參數(shù)也是局部變量。其它函數(shù)是不能調(diào)用 該形參的; 4、在一個(gè)函數(shù)內(nèi)部,可以在復(fù)合語句中定義變量 ,這些變量只能在本復(fù)
28、合語句中有效。3.4 函數(shù)調(diào)用機(jī)制函數(shù)調(diào)用機(jī)制 局部變量占用的內(nèi)存是在程序執(zhí)行過程中局部變量占用的內(nèi)存是在程序執(zhí)行過程中“動(dòng)態(tài)動(dòng)態(tài)”地建立地建立和釋放的。這種和釋放的。這種“動(dòng)態(tài)動(dòng)態(tài)”是通過棧由系統(tǒng)自動(dòng)管理進(jìn)行的。是通過棧由系統(tǒng)自動(dòng)管理進(jìn)行的。(1)建立??臻g;)建立??臻g;(6)恢復(fù)現(xiàn)場(chǎng):取主調(diào)函數(shù)運(yùn)行狀態(tài)及返回地址,釋放棧空間;)恢復(fù)現(xiàn)場(chǎng):取主調(diào)函數(shù)運(yùn)行狀態(tài)及返回地址,釋放棧空間;(7)繼續(xù)主調(diào)函數(shù)后續(xù)語句。)繼續(xù)主調(diào)函數(shù)后續(xù)語句。(5)釋放被調(diào)函數(shù)中局部變量占用的??臻g;)釋放被調(diào)函數(shù)中局部變量占用的??臻g;(4)執(zhí)行被調(diào)函數(shù)函數(shù)體;)執(zhí)行被調(diào)函數(shù)函數(shù)體;(3)為被調(diào)函數(shù)中的局部變量分配
29、空間,完成參數(shù)傳遞;)為被調(diào)函數(shù)中的局部變量分配空間,完成參數(shù)傳遞;(2)保護(hù)現(xiàn)場(chǎng):主調(diào)函數(shù)運(yùn)行狀態(tài)和返回地址入棧;)保護(hù)現(xiàn)場(chǎng):主調(diào)函數(shù)運(yùn)行狀態(tài)和返回地址入棧;調(diào)用過程:調(diào)用過程:3.4 函數(shù)調(diào)用機(jī)制函數(shù)調(diào)用機(jī)制 void fun1(int, int);void fun2(float);int main() int x=1;y=2; fun1(x, y); return 0;void fun1(int a,int b) float x=3; fun2(x);void fun2(float y) int x; x棧頂棧頂棧底棧底y3fun2()fun1()運(yùn)行狀態(tài)及返回地址運(yùn)行狀態(tài)及返回地址x3
30、b2a1fun1()main()運(yùn)行狀態(tài)及返回地址運(yùn)行狀態(tài)及返回地址y2x1main()操作系統(tǒng)運(yùn)行狀態(tài)及返回地址操作系統(tǒng)運(yùn)行狀態(tài)及返回地址此圖例說明在程序執(zhí)行過程中怎樣通過棧此圖例說明在程序執(zhí)行過程中怎樣通過?!皠?dòng)態(tài)動(dòng)態(tài)”地建立和地建立和釋放局部變量占用的內(nèi)存的釋放局部變量占用的內(nèi)存的地址地址.0XFE8020X5984D0XFE154 3.5 作用域與標(biāo)識(shí)符的可見性作用域與標(biāo)識(shí)符的可見性3 文件作用域文件作用域 2 函數(shù)聲明作用域函數(shù)聲明作用域 作用域:作用域:指標(biāo)識(shí)符能夠被使用的范圍。只有在作指標(biāo)識(shí)符能夠被使用的范圍。只有在作用域內(nèi)標(biāo)識(shí)符才可以被訪問(稱為可見)。用域內(nèi)標(biāo)識(shí)符才可以被訪問
31、(稱為可見)。本節(jié)重點(diǎn)討論本節(jié)重點(diǎn)討論局部域局部域和文件域(全局域),其中和文件域(全局域),其中局部域包括局部域包括塊域塊域和和函數(shù)聲明域函數(shù)聲明域。任何。任何標(biāo)識(shí)符標(biāo)識(shí)符作用域的作用域的起始點(diǎn)均為起始點(diǎn)均為標(biāo)識(shí)符說明標(biāo)識(shí)符說明處。處。下面分別介紹下面分別介紹:1 塊作用域塊作用域 函數(shù)中定義的標(biāo)識(shí)符,包括形參和函數(shù)體中定義函數(shù)中定義的標(biāo)識(shí)符,包括形參和函數(shù)體中定義的局部變量,作用域都在該函數(shù)內(nèi),也稱作的局部變量,作用域都在該函數(shù)內(nèi),也稱作函數(shù)域函數(shù)域。1. 塊域塊域塊塊指一對(duì)大括號(hào)括起來的程序段。塊中定義的標(biāo)指一對(duì)大括號(hào)括起來的程序段。塊中定義的標(biāo)識(shí)符,作用域在塊內(nèi)。識(shí)符,作用域在塊內(nèi)。復(fù)
32、合語句是一個(gè)塊。復(fù)合語句是一個(gè)塊。函數(shù)也是一個(gè)塊。函數(shù)也是一個(gè)塊。復(fù)合語句中定義的標(biāo)識(shí)符,復(fù)合語句中定義的標(biāo)識(shí)符,作用域僅在該復(fù)合語句中。作用域僅在該復(fù)合語句中?!纠纠?.7】 輸入兩數(shù),按從大到小的順序保存。輸入兩數(shù),按從大到小的順序保存。塊的引入:塊的引入:1. 塊域塊域由由VC+平臺(tái)運(yùn)行,結(jié)果如下:平臺(tái)運(yùn)行,結(jié)果如下:輸入兩整數(shù):輸入兩整數(shù):3 5調(diào)用前:實(shí)參調(diào)用前:實(shí)參a=3,b=5調(diào)用中調(diào)用中交換前:形參交換前:形參a=3,b=5交換后:形參交換后:形參a=5,b=3調(diào)用后:實(shí)參調(diào)用后:實(shí)參a=3,b=5 交換失敗交換失敗局部變量具有局部作用域使得程序在不同塊中可以局部變量具有局部
33、作用域使得程序在不同塊中可以使用同名變量。這些同名變量各自在自己的作用域使用同名變量。這些同名變量各自在自己的作用域中可見,在其它地方不可見。中可見,在其它地方不可見?!纠纠?.8】設(shè)計(jì)函數(shù)完成兩數(shù)交換,用主函數(shù)進(jìn)行測(cè)試。設(shè)計(jì)函數(shù)完成兩數(shù)交換,用主函數(shù)進(jìn)行測(cè)試。1. 塊域塊域 對(duì)于塊中對(duì)于塊中嵌套嵌套其它塊的情況,如果嵌套塊中有同其它塊的情況,如果嵌套塊中有同名局部變量,服從局部?jī)?yōu)先原則,即在內(nèi)層塊中名局部變量,服從局部?jī)?yōu)先原則,即在內(nèi)層塊中屏屏蔽蔽外層塊中的同名變量,換句話說,內(nèi)層塊中局部外層塊中的同名變量,換句話說,內(nèi)層塊中局部變量的作用域?yàn)閮?nèi)層塊;外層塊中局部變量的作用變量的作用域?yàn)閮?nèi)
34、層塊;外層塊中局部變量的作用域?yàn)橥鈱映グ兞康膬?nèi)層塊部分。域?yàn)橥鈱映グ兞康膬?nèi)層塊部分。如果塊內(nèi)定義的局部變量與全局變量同名,塊內(nèi)仍如果塊內(nèi)定義的局部變量與全局變量同名,塊內(nèi)仍然局部變量?jī)?yōu)先,但與塊作用域不同的是,在塊內(nèi)然局部變量?jī)?yōu)先,但與塊作用域不同的是,在塊內(nèi)可以通過域運(yùn)算符可以通過域運(yùn)算符“:”訪問同名的全局變量。訪問同名的全局變量?!纠纠?.9】 顯示同名變量可見性。顯示同名變量可見性。2函數(shù)聲明作用域函數(shù)聲明作用域 函數(shù)聲明不是定義函數(shù),在作函函數(shù)聲明不是定義函數(shù),在作函數(shù)聲明時(shí),其中的形參作用域只在數(shù)聲明時(shí),其中的形參作用域只在聲明中,即聲明中,即作用域結(jié)束于右括
35、號(hào)作用域結(jié)束于右括號(hào)。正是由于形參不能被程序的其他地正是由于形參不能被程序的其他地方引用,所以通常只要聲明形參個(gè)方引用,所以通常只要聲明形參個(gè)數(shù)和類型,數(shù)和類型,形參名可省略形參名可省略。3 3 文件作用域文件作用域 文件作用域文件作用域也稱全局作用域。定義在所有函數(shù)之外的也稱全局作用域。定義在所有函數(shù)之外的標(biāo)識(shí)符,具有文件作用域,作用域?yàn)閺亩x處到整個(gè)標(biāo)識(shí)符,具有文件作用域,作用域?yàn)閺亩x處到整個(gè)源文件結(jié)束。文件中定義的全局變量和函數(shù)都具有文源文件結(jié)束。文件中定義的全局變量和函數(shù)都具有文件作用域。件作用域。如果某個(gè)文件中說明了具有文件作用域的標(biāo)識(shí)符,該如果某個(gè)文件中說明了具有文件作用域的標(biāo)識(shí)
36、符,該文件又被另一個(gè)文件包含,則該標(biāo)識(shí)符的作用域延伸文件又被另一個(gè)文件包含,則該標(biāo)識(shí)符的作用域延伸到新的文件中。如到新的文件中。如cincin和和coutcout是在頭文件是在頭文件iostreamiostream中說明中說明的具有文件作用域的標(biāo)識(shí)符,它們的作用域也延伸到的具有文件作用域的標(biāo)識(shí)符,它們的作用域也延伸到嵌入嵌入iostreamiostream的文件中。的文件中。存儲(chǔ)類型(存儲(chǔ)類型(storage class)決定標(biāo)識(shí)符的存儲(chǔ))決定標(biāo)識(shí)符的存儲(chǔ)區(qū)域,即編譯系統(tǒng)在不同區(qū)域?yàn)椴煌鎯?chǔ)類型的標(biāo)區(qū)域,即編譯系統(tǒng)在不同區(qū)域?yàn)椴煌鎯?chǔ)類型的標(biāo)識(shí)符分配空間。由于存儲(chǔ)區(qū)域不同,標(biāo)識(shí)符的生命識(shí)符分配
37、空間。由于存儲(chǔ)區(qū)域不同,標(biāo)識(shí)符的生命期也不同。所謂生命期,指的是標(biāo)識(shí)符從獲得空間期也不同。所謂生命期,指的是標(biāo)識(shí)符從獲得空間到空間釋放之間的期間,標(biāo)識(shí)符只有在生存期中、到空間釋放之間的期間,標(biāo)識(shí)符只有在生存期中、并且在其自己的作用域中才能被訪問。并且在其自己的作用域中才能被訪問。3.6 存儲(chǔ)類型與標(biāo)識(shí)符的生命期存儲(chǔ)類型與標(biāo)識(shí)符的生命期 自動(dòng)變量為用自動(dòng)變量為用auto說明的變量,通常說明的變量,通常auto缺省。局部變量都是自缺省。局部變量都是自動(dòng)變量,生命期開始于塊的執(zhí)行,結(jié)束于塊的結(jié)束,其原動(dòng)變量,生命期開始于塊的執(zhí)行,結(jié)束于塊的結(jié)束,其原因是自動(dòng)變量的空間分配在棧中,塊開始執(zhí)行時(shí)系統(tǒng)自動(dòng)
38、因是自動(dòng)變量的空間分配在棧中,塊開始執(zhí)行時(shí)系統(tǒng)自動(dòng)分配空間,塊執(zhí)行結(jié)束時(shí)系統(tǒng)自動(dòng)釋放空間。故自動(dòng)變量分配空間,塊執(zhí)行結(jié)束時(shí)系統(tǒng)自動(dòng)釋放空間。故自動(dòng)變量的生命期和作用域是一致的。的生命期和作用域是一致的。3.6.1 存儲(chǔ)類型存儲(chǔ)類型 為提高程序運(yùn)行效率,可以將某些變量保存在寄存器中,即用為提高程序運(yùn)行效率,可以將某些變量保存在寄存器中,即用register說明為寄存器變量,說明為寄存器變量,但不提倡使用但不提倡使用。C+中關(guān)于存儲(chǔ)類型的說明符(中關(guān)于存儲(chǔ)類型的說明符(storage class specifier)有四)有四個(gè):個(gè):auto、register、static和和extern。其中用
39、。其中用auto和和register修修飾的稱為自動(dòng)存儲(chǔ)類型,用飾的稱為自動(dòng)存儲(chǔ)類型,用static修飾的稱為靜態(tài)存儲(chǔ)類型,修飾的稱為靜態(tài)存儲(chǔ)類型,用用extern修飾的稱為外部存儲(chǔ)類型。修飾的稱為外部存儲(chǔ)類型。1 1 自動(dòng)存儲(chǔ)類型自動(dòng)存儲(chǔ)類型static說明的變量稱為靜態(tài)變量。根據(jù)定義的位置不同,還說明的變量稱為靜態(tài)變量。根據(jù)定義的位置不同,還分為局部靜態(tài)變量和全局靜態(tài)變量,也稱內(nèi)部靜態(tài)變量和外部分為局部靜態(tài)變量和全局靜態(tài)變量,也稱內(nèi)部靜態(tài)變量和外部靜態(tài)變量。靜態(tài)變量均存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),如果程序未顯式給靜態(tài)變量。靜態(tài)變量均存儲(chǔ)在全局?jǐn)?shù)據(jù)區(qū),如果程序未顯式給出初始化值,系統(tǒng)自動(dòng)初始化為全出初始
40、化值,系統(tǒng)自動(dòng)初始化為全0,且初始化只進(jìn)行一次;靜,且初始化只進(jìn)行一次;靜態(tài)變量占有的空間要到整個(gè)程序執(zhí)行結(jié)束才釋放,故靜態(tài)變量態(tài)變量占有的空間要到整個(gè)程序執(zhí)行結(jié)束才釋放,故靜態(tài)變量具有全局生命期。具有全局生命期。3.6.1 存儲(chǔ)類型存儲(chǔ)類型局部靜態(tài)變量是定義在塊中的靜態(tài)變量,當(dāng)塊第一次被執(zhí)行時(shí),局部靜態(tài)變量是定義在塊中的靜態(tài)變量,當(dāng)塊第一次被執(zhí)行時(shí),編譯系統(tǒng)在全局?jǐn)?shù)據(jù)區(qū)為其開辟空間并保存數(shù)據(jù),該空間一直編譯系統(tǒng)在全局?jǐn)?shù)據(jù)區(qū)為其開辟空間并保存數(shù)據(jù),該空間一直到整個(gè)程序結(jié)束才釋放。局部靜態(tài)變量具有局部作用域,但卻到整個(gè)程序結(jié)束才釋放。局部靜態(tài)變量具有局部作用域,但卻具有全局生命期。具有全局生命期
41、?!纠纠?.10】 自動(dòng)變量與局部靜態(tài)變量的區(qū)別自動(dòng)變量與局部靜態(tài)變量的區(qū)別 int f( int a) auto int b=0; static int c=3; b=b+1;c=c+1; return(a+b+c); int main() int a=2, i ; for(i=0; i 3; i +) cout f(a)endl; 0b3c1舉舉例例2a2a4701580691 fun(int a, int b) static int m, i=2; i+=m+1; m=i+a+b; return(m); int main() int k=4,m=1,p; p=fun(k,m); cou
42、tpendl; p=fun(k,m); coutpendl; 0m4k4a1m1b p2i388120178 17817int main() fun(); fun(); void fun() static int a3=0,1,2; int i ; for(i =0; i 3; i +) ai +=ai ; for(i =0; i 3; i +) coutai ; coutendl; return; 0 12 a0 a1 a20240483.6.1 存儲(chǔ)類型存儲(chǔ)類型一個(gè)一個(gè)C+程序可以由多個(gè)源程序文件組成。多文件程序系統(tǒng)可程序可以由多個(gè)源程序文件組成。多文件程序系統(tǒng)可以通過以通過外部存儲(chǔ)類型外
43、部存儲(chǔ)類型的變量和函數(shù)來的變量和函數(shù)來共享共享某些數(shù)據(jù)和操作。某些數(shù)據(jù)和操作。在一個(gè)程序文件中定義的全局變量和函數(shù)缺省為外部的,即其作在一個(gè)程序文件中定義的全局變量和函數(shù)缺省為外部的,即其作用域可以延伸到程序的其他文件中。其他文件如果要使用這個(gè)文用域可以延伸到程序的其他文件中。其他文件如果要使用這個(gè)文件中定義的全局變量和函數(shù),應(yīng)該在使用前用件中定義的全局變量和函數(shù),應(yīng)該在使用前用“extern”作外部聲作外部聲明。外部聲明通常放在文件的開頭(明。外部聲明通常放在文件的開頭(函數(shù)函數(shù)總是總是省略省略extern)。)。外部變量聲明不同于全局變量定義,變量定義時(shí)編譯器為其分外部變量聲明不同于全局變
44、量定義,變量定義時(shí)編譯器為其分配存儲(chǔ)空間,而變量聲明則表示該全局變量已在其他地方定義配存儲(chǔ)空間,而變量聲明則表示該全局變量已在其他地方定義過,編譯系統(tǒng)不再分配存儲(chǔ)空間。過,編譯系統(tǒng)不再分配存儲(chǔ)空間。外部的全局變量或函數(shù)加上外部的全局變量或函數(shù)加上static修飾,就成為靜態(tài)全局變量修飾,就成為靜態(tài)全局變量或靜態(tài)函數(shù)。靜態(tài)的全局變量和函數(shù)作用域限制在本文件,其或靜態(tài)函數(shù)。靜態(tài)的全局變量和函數(shù)作用域限制在本文件,其他文件即使使用外部聲明也無法使用該全局變量或函數(shù)。他文件即使使用外部聲明也無法使用該全局變量或函數(shù)。 【例【例3.11】外部存儲(chǔ)類型的例子外部存儲(chǔ)類型的例子全局變量的static:如果程
45、序是由多個(gè)源文件組成時(shí),此全局變量的作用域只限于本文件中。extern int x; int x;main() a1.cppstatic char cc; extern int x; a2.cpp extern char cc; a3.cpp3.6.2 生命期生命期1.1. 靜態(tài)生命期靜態(tài)生命期 靜態(tài)生命期靜態(tài)生命期(Static extent或或Static storage duration)指)指的是標(biāo)識(shí)符從程序開始運(yùn)行時(shí)就存在,具有存儲(chǔ)空間,到程的是標(biāo)識(shí)符從程序開始運(yùn)行時(shí)就存在,具有存儲(chǔ)空間,到程序運(yùn)行結(jié)束時(shí)消亡,釋放存儲(chǔ)空間。具有靜態(tài)生命期的標(biāo)識(shí)序運(yùn)行結(jié)束時(shí)消亡,釋放存儲(chǔ)空間。具有靜態(tài)
46、生命期的標(biāo)識(shí)符存放在全局?jǐn)?shù)據(jù)區(qū),如符存放在全局?jǐn)?shù)據(jù)區(qū),如全局變量、靜態(tài)全局變量、靜態(tài)局全局變量、靜態(tài)全局變量、靜態(tài)局部變量部變量。具有靜態(tài)生命期的標(biāo)識(shí)符在未被用戶初始化的情況。具有靜態(tài)生命期的標(biāo)識(shí)符在未被用戶初始化的情況下,系統(tǒng)會(huì)自動(dòng)將其初始化為下,系統(tǒng)會(huì)自動(dòng)將其初始化為0。 函數(shù)駐留在代碼區(qū),也具有靜態(tài)生命期。所有具有文件函數(shù)駐留在代碼區(qū),也具有靜態(tài)生命期。所有具有文件作用域的標(biāo)識(shí)符都具有靜態(tài)生命期。作用域的標(biāo)識(shí)符都具有靜態(tài)生命期。 3.6.2 生命期生命期2. 2. 局部生命期局部生命期 在函數(shù)內(nèi)部或塊中定義的標(biāo)識(shí)符具有在函數(shù)內(nèi)部或塊中定義的標(biāo)識(shí)符具有局部生命期局部生命期(Automati
47、c extent或或Automatic storage duration),),其生命期開始于執(zhí)行到該函數(shù)或塊的標(biāo)識(shí)符定義處,其生命期開始于執(zhí)行到該函數(shù)或塊的標(biāo)識(shí)符定義處,結(jié)束于該函數(shù)或塊的結(jié)束處。具有局部生命期的標(biāo)識(shí)結(jié)束于該函數(shù)或塊的結(jié)束處。具有局部生命期的標(biāo)識(shí)符存放在棧區(qū)。具有局部生命期的標(biāo)識(shí)符如果未被初符存放在棧區(qū)。具有局部生命期的標(biāo)識(shí)符如果未被初始化,其內(nèi)容是隨機(jī)的,不可引用。始化,其內(nèi)容是隨機(jī)的,不可引用。 具有局部生命期的標(biāo)識(shí)符必定具有局部作用域;具有局部生命期的標(biāo)識(shí)符必定具有局部作用域;但反之不然,但反之不然,靜態(tài)局部變量靜態(tài)局部變量具有局部作用域,但卻具具有局部作用域,但卻具有
48、靜態(tài)生命期。有靜態(tài)生命期。3.6.2 生命期生命期具有具有動(dòng)態(tài)生命期動(dòng)態(tài)生命期(dynamic extent或或dynamic storage duration)的標(biāo)識(shí)符存放在自由存儲(chǔ)區(qū),)的標(biāo)識(shí)符存放在自由存儲(chǔ)區(qū),由特定的函數(shù)調(diào)用或運(yùn)算來創(chuàng)建和釋放,如用由特定的函數(shù)調(diào)用或運(yùn)算來創(chuàng)建和釋放,如用new運(yùn)算符(或調(diào)用運(yùn)算符(或調(diào)用malloc()函數(shù))為變量分配函數(shù))為變量分配存儲(chǔ)空間時(shí),變量的生命期開始,而用存儲(chǔ)空間時(shí),變量的生命期開始,而用delete運(yùn)運(yùn)算符(或調(diào)用算符(或調(diào)用free()函數(shù))釋放空間或程序結(jié)束函數(shù))釋放空間或程序結(jié)束時(shí),變量生命期結(jié)束。關(guān)于時(shí),變量生命期結(jié)束。關(guān)于new
49、運(yùn)算符和運(yùn)算符和delete運(yùn)算符將在第七章中介紹。運(yùn)算符將在第七章中介紹。3. 3. 動(dòng)態(tài)生命期動(dòng)態(tài)生命期3.7 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用1n 1)!-(n*n1n 1 0n 1 n! 遞歸是一種描述問題的方法,或稱算法。遞歸的思想遞歸是一種描述問題的方法,或稱算法。遞歸的思想可以簡(jiǎn)單地描述為可以簡(jiǎn)單地描述為“自己調(diào)用自己自己調(diào)用自己”。例如用如下方法定。例如用如下方法定義階乘:義階乘:可以看出是用階乘定義階乘,這種自己定義可以看出是用階乘定義階乘,這種自己定義自己的方法稱為遞歸定義。自己的方法稱為遞歸定義。遞歸的引入:遞歸的引入:遞歸定義的階乘函數(shù):遞歸定義的階乘函數(shù):fac(int
50、n)if (n=0|n=1) return 1;else return n*fac(n-1);只要設(shè)計(jì)主函數(shù)調(diào)用階乘函數(shù),即可實(shí)現(xiàn)計(jì)算階乘。只要設(shè)計(jì)主函數(shù)調(diào)用階乘函數(shù),即可實(shí)現(xiàn)計(jì)算階乘。3.7 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用【例【例3.12】 求求4!運(yùn)行結(jié)果:運(yùn)行結(jié)果:4321126244!=24說明:說明:cout”n4!=”fac(4)endl;執(zhí)行時(shí)是先算函數(shù)值,然后再從左到右輸出各表達(dá)式的值。執(zhí)行時(shí)是先算函數(shù)值,然后再從左到右輸出各表達(dá)式的值。所以有兩行輸出,而不是第一行插在第二行賦值號(hào)與所以有兩行輸出,而不是第一行插在第二行賦值號(hào)與24之間。之間。3.7 函數(shù)的遞歸調(diào)用函數(shù)的遞歸調(diào)用
51、探討:探討:計(jì)算是先右后左。請(qǐng)看下一條輸出語句:計(jì)算是先右后左。請(qǐng)看下一條輸出語句:cout”n4!=”fac(4) ”n3!=”fac(3)=0&ch=9?1:0;int main() char ch; while(cin.get(ch), ch!= n) if (IsNumber(ch) cout是數(shù)字字符是數(shù)字字符 endl; else cout不是數(shù)字字符不是數(shù)字字符 endl; return 0;因使用頻度很高,說明為內(nèi)聯(lián)函數(shù)。因使用頻度很高,說明為內(nèi)聯(lián)函數(shù)。3.9 頭文件與多文件結(jié)構(gòu)頭文件與多文件結(jié)構(gòu) (選讀)(選讀)3.9.1 頭文件頭文件標(biāo)準(zhǔn)庫頭文件:標(biāo)準(zhǔn)庫頭文件:考慮標(biāo)識(shí)符在
52、其他文件中的可見性。使用頭文件是很有效的方考慮標(biāo)識(shí)符在其他文件中的可見性。使用頭文件是很有效的方法。如:法。如:#includeusing namespace std; 其中的其中的iostream是是在在標(biāo)準(zhǔn)名字空間域標(biāo)準(zhǔn)名字空間域std中定義的頭文件。對(duì)中定義的頭文件。對(duì)應(yīng)的傳統(tǒng)方式的文件名為應(yīng)的傳統(tǒng)方式的文件名為,頭文件以,頭文件以“.h”為后綴為后綴。 系統(tǒng)定義的頭文件系統(tǒng)定義的頭文件中定義了一些常用的公用標(biāo)識(shí)符和函數(shù)中定義了一些常用的公用標(biāo)識(shí)符和函數(shù),用戶只要將頭文件包含進(jìn)自己的文件,就可使頭文件中定義,用戶只要將頭文件包含進(jìn)自己的文件,就可使頭文件中定義的標(biāo)識(shí)符在用戶文件中變得可見
53、,也就可以直接使用頭文件中的標(biāo)識(shí)符在用戶文件中變得可見,也就可以直接使用頭文件中定義的標(biāo)識(shí)符和函數(shù)。定義的標(biāo)識(shí)符和函數(shù)。 3.9.1 頭文件頭文件自定義頭文件:自定義頭文件:除了系統(tǒng)定義的頭文件外,用戶還可以除了系統(tǒng)定義的頭文件外,用戶還可以自定義頭文件自定義頭文件。對(duì)于具有外部存儲(chǔ)類型的標(biāo)識(shí)符,可以在其他任何。對(duì)于具有外部存儲(chǔ)類型的標(biāo)識(shí)符,可以在其他任何一個(gè)源程序文件中經(jīng)聲明后引用,因此用戶完全可以一個(gè)源程序文件中經(jīng)聲明后引用,因此用戶完全可以將一些具有將一些具有外部存儲(chǔ)類型的標(biāo)識(shí)符的聲明外部存儲(chǔ)類型的標(biāo)識(shí)符的聲明放在一個(gè)頭放在一個(gè)頭文件中。具體地說,頭文件中可以包括:文件中。具體地說,頭文
54、件中可以包括:用戶構(gòu)造的用戶構(gòu)造的數(shù)據(jù)類型(如枚舉類型),外部變量,外部函數(shù)、常數(shù)據(jù)類型(如枚舉類型),外部變量,外部函數(shù)、常量和內(nèi)聯(lián)函數(shù)等具有一定通用性或常用的量,量和內(nèi)聯(lián)函數(shù)等具有一定通用性或常用的量,而一般而一般性的變量和函數(shù)定義不宜放在頭文件中。性的變量和函數(shù)定義不宜放在頭文件中。3.9.2 多文件結(jié)構(gòu)多文件結(jié)構(gòu) 在開發(fā)較大程序時(shí),通常將其分解為多個(gè)源程序文件在開發(fā)較大程序時(shí),通常將其分解為多個(gè)源程序文件,每個(gè)較小的程序用一個(gè)源程序文件建立。程序經(jīng)過建立,每個(gè)較小的程序用一個(gè)源程序文件建立。程序經(jīng)過建立、編譯、連接,成為一個(gè)完整的可執(zhí)行程序。、編譯、連接,成為一個(gè)完整的可執(zhí)行程序。多文
55、件結(jié)構(gòu)多文件結(jié)構(gòu)通過工程進(jìn)行管理,在工程中建立若干用戶定義的頭文件通過工程進(jìn)行管理,在工程中建立若干用戶定義的頭文件.h和源程序文件和源程序文件.cpp。頭文件中定義用戶自定義的數(shù)據(jù)類。頭文件中定義用戶自定義的數(shù)據(jù)類型,所有的程序?qū)崿F(xiàn)則放在不同的源程序文件中型,所有的程序?qū)崿F(xiàn)則放在不同的源程序文件中。編譯時(shí)。編譯時(shí)每個(gè)源程序文件單獨(dú)編譯,如果源程序文件中有編譯預(yù)處每個(gè)源程序文件單獨(dú)編譯,如果源程序文件中有編譯預(yù)處理指令,則首先經(jīng)過編譯預(yù)處理生成臨時(shí)文件存放在內(nèi)存理指令,則首先經(jīng)過編譯預(yù)處理生成臨時(shí)文件存放在內(nèi)存,之后對(duì)臨時(shí)文件進(jìn)行編譯生成目標(biāo)文件,之后對(duì)臨時(shí)文件進(jìn)行編譯生成目標(biāo)文件.obj,編
56、譯后臨,編譯后臨時(shí)文件撤銷。所有的目標(biāo)文件經(jīng)連接器連接最終生成一個(gè)時(shí)文件撤銷。所有的目標(biāo)文件經(jīng)連接器連接最終生成一個(gè)完整的可執(zhí)行文件完整的可執(zhí)行文件.exe。 圖圖3.11是一個(gè)多文件系統(tǒng)的開發(fā)過程。是一個(gè)多文件系統(tǒng)的開發(fā)過程。3.9.2 多文件結(jié)構(gòu)多文件結(jié)構(gòu) 編譯 預(yù)編譯編譯 預(yù)編譯 預(yù)編譯編譯圖圖3.11 C+程序開發(fā)過程程序開發(fā)過程file1.hfile1.cppfile2.hfile2.cppfilen.hfilen.cpp臨時(shí)文件臨時(shí)文件1臨時(shí)文件臨時(shí)文件2臨時(shí)文件臨時(shí)文件nfile1.objfile2.objfilen.objFilename.exe.libC+標(biāo)準(zhǔn)類庫標(biāo)準(zhǔn)類庫連接
57、連接運(yùn)行運(yùn)行3.10 編譯預(yù)處理編譯預(yù)處理(選讀選讀) 3.10.1 宏定義指令宏定義指令 3.10.2 文件包含指令文件包含指令 3.10.3 條件編譯指令條件編譯指令 3.10.1 宏定義指令宏定義指令1 1 不帶參宏定義不帶參宏定義用來產(chǎn)生與一個(gè)字符串對(duì)應(yīng)的常量字符串,格式為:用來產(chǎn)生與一個(gè)字符串對(duì)應(yīng)的常量字符串,格式為:#define #define 宏名宏名 常量串常量串 預(yù)處理后文件中凡出現(xiàn)該字符串處均用其對(duì)應(yīng)的常量預(yù)處理后文件中凡出現(xiàn)該字符串處均用其對(duì)應(yīng)的常量串代替。替換過程稱為宏替換或宏展開。例如,如果串代替。替換過程稱為宏替換或宏展開。例如,如果使用指令使用指令#define
58、 PI 3.1415926#define PI 3.1415926則程序中可以使用標(biāo)識(shí)符則程序中可以使用標(biāo)識(shí)符PIPI,編譯預(yù)處理后產(chǎn)生一個(gè),編譯預(yù)處理后產(chǎn)生一個(gè)中間文件,文件中所有中間文件,文件中所有PIPI被替換為被替換為3.14159263.1415926。宏替換只是字符串和標(biāo)識(shí)符之間的簡(jiǎn)單替換,預(yù)處理宏替換只是字符串和標(biāo)識(shí)符之間的簡(jiǎn)單替換,預(yù)處理本身不做任何數(shù)據(jù)類型和合法性檢查,也不分配內(nèi)存本身不做任何數(shù)據(jù)類型和合法性檢查,也不分配內(nèi)存單元單元。3.10.1 宏定義指令宏定義指令2 2 帶參數(shù)的宏定義帶參數(shù)的宏定義帶參宏定義的形式很象定義一個(gè)函數(shù),格式為:帶參宏定義的形式很象定義一個(gè)函
59、數(shù),格式為:#define 宏名宏名 ( 形參表形參表 ) 表達(dá)式串表達(dá)式串 例如作如下宏定義:例如作如下宏定義:#define S(a,b) (a)*(b)/2程序中可使用程序中可使用S(a,b),預(yù)處理后產(chǎn)生中間文件,其中,預(yù)處理后產(chǎn)生中間文件,其中S(a,b)被被替換成替換成(a)*(b)/2。注意,宏定義時(shí)形參通常要用括號(hào)括起來。注意,宏定義時(shí)形參通常要用括號(hào)括起來,否則容易導(dǎo)致邏輯錯(cuò)誤。例如,如果定義:,否則容易導(dǎo)致邏輯錯(cuò)誤。例如,如果定義:#define S(a,b) a*b/2那么程序中的那么程序中的S(3+5,4+2)就會(huì)被宏展開為就會(huì)被宏展開為3+5*4+2/2,不,不符合定
60、義的真正的意圖。符合定義的真正的意圖。帶參宏定義形式上象定義函數(shù),但它與函數(shù)的本質(zhì)不同,宏定帶參宏定義形式上象定義函數(shù),但它與函數(shù)的本質(zhì)不同,宏定義仍然只是產(chǎn)生字符串替代,不存在分配內(nèi)存和參數(shù)傳遞。義仍然只是產(chǎn)生字符串替代,不存在分配內(nèi)存和參數(shù)傳遞。 3.10.2 文件包含指令文件包含指令文件包含文件包含用用#include指令指令,預(yù)處理后將指令中指明的源程序,預(yù)處理后將指令中指明的源程序文件嵌入到當(dāng)前源程序文件的指令位置處。格式為:文件嵌入到當(dāng)前源程序文件的指令位置處。格式為:#include 或或#include 文件名文件名第一種第一種方式稱為方式稱為標(biāo)準(zhǔn)方式標(biāo)準(zhǔn)方式,預(yù)處理器將在,預(yù)
61、處理器將在include子目錄下子目錄下搜索由文件名所指明的文件。這種方式適用于嵌入搜索由文件名所指明的文件。這種方式適用于嵌入C+提供提供的頭文件,因?yàn)檫@些頭文件一般都存在的頭文件,因?yàn)檫@些頭文件一般都存在C+系統(tǒng)目錄的系統(tǒng)目錄的include子目錄下。而子目錄下。而第二種方式第二種方式編譯器將首先在當(dāng)前文件編譯器將首先在當(dāng)前文件所在目錄下搜索,如果找不到再按標(biāo)準(zhǔn)方式搜索。這種方式所在目錄下搜索,如果找不到再按標(biāo)準(zhǔn)方式搜索。這種方式適用于嵌入用戶自己建立的頭文件。適用于嵌入用戶自己建立的頭文件。一個(gè)被包含的頭文件中還可以有一個(gè)被包含的頭文件中還可以有#include指令,指令,即即inclu
62、de指令可以嵌套指令可以嵌套,但是,如果同一個(gè)頭文,但是,如果同一個(gè)頭文件在同一個(gè)源程序文件中被件在同一個(gè)源程序文件中被重復(fù)包含重復(fù)包含,就會(huì)出現(xiàn),就會(huì)出現(xiàn)標(biāo)標(biāo)識(shí)符重復(fù)定義的錯(cuò)誤識(shí)符重復(fù)定義的錯(cuò)誤。例如:頭文件。例如:頭文件f2.h中包含了中包含了f1.h,如果文件,如果文件f3.cpp中既包含中既包含f1.h,又包含,又包含f2.h,那么編譯將提示錯(cuò)誤,原因是那么編譯將提示錯(cuò)誤,原因是f1.h被包含了兩次,被包含了兩次,那么其中定義的標(biāo)識(shí)符在那么其中定義的標(biāo)識(shí)符在f3.cpp中就被重復(fù)定義。中就被重復(fù)定義。避免重復(fù)包含可以用避免重復(fù)包含可以用條件編譯指令條件編譯指令。3.10.2 文件包含指
63、令文件包含指令3.10.3 條件編譯指令條件編譯指令 1 用用宏名宏名作為編譯的條件作為編譯的條件格式為:格式為:#ifdef#else#endif2 表達(dá)式的值表達(dá)式的值作為編譯條件作為編譯條件格式為:格式為:#if #else#endif當(dāng)希望在不同條件下編譯程序的不同部分。這種情況就要使當(dāng)希望在不同條件下編譯程序的不同部分。這種情況就要使用條件編譯指令。用條件編譯指令。 其中程序段可以是程序也可以是編譯預(yù)處理指令??梢酝ㄟ^其中程序段可以是程序也可以是編譯預(yù)處理指令??梢酝ㄟ^在該指令前面安排宏定義來控制編譯不同的程序段。在該指令前面安排宏定義來控制編譯不同的程序段。例:在調(diào)試程序時(shí)常常要輸
64、出調(diào)試信息,而調(diào)試完后不需要例:在調(diào)試程序時(shí)常常要輸出調(diào)試信息,而調(diào)試完后不需要輸出這些信息,則可以把輸出調(diào)試信息的語句用條件編譯指輸出這些信息,則可以把輸出調(diào)試信息的語句用條件編譯指令括起來。形式如下:令括起來。形式如下:#ifdef DEBUGcouta=atx=xendl;#endif在程序調(diào)試期間,在該條件編譯指令前增加宏定義:在程序調(diào)試期間,在該條件編譯指令前增加宏定義:#define DEBUG調(diào)試好后,刪除調(diào)試好后,刪除DEBUG宏定義,將源程序重新編譯一次。宏定義,將源程序重新編譯一次。條件編譯指令包括:條件編譯指令包括:#if、#else、#ifdef、#ifndef、#en
65、dif、#undef等。等。#ifndef與與#ifdef作用一樣,只是選擇的條件相反。作用一樣,只是選擇的條件相反。#undef指令用來取消指令用來取消#define指令所定義的符號(hào),這樣指令所定義的符號(hào),這樣可以根據(jù)需要打開和關(guān)閉符號(hào)??梢愿鶕?jù)需要打開和關(guān)閉符號(hào)。第三章第三章 函數(shù)函數(shù)再見謝謝!謝謝!3.1.3 函數(shù)的調(diào)用函數(shù)的調(diào)用【例【例3.1】 main( )函數(shù)函數(shù)調(diào)用調(diào)用max(2.5,4.7 )函數(shù)函數(shù)max(2.5,4.7 )return 4.7 主程序后主程序后續(xù)語句續(xù)語句【例【例3.1】 輸入兩個(gè)實(shí)數(shù),輸出其中較大的數(shù)。其中輸入兩個(gè)實(shí)數(shù),輸出其中較大的數(shù)。其中求兩個(gè)實(shí)數(shù)中的
66、較大數(shù)用函數(shù)完成。求兩個(gè)實(shí)數(shù)中的較大數(shù)用函數(shù)完成。程序如下程序如下:#include using namespace std;float max(float a,float b)return(a=b?a:b);int main()float x,y;cout輸入兩個(gè)實(shí)數(shù):輸入兩個(gè)實(shí)數(shù):xy;coutx和和y中較大數(shù)為中較大數(shù)為max(x,y)endl;return 0;形式參數(shù)形式參數(shù)實(shí)際參數(shù)實(shí)際參數(shù) 3.2.1 函數(shù)的參數(shù)傳遞及傳值調(diào)用函數(shù)的參數(shù)傳遞及傳值調(diào)用【例【例3.2】 調(diào)用調(diào)用power(4.6,3 )函數(shù)函數(shù)power(4.6,3 )return 97.336 主程序后續(xù)語主程序后續(xù)語句句n= 3x= 4.6c= a【例【例3.2】 實(shí)參和形參對(duì)應(yīng)關(guān)系的示例。實(shí)參和形參對(duì)應(yīng)關(guān)系的示例。float power(float x,int n) /求求x x的的n n次冪次冪float p=1;while(n-) p*=x;return p; int main()int n=3;float x=4.6;char c=a;coutpower(x,n)=power(x,n)endl;c
- 溫馨提示:
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ì)自己和他人造成任何形式的傷害或損失。