面向?qū)ο笤O(shè)計與C++第3章-函數(shù)和編譯預(yù)處理_第1頁
面向?qū)ο笤O(shè)計與C++第3章-函數(shù)和編譯預(yù)處理_第2頁
面向?qū)ο笤O(shè)計與C++第3章-函數(shù)和編譯預(yù)處理_第3頁
面向?qū)ο笤O(shè)計與C++第3章-函數(shù)和編譯預(yù)處理_第4頁
面向?qū)ο笤O(shè)計與C++第3章-函數(shù)和編譯預(yù)處理_第5頁
已閱讀5頁,還剩106頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第3章函數(shù)和編譯預(yù)處理3.1函數(shù)概述

3.2函數(shù)的定義和調(diào)用

3.3函數(shù)的參數(shù)傳遞

3.4函數(shù)的嵌套調(diào)用和遞歸調(diào)用

3.5內(nèi)置函數(shù)

3.6變量和函數(shù)的屬性

3.7編譯預(yù)處理

整理ppt3.1概述一個較大的程序不可能完全由一個人從頭至尾地完成,更不可能把所有的內(nèi)容都放在一個主函數(shù)中。為了便于規(guī)劃、組織、編程和調(diào)試,一般的做法是把一個大的程序劃分為若干個程序模塊(即程序文件),每一個模塊實現(xiàn)一部分功能。不同的程序模塊可以由不同的人來完成。在程序進行編譯時,以程序模塊為編譯單位,即分別對每一個編譯單位進行編譯。如果發(fā)現(xiàn)錯誤,可以在本程序模塊范圍內(nèi)查錯并改正。在分別通過編譯后,才進行連接,把各模塊的目標(biāo)文件以及系統(tǒng)文件連接在一起形成可執(zhí)行文件。整理ppt在一個程序文件中可以包含若干個函數(shù)。無論把一個程序劃分為多少個程序模塊,只能有一個main函數(shù)。程序總是從main函數(shù)開始執(zhí)行的。在程序運行過程中,由主函數(shù)調(diào)用其他函數(shù),其他函數(shù)也可以互相調(diào)用。在C語言中沒有類和對象,在程序模塊中直接定義函數(shù)。可以認為,一個C程序是由若干個函數(shù)組成的,C語言被認為是面向函數(shù)的語言。C++面向過程的程序設(shè)計沿用了C語言使用函數(shù)的方法。在C++面向?qū)ο蟮某绦蛟O(shè)計中,主函數(shù)以外的函數(shù)大多是被封裝在類中的。主函數(shù)或其他函數(shù)可以通過類對象調(diào)用類中的函數(shù)。無論是C還是C++,程序中的各項操作基本上都是由函數(shù)來實現(xiàn)的,程序編寫者要根據(jù)需要編寫一個個函數(shù),每個函數(shù)用來實現(xiàn)某一功能。因此,讀者必須掌握函數(shù)的概念以及學(xué)會設(shè)計和使用函數(shù)。整理ppt“函數(shù)”這個名詞是從英文function翻譯過來的,其實function的原意是“功能”。顧名思義,一個函數(shù)就是一個功能。在實際應(yīng)用的程序中,主函數(shù)寫得很簡單,它的作用就是調(diào)用各個函數(shù),程序各部分的功能全部都是由各函數(shù)實現(xiàn)的。主函數(shù)相當(dāng)于總調(diào)度,調(diào)動各函數(shù)依次實現(xiàn)各項功能。開發(fā)商和軟件開發(fā)人員將一些常用的功能模塊編寫成函數(shù),放在函數(shù)庫中供公共選用。程序開發(fā)人員要善于利用庫函數(shù),以減少重復(fù)編寫程序段的工作量。整理ppt圖3.1是一個程序中函數(shù)調(diào)用的示意圖。圖3.1main()func1()func2()func3()func5()func4()整理ppt例3.1在主函數(shù)中調(diào)用其他函數(shù)。#include<iostream.h>//*****ex3_1.cpp*****intcalc_sum(intn)//定義calc_sum()函數(shù){intk,s;s=0;for(k=1;k<=n;k++)s=s+k;

returns;}voidprint_word(void)//定義print_word()函數(shù){cout<<"Hello,C++!"<<endl;//輸出一行文字}voidmain(void){intn;cin>>n;if(n>1)cout<<"thesumis:"<<calc_sum(n)<<endl;//調(diào)用calc_sum()函數(shù)

print_word();//調(diào)用rint_word()函數(shù)}整理ppt若用戶從鍵盤輸入的數(shù)是4,運行情況如下:thesumis:10Hello,C++!

從用戶使用的角度看,函數(shù)有兩種:(1)系統(tǒng)函數(shù),即庫函數(shù)。這是由編譯系統(tǒng)提供的,用戶不必自己定義這些函數(shù),可以直接使用它們。(2)用戶自己定義的函數(shù)。用以解決用戶的專門需要。從函數(shù)的形式看,函數(shù)分兩類:(1)無參函數(shù)。調(diào)用函數(shù)時不必給出參數(shù)。(2)有參函數(shù)。在調(diào)用函數(shù)時,要給出參數(shù)。在主調(diào)函數(shù)和被調(diào)用函數(shù)之間有數(shù)據(jù)傳遞。整理ppt3.2函數(shù)的定義和調(diào)用3.2.1定義無參函數(shù)的一般形式定義函數(shù)的一般形式如下:類型標(biāo)識符函數(shù)名([形式參數(shù)列表]){聲明語句執(zhí)行語句}整理ppt【例3.1】的print_word函數(shù)是無參函數(shù),它的定義中首句也可以寫成:voidprint_word()//定義print_word()函數(shù)的首部;或:voidprint_word(void)//定義print_word()函數(shù)的首部【例3.1】的calc_sum函數(shù)是有參函數(shù),不過它只有一個參數(shù),參數(shù)的類型是整數(shù)類型。intcalc_sum(intn)//定義calc_sum()函數(shù)

C++要求在定義函數(shù)時必須指定函數(shù)的類型。下面的函數(shù)f則有兩個參數(shù),第一個是整數(shù)類型,第二個是單精度實數(shù)類型,而函數(shù)的返回值是雙精度實數(shù)類型:doublef(intx,floaty)//定義f()函數(shù)的首部整理ppt(1)對庫函數(shù)的聲明其實,對庫函數(shù)的聲明語句已經(jīng)寫在有關(guān)包含文件中了,因此只要在程序文件頭用include語句將這些包含文件包含到本程序中來,就完成了對庫函數(shù)的聲明。(2)對自定義函數(shù)的聲明必須在調(diào)用某自定義函數(shù)的語句之前寫上如下聲明語句:函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型,參數(shù)1名稱][,參數(shù)2類型,參數(shù)2名稱][…]);

3.2.2函數(shù)的聲明整理ppt(2)對自定義函數(shù)的聲明(續(xù))也可以在聲明語句中略去參數(shù)的名稱,或?qū)懸粋€任意名稱,這叫做函數(shù)原型(functionprototype),即聲明函數(shù)原型。函數(shù)原型有下列兩種表示形式:函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型][,參數(shù)2類型][…]);函數(shù)類型關(guān)鍵字函數(shù)名([參數(shù)1類型,標(biāo)識符1][,參數(shù)2類型,標(biāo)識符2][…]);C++中的函數(shù)原型說明了函數(shù)的類型、函數(shù)名、函數(shù)各形式參數(shù)類型。使用函數(shù)原型是C和C++的一個重要特點。3.2.2函數(shù)的聲明整理ppt【例3.2】對被調(diào)函數(shù)做聲明的示例。#include<iostream.h>//*****ex3_2.cpp*****voidmain(){floatadd(floatx,floaty);//對add函數(shù)作聲明

floatsubtract(float,float);//對subtract函數(shù)作聲明,用函數(shù)原型

doublemultiply(floatp,floatq);//對multiply函數(shù)作聲明,參數(shù)名任意

floata,b,c1,c2;doublec3;cout<<"pleaseinputa,b:";cin>>a>>b;c1=add(a,b);c2=subtract(a,b);c3=multiply(a,b);cout<<c1<<","<<c2<<","<<c3<<endl;}}整理pptfloatadd(floatx,floaty)//定義add函數(shù){floatz;z=x+y;return(z);}floatsubtract(floatx,floaty)//定義subtract函數(shù){floatz;z=x-y;return(z);}doublemultiply(floatx,floaty)//定義multiply函數(shù){doublez;z=x*y;return(z);}運行情況如下:pleaseinputa,b:4.252.00↙6.25,2.25,8.5

整理ppt說明:(1)對函數(shù)的定義和函數(shù)聲明是兩回事,不要混淆。(2)之所以函數(shù)原型中可以省略形式參數(shù)的名稱,是因為形式參數(shù)的名稱是無關(guān)緊要的,且在調(diào)用前形參并不存在。(3)函數(shù)聲明語句的位置。函數(shù)聲明語句可以放在主調(diào)函數(shù)中,也可放在函數(shù)外面,只要出現(xiàn)在調(diào)用語句之前即聲明有效。整理ppt3.2.3函數(shù)的返回值(1)函數(shù)的返回值是通過函數(shù)中的return語句獲得的。return語句將被調(diào)用函數(shù)中的一個確定值帶回主調(diào)函數(shù)中去。return語句后面的括號可以要,也可以不要。return后面的值可以是一個表達式。(2)函數(shù)值的類型。既然函數(shù)有返回值,這個值當(dāng)然應(yīng)屬于某一個確定的類型,應(yīng)當(dāng)在定義函數(shù)時指定函數(shù)值的類型。(3)如果函數(shù)值的類型和return語句中表達式的值不一致,則以函數(shù)類型為準(zhǔn),即函數(shù)類型決定返回值的類型。對數(shù)值型數(shù)據(jù),可以自動進行類型轉(zhuǎn)換。整理ppt第(1)種形式是基本的形式。為了便于閱讀程序,也允許在函數(shù)原型中加上參數(shù)名,就成了第(2)種形式。但編譯系統(tǒng)并不檢查參數(shù)名。因此參數(shù)名是什么都無所謂。上面程序中的聲明也可以寫成floatadd(floata,floatb);//參數(shù)名不用x、y,而用a、b效果完全相同。應(yīng)當(dāng)保證函數(shù)原型與函數(shù)首部寫法上的一致,即函數(shù)類型、函數(shù)名、參數(shù)個數(shù)、參數(shù)類型和參數(shù)順序必須相同。在函數(shù)調(diào)用時函數(shù)名、實參類型和實參個數(shù)應(yīng)與函數(shù)原型一致。整理ppt說明:(1)前面已說明,如果被調(diào)用函數(shù)的定義出現(xiàn)在主調(diào)函數(shù)之前,可以不必加以聲明。因為編譯系統(tǒng)已經(jīng)事先知道了已定義的函數(shù)類型,會根據(jù)函數(shù)首部提供的信息對函數(shù)的調(diào)用作正確性檢查。有經(jīng)驗的程序編制人員一般都把main函數(shù)寫在最前面,這樣對整個程序的結(jié)構(gòu)和作用一目了然,統(tǒng)覽全局,然后再具體了解各函數(shù)的細節(jié)。此外,用函數(shù)原型來聲明函數(shù),還能減少編寫程序時可能出現(xiàn)的錯誤。由于函數(shù)聲明的位置與函數(shù)調(diào)用語句的位置比較近,因此在寫程序時便于就近參照函數(shù)原型來書寫函數(shù)調(diào)用,不易出錯。所以應(yīng)養(yǎng)成對所有用到的函數(shù)作聲明的習(xí)慣。這是保證程序正確性和可讀性的重要環(huán)節(jié)。整理ppt(2)函數(shù)聲明的位置可以在調(diào)用函數(shù)所在的函數(shù)中,也可以在函數(shù)之外。如果函數(shù)聲明放在函數(shù)的外部,在所有函數(shù)定義之前,則在各個主調(diào)函數(shù)中不必對所調(diào)用的函數(shù)再作聲明。例如:charletter(char,char);//本行和以下兩行函數(shù)聲明在所有函數(shù)之前且在函數(shù)外部floatf(float,float);//因而作用域是整個文件inti(float,float);intmain(){…}//在main函數(shù)中不必對它所調(diào)用的函數(shù)作聲明charletter(charc1,charc2)//定義letter函數(shù){…}floatf(floatx,floaty)//定義f函數(shù){…}inti(floatj,floatk)//定義i函數(shù){…}如果一個函數(shù)被多個函數(shù)所調(diào)用,用這種方法比較好,不必在每個主調(diào)函數(shù)中重復(fù)聲明。整理ppt函數(shù)調(diào)用的一般形式:函數(shù)名([實際參數(shù)列表])如果是調(diào)用無參函數(shù),則“實參表列”可以沒有,但括號不能省略。如果實參表列包含多個實參,則各參數(shù)間用逗號隔開。實參與形參的個數(shù)應(yīng)相等,類型應(yīng)匹配(相同或賦值兼容)。實參與形參按順序?qū)?yīng),一對一地傳遞數(shù)據(jù)。但應(yīng)說明,如果實參表列包括多個實參,對實參求值的順序并不是確定的。3.2.4函數(shù)的調(diào)用

整理ppt按函數(shù)在語句中的作用來分,可以有以下3種函數(shù)調(diào)用方式:1.函數(shù)語句把函數(shù)調(diào)用單獨作為一個語句,并不要求函數(shù)帶回一個值,只是要求函數(shù)完成一定的操作。如【例3.1】中的print_word()函數(shù)調(diào)用語句。2.函數(shù)表達式函數(shù)出現(xiàn)在一個表達式中,這時要求函數(shù)帶回一個確定的值以參加表達式的運算。如c=2*max(a,b);3.函數(shù)參數(shù)函數(shù)調(diào)用作為一個函數(shù)的實參。如m=max(a,max(b,c));//max(b,c)是函數(shù)調(diào)用,其值作為外層max函數(shù)調(diào)用的一個實參函數(shù)調(diào)用的方式整理ppt3.3函數(shù)的參數(shù)傳遞

形參:在定義函數(shù)時函數(shù)名后面括號中的變量名稱為形式參數(shù)(formalparameter),簡稱形參。形參是無內(nèi)存單元(因而不存在)的任何合法標(biāo)識符。實參:在調(diào)用一個函數(shù)時,調(diào)用語句的函數(shù)名后面括號中的參數(shù)稱為實際參數(shù)(actualparameter),簡稱實參。實參是實際存在(因而有特定值)的常量、變量或表達式。整理ppt【例3.3】形參和實參及其數(shù)據(jù)傳遞。#include<iostream>//*****ex3_3.cpp*****usingnamespacestd;floatvolume(floatr,floath)//定義有參函數(shù)volume求圓柱體體積,r和h是形參{floatv;v=3.14*r*r*h;return(v);}voidmain(){floata,b,c;cout<<"pleaseinputtwofloatnumbers:";cin>>a>>b;c=volume(a,b);//調(diào)用函數(shù)volume,a和b是實參。函數(shù)值賦給變量ccout<<"Thevolumeis"<<c<<endl;}整理ppt運行情況如下:pleaseinputtwofloatnukbers:2.05.0↙Thevolumeis62.8整理ppt有關(guān)形參與實參的說明:(1)在定義函數(shù)時指定的形參,在未出現(xiàn)函數(shù)調(diào)用時,它們并不占內(nèi)存中的存儲單元,因此稱它們是形式參數(shù)或虛擬參數(shù),表示它們并不是實際存在的數(shù)據(jù),只有在發(fā)生函數(shù)調(diào)用時,函數(shù)max中的形參才被分配內(nèi)存單元,以便接收從實參傳來的數(shù)據(jù)。在調(diào)用結(jié)束后,形參所占的內(nèi)存單元也被釋放。(2)實參可以是常量、變量或表達式,如max(3,a+b);但要求a和b有確定的值。以便在調(diào)用函數(shù)時將實參的值賦給形參。(3)在定義函數(shù)時,必須在函數(shù)首部指定形參的類型,至于形參使用何名字可隨意。整理ppt(4)實參與形參的類型應(yīng)相同或賦值兼容。兩種參數(shù)類型完全一致無疑是完全合法、正確的。如果實參為整型而形參為實型,或者相反,則按不同類型數(shù)值的賦值規(guī)則進行轉(zhuǎn)換,原則上不出現(xiàn)語法錯誤,但結(jié)果可能帶來某些非期望的誤差。例如實參a的值是3.5,而被調(diào)函數(shù)的形參x為整型,則調(diào)用該函數(shù)時會將3.5轉(zhuǎn)化為整數(shù)3,然后送到形參x,故x得到的是3,由3計算出的函數(shù)值與人們期望由3.5計算出的函數(shù)值一般是有差別的。但字符型與整型可以互相通用。整理ppt3.3.2參數(shù)的值傳遞值傳遞參數(shù)的實現(xiàn)是系統(tǒng)將實參拷貝一個副本給形參,拷貝后兩者就斷開關(guān)系。在被調(diào)函數(shù)中,形參可以被改變,但這只影響副本中的形參值,而不影響調(diào)用函數(shù)的實參值。所以這類函數(shù)有對原始數(shù)據(jù)保護的作用。換一句話說,這種參數(shù)傳遞機制是單向影響,即只能由實參將值傳給形參(實參影響形參);而形參在函數(shù)中的值如果發(fā)生修改,不會反過來影響與之對應(yīng)的實參。整理ppt【例3.4】參數(shù)值傳遞的演示。#include<iostream>//*****ex3_4.cpp*****usingnamespacestd;intmax(intx,inty)//定義有參函數(shù)max求兩數(shù)最大值,x和y是形參{floatm;cout<<"Theinitialx,y:"<<x<<","<<y<<endl;m=x>y?x:y;x=2*x;y=y+1;cout<<"Thenewx,y:"<<x<<","<<y<<endl;return(m);}整理pptvoidmain(){floata,b,c;cout<<"pleaseinputtwointegernumbers:";cin>>a>>b;c=max(a,b);//調(diào)用函數(shù)max,a和b是實參,函數(shù)值賦給變量c。cout<<"Themaxinumis:"<<c<<endl;cout<<"Aftercallingfuction,a,b:"<<a<<","<<b<<endl;}運行情況如下:pleaseinputtwointegernumbers:38↙Theinitialx,y:3,8Thenewx,y:69Themaxinumis:8Aftercallingfuction,a,b:3,8}整理ppt3.3.3參數(shù)的地址傳遞除了3.3.2小節(jié)介紹的值傳遞參數(shù)方式外,函數(shù)調(diào)用還有一種特殊的值傳遞形式,即傳遞的值不是一般的數(shù)值,而是一些內(nèi)存單元地址編號(即地址),這時,一般稱之為參數(shù)的地址傳遞。在這種參數(shù)傳遞形式中,無論在函數(shù)的定義中出現(xiàn)的形參還是在調(diào)用語句中出現(xiàn)的實參,都是代表一些內(nèi)存單元地址編號(即地址數(shù)值),而不是一般的數(shù)值。C++中的參數(shù)地址傳遞情況一般有如下幾種:實參可以是一個有確定值的普通變量的地址,或者是一個已經(jīng)初始化的指針變量;或者是一個初始化的數(shù)組名;或者是一個具體的函數(shù)名。而形參可以是一個任意普通變量的地址,或是一個任意指針變量,或是一個任意的數(shù)組名,或是一個指向函數(shù)的指針變量(對應(yīng)于實參是具體函數(shù)名)。整理ppt實際上,這種參數(shù)傳遞機制就是在函數(shù)調(diào)用時把一個內(nèi)存單元地址傳遞給形參,使形參也具有實參的內(nèi)存單元地址(即兩者對應(yīng)同一個內(nèi)存單元),稱作形參和實參地址結(jié)合,兩者合二為一。這樣一來,任何時候形參的值等于實參的值;而實參的值也等于形參的值。因此,形參在函數(shù)中發(fā)生變化后,也會引起實參跟著變化(因為它們是捆綁在一起的,一體化的)。這就意味著按地址傳遞的方式,在調(diào)用剛開始時實參的值影響了形參;而在被調(diào)函數(shù)執(zhí)行過程中形參值若發(fā)生了變化,它也會影響實參的值變化。即機制是雙向影響,這與普通值傳遞方式的單向影響機制形成對比。整理ppt3.3.4帶默認值的參數(shù)C++語言中,允許在函數(shù)聲明或定義時給一個或多個參數(shù)指定默認值。通常調(diào)用函數(shù)時,要為函數(shù)的每個形式參數(shù)給定相應(yīng)的值。例如下面的delay()函數(shù)作用是作時間延遲,在沒有使用默認值參數(shù)的情況下,是按如下普通方式聲明和定義的:【例3.5】延遲函數(shù)的使用。#include<iostream.h>//*****ex3_5.cpp*****voiddelay(intloop);//函數(shù)聲明voidmain(){cout<<"begin"<<endl;delay(1000);//函數(shù)調(diào)用cout<<"end"<<endl;}voiddelay(intloop)//函數(shù)定義{if(loop==0)return;for(inti=0;i<loop;i++)cout<<i<<endl;//輸出i的值為了清楚看到程序執(zhí)行的情況}整理ppt如果每次調(diào)用延遲時間基本一樣,可以使用C++中默認值參數(shù)函數(shù)形式來解決問題。解決的方法就是在函數(shù)的聲明(或定義)時給定默認值即可。具體做法只要把delay()函數(shù)的聲明改為下列形式:voiddelay(intloop=1000);//指定參數(shù)默認值為1000以后如果需要延遲相同時間1000,都可以不必指定實參的值而直接調(diào)用函數(shù):delay();//不給定實參,形參將得到默認值1000delay(500);//給定實參,形參將得到所給的值500整理ppt如果有多個形參,可以使每個形參有一個默認值;也可以只對一部分形參指定默認值。如前面的求圓柱體體積的函數(shù)volume,可以這樣聲明:floatvolume(floatr,floath=8.5);//只對形參h指定默認值8.5這時函數(shù)調(diào)用可采用以下形式:volume(6.0);//相當(dāng)于volume(6.0,8.5)volume(6.0,7.2);//r的值為6.0,h的值為7.2C++中實參和形參的結(jié)合是從左至右進行的,第1個實參必然與第1個形參結(jié)合,第2個實參必然與第2個形參結(jié)合,……。因此,指定默認值的參數(shù)必須放在參數(shù)列表中的最右邊。整理ppt3.4函數(shù)的嵌套調(diào)用和遞歸調(diào)用

C++不允許對函數(shù)作嵌套定義,也就是說在一個函數(shù)中不能完整地包含另一個函數(shù)。在一個程序中每一個函數(shù)的定義都是互相平行和獨立的。雖然C++不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),也就是說,在調(diào)用一個函數(shù)的過程中,又調(diào)用另一個函數(shù)。見圖3.2示意。

圖3.2整理ppt在程序中實現(xiàn)函數(shù)嵌套調(diào)用時,需要注意的是:在調(diào)用函數(shù)之前,需要對每一個被調(diào)用的函數(shù)作聲明(除非定義在前,調(diào)用在后)?!纠?.6】編程求組合,其中求組合的功能要求用函數(shù)完成。分析:根據(jù)組合的計算公式,知組合函數(shù)有兩個形參:m和n,可以用自定義函數(shù)comb(intn,intm)表示求組合。而在comb函數(shù)中需要3次計算階乘,如果定義函數(shù)fac(k)求k的階乘,然后在comb函數(shù)中調(diào)用fac函數(shù),可以使程序代碼簡單,只要在comb函數(shù)中寫一個語句“c=fac(m)/(fac(n)*fac(m-n));”即可求出組合值。整理ppt【例3.6】程序代碼如下:#include<iostream>//*****ex3_6.cpp*****usingnamespacestd;longfac(intk)//定義求階乘的函數(shù){longf=1;inti;for(i=1;i<=k;i++)f=f*i;returnf;}longcomb(intn,intm)//定義組合函數(shù){longc;c=fac(m)/(fac(n)*fac(m-n));//嵌套調(diào)用階乘函數(shù)

returnc;}整理pptvoidmain(){intn,m;longc;cout<<"pleaseinputtwointegernumbers:m,n"<<endl;cin>>m>>n;c=comb(n,m);//調(diào)用組合函數(shù)combcout<<"c="<<c<<endl;}主函數(shù)調(diào)用函數(shù)comb();comb()在執(zhí)行過程中又調(diào)用了函數(shù)fac()。fac()的調(diào)用被嵌套在函數(shù)comb()的調(diào)用中。整理ppt在調(diào)用一個函數(shù)的過程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸(recursive)調(diào)用。C++允許函數(shù)的遞歸調(diào)用。例如:直接遞歸調(diào)用的代碼形式如下:intf1()//函數(shù)f1的定義{……//函數(shù)其他部分

z=f1();//直接調(diào)用自身

……//函數(shù)其他部分}以上是在函數(shù)f1()中,又直接調(diào)用了f1()函數(shù),直接遞歸調(diào)用過程如圖3.3所示。3.4.2函數(shù)的遞歸調(diào)用整理ppt間接遞歸調(diào)用可以表現(xiàn)為如下形式:intf2()//函數(shù)f2的定義{……//f2的其他部分x=f3();//調(diào)用f3()……//f2的其他部分}intf3()//函數(shù)f3的定義{……//f3的其他部分y=f2();//調(diào)用f2()……//f3的其他部分}函數(shù)f2()中調(diào)用了f3(),而f3()中又調(diào)用了f2(),相當(dāng)于f2()間接地調(diào)用了f2()。這種調(diào)用稱為間接遞歸調(diào)用,調(diào)用過程如圖3.4所示。整理ppt

圖3.3函數(shù)的直接遞歸調(diào)用圖3.4函數(shù)的間接遞歸調(diào)用從圖上可以看到,這兩種遞歸調(diào)用都是無終止的自身調(diào)用。顯然,程序中不應(yīng)出現(xiàn)這種無終止的遞歸調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的、有終止的遞歸調(diào)用,這可以用if語句來控制,只有在某一條件成立時才繼續(xù)執(zhí)行遞歸調(diào)用,否則就不再繼續(xù)。包含遞歸調(diào)用的函數(shù)稱為遞歸函數(shù)。整理ppt【例3.7】用遞歸計算n!。分析:n!本身就是以遞歸的形式定義的:求n!,應(yīng)先求(n-1)??;而求(n-1)!,又需要先求(n-2)!,而求(n–2)??;又可以變成求(n-3)!,如此繼續(xù),直到最后變成求0!的問題,而根據(jù)公式有0!=1(這就是本問題的遞歸終止條件)。由終止條件得到0!結(jié)果后,再反過來依次求出1!,2!……直到最后求出n!。設(shè)求n!的函數(shù)為fac(n),函數(shù)體內(nèi)求n!,只要n>0,可用n*fac(n-1)表示,即fac(n)的函數(shù)體內(nèi)將遞歸調(diào)用fac()本身;但一旦參數(shù)n為0時,則終止調(diào)用函數(shù)自身并給出函數(shù)值1。程序如下:整理pptusingnamespacestd;#include<iostream>//*****ex3_7.cpp*****longfac(intn){longf;if(n==0)f=1;elsef=n*fac(n-1);//遞歸調(diào)用,求(n-1)!returnf;}整理pptvoidmain(){longy;intn;cout<<"pleaseinputaintegern"<<endl;cin>>n;y=fac(n);//調(diào)用fac(n)求n!cout<<"n="<<n<<","<<"y="<<y<<endl;}運行時,如果輸入:3,運行結(jié)果如下:n=3,y=6遞歸調(diào)用及返回過程如圖3.5所示,圖中的數(shù)字序號表示遞歸調(diào)用和返回的先后順序。整理ppt圖3.5求3!的遞歸過程fac(3)fac()n=33*fac(2)return6main()fac()n=22*fac(1)return2n=0fac(0)=1return1n1*fac(0)return1fac()fac()⑦②①③④⑧⑥⑤整理ppt從求n!的遞歸程序中可以看出,遞歸定義有兩個要素:(1)遞歸終止條件。也就是所描述問題的最簡單情況,它本身不再使用遞歸的定義,即程序必須終止。如上例,當(dāng)n=0時,fac(n)=1,不再使用f(n-1)來定義。(2)遞歸定義使問題向終止條件轉(zhuǎn)化的規(guī)則。遞歸定義必須能使問題越來越簡單,即參數(shù)越來越接近終止條件的參數(shù);達到終止條件參數(shù)時函數(shù)有確定的值。如上例,f(n)由f(n-1)定義,越來越靠近f(0),即參數(shù)越來越接近終止條件參數(shù)0;達到終止條件參數(shù)時函數(shù)有確定的值是f(0)=1。整理ppt【例3.8】漢諾塔問題漢諾塔(TowerofHanoi)問題據(jù)說來源于布拉瑪神廟。該問題的裝置如圖3.6所示(圖上僅畫三個金片以簡化問題的原理,原問題有64個金片),底座上有三根金鋼石的針,第一根針a上放著從大到小64個金片。解決該問題就是要想法把所有金片從第一根針a上移到第三根針c上,第二根針b作為中間過渡。要求是每次只能移動一個金片,并且任何時候不允許大的金片壓在小的金片上面。圖3.6三個金片的漢諾塔問題裝置abc整理ppt1.本問題的遞歸終止條件。如果只有1個盤,顯然問題的解就很明顯是:直接把金片從a移到c。因此終止條件是n=1;終止條件對應(yīng)的操作是直接把金片從a移到c,示意ac。2.本問題的遞歸分析:移動n個金片從a到c,必須先將n-1個金片從a借助c移動到b,移動n-1個金片與原問題相同,但規(guī)模變小,即向終止條件接近,因此,此問題可以用遞歸過程完成。遞歸過程可以用如下步驟表示:(1)將n-1個金片從a經(jīng)過c移動到b。(2)將第n個金片從a直接移動到c。(3)再將n-1個金片從b經(jīng)過a移動到c。

整理ppt一般地,設(shè)將n個金片從x針借助y針移動到z針的函數(shù)原形為:voidhanoi(intn,charx,chary,charz)根據(jù)解題步驟,可以寫出求解n個金片的漢諾塔函數(shù)如下:#include<iostream>//*****ex3_8.cpp*****usingnamespacestd;voidhanoi(intn,charx,chary,charz){if(n==1)//n=1時,直接將金片從x移動到zcout<<x<<"->"<<z<<endl;else//n>1時{hanoi(n-1,x,z,y);//先將n-1個金片從借助z移動到y(tǒng)cout<<x<<"->"<<z<<endl;//然后將第n個金片從x移到zhanoi(n-1,y,x,z);//再將n-1個金片從y借助x移動到z}}整理ppt當(dāng)n>1時,就遞歸調(diào)用hanoi(),每次n減1。最后當(dāng)n=1時,直接移動該金片就可以了。主函數(shù)如下:

voidmain(){intn;cout<<"inputn:"<<endl;cin>>n;hanoi(n,'a','b','c');//n個金片從a針借助b針移動到c針}雖然遞歸調(diào)用在寫程序時很簡單,但執(zhí)行起來卻很復(fù)雜(時間、存儲空間都開銷大)。對于漢諾塔問題程序的執(zhí)行過程分析比較復(fù)雜,有興趣的讀者可參閱教材對3個盤情景的分析(圖3.7及其相應(yīng)文字敘述)。整理ppt調(diào)用函數(shù)時需要一定的時間和空間的開銷。下圖表示的是一般函數(shù)調(diào)用的過程。一般函數(shù)調(diào)用過程3.5內(nèi)置函數(shù)整理ppt3.5.1內(nèi)置函數(shù)的作用內(nèi)置函數(shù)也稱內(nèi)聯(lián)函數(shù)、內(nèi)嵌函數(shù)。引入內(nèi)置函數(shù)的目的是為了提高程序中函數(shù)調(diào)用的效率。C++提供一種提高效率的方法,即在編譯時將所調(diào)用函數(shù)的代碼直接嵌入到主調(diào)函數(shù)中,而不是將流程轉(zhuǎn)出去。這種嵌入到主調(diào)函數(shù)中的函數(shù)稱為內(nèi)置函數(shù)(inlinefunction),又稱內(nèi)嵌函數(shù)。在有些書中把它譯成內(nèi)聯(lián)函數(shù)。指定內(nèi)置函數(shù)的方法很簡單,只需在函數(shù)首行的左端加一個關(guān)鍵字inline即可。整理ppt【例3.9】判斷用戶從鍵盤輸入的系列字符是數(shù)字字符還是其它字符的函數(shù)is_number()。#include<iostream.h>//*****ex3_9a.cpp*****intis_number(char);//函數(shù)聲明voidmain(){charc;while((c=cin.get())!='\n'){if(is_number(c))//調(diào)用一個小函數(shù)cout<<"youenteradigit\n";elsecout<<"youenteranon-digit\n";}}整理pptintis_number(charch)//函數(shù)定義{return(ch>='0'&&ch<='9')?1:0;}程序中不斷到設(shè)備中讀取數(shù)據(jù),頻繁調(diào)用is_number()函數(shù)。為了避免頻繁調(diào)用函數(shù),提高執(zhí)行效率,可以將【例3.9】程序改為:#include<iostream.h>//*****ex3_9b.cpp*****voidmain(){charc;while((c=cin.get())!='\n'){if((c>='0'&&c<='9')?1:0)//修改處:直接計算表達式

cout<<"youenteradigit\n";elsecout<<"youenteranon-digit\n";}}整理ppt修改后的程序在if語句中用表達式替換了函數(shù)調(diào)用。在程序運行上,提高了一些執(zhí)行效率,因為免去了大量的函數(shù)調(diào)用開銷。但是,由于is_number函數(shù)比相應(yīng)的表達式可讀性好,所以修改后的代碼可讀性降低,尤其若程序中多處出現(xiàn)is_number的替換時,會大大降低可讀性。我們希望既要用函數(shù)調(diào)用來體現(xiàn)其結(jié)構(gòu)化和可讀性,又要使效率盡可能地高。為了盡量做到兩全其美,C++中引入內(nèi)置函數(shù)這個方法。整理ppt3.5.2定義和使用內(nèi)置函數(shù)內(nèi)置函數(shù)的定義格式如下:inline函數(shù)名(形參列表){……//函數(shù)體}內(nèi)置函數(shù)的聲明格式如下:inline函數(shù)名(形參類型表);其實,內(nèi)置函數(shù)只要在開頭一次性聲明為inline即可,而后面的函數(shù)定義仍可寫成一般函數(shù)定義的形式,編譯器也會將函數(shù)視為內(nèi)置函數(shù)。整理ppt對【例3.9】使用內(nèi)置函數(shù)來解決,代碼可以寫成下列形式:#include<iostream.h>//*****ex3_9c.cpp*****inlineintis_number(char);//inline函數(shù)聲明voidmain(){charc;while((c=cin.get())!='\n'){if(is_number(c))//調(diào)用一個小函數(shù)cout<<"youenteradigit\n";elsecout<<"youenteranon-digit\n";}}intis_number(charch)//此處無inline,卻被本程序視為inline{return(ch>='0'&&ch<='9')?1:0;}整理ppt關(guān)于內(nèi)置函數(shù)的說明:(1)內(nèi)置函數(shù)與一般函數(shù)的區(qū)別在于函數(shù)調(diào)用的處理。一般函數(shù)進行調(diào)用時,要將程序執(zhí)行到被調(diào)用函數(shù)中,然后返回到主調(diào)函數(shù)中;而內(nèi)置函數(shù)在調(diào)用時,是將調(diào)用部分用內(nèi)置函數(shù)體來替換。(2)內(nèi)置函數(shù)必須先聲明后調(diào)用。因為程序編譯時要對內(nèi)置函數(shù)替換,所以在內(nèi)置函數(shù)調(diào)用之前必須聲明是內(nèi)置的(inline),否則將會像一般函數(shù)那樣產(chǎn)生調(diào)用而不是進行替換操作。(3)在內(nèi)置函數(shù)中,不能含有復(fù)雜的結(jié)構(gòu)控制語句,如switch、for和while。如果內(nèi)置函數(shù)有這些語句,則編譯器將該函數(shù)視同一般函數(shù)那樣產(chǎn)生函數(shù)調(diào)用。(4)遞歸函數(shù)不能用作內(nèi)置函數(shù)。(5)以后講到的類中,所有定義在說明內(nèi)部的函數(shù)都是內(nèi)置函數(shù)。整理ppt3.6.1變量的作用域

首先將變量按作用域大小分類,可以分為局部變量和全局變量。C++中并不是所有的變量對任何函數(shù)都是可知的。一些變量在整個程序或文件中都是可見的,這些變量作用域大,被稱為全局變量。一些變量只能在一個函數(shù)或塊中可見,這些變量作用域小,被稱為局部變量。變量作用域的大小和它們的存儲區(qū)域有關(guān)。全局變量存儲在全局數(shù)據(jù)區(qū)(也稱為靜態(tài)存儲區(qū)),它在程序運行的時候被分配存儲空間,當(dāng)程序結(jié)束時釋放存儲空間。局部變量存儲在堆棧數(shù)據(jù)區(qū),當(dāng)程序執(zhí)行到該變量聲明的函數(shù)(或程序塊)時才開辟存儲空間,當(dāng)函數(shù)(或程序塊)執(zhí)行完畢時釋放存儲空間。而決定變量作用域大小的根源是它的定義位置。3.6變量和函數(shù)的屬性整理ppt1.局部變量局部變量是指定義在函數(shù)或程序塊內(nèi)的變量,它們的作用域分別在所定義的函數(shù)體或程序塊內(nèi)。下面是一些局部變量的實例:voidmain(){intx;//x為函數(shù)級的局部變量。其作用域為main()函數(shù)內(nèi)

……{inty;//y為語句塊級的局部變量,其作用域為該塊內(nèi)

……}……}voidfun(){charch;//ch為函數(shù)級局部變量,其作用域為fun()函數(shù)內(nèi)……}整理ppt【例3.10】局部變量的使用。#include<iostream.h>//*****ex3_10.cpp*****doublefun1(doublea,doubleb)//fun1函數(shù)中3個局部變量a、b、c{doublec;c=a+b;returnc;}doublefun2(doublea,doubleb)//fun2函數(shù)中3個局部變量a、b、c{doublec;c=a*b;returnc;}整理pptvoidmain()//main函數(shù)中3個局部變量a、b、c{doublea,b,c;cout<<"inputtwonumbers:";cin>>a>>b;c=fun1(a,b);cout<<"a+b="<<c<<endl;c=fun2(a,b);cout<<"a*b="<<c<<endl;}程序運行結(jié)果如下:inputtwonumbers:3.54↙

a+b=7.5a*b=14注意:不同范圍的局部變量可以同名,但同一范圍內(nèi)不允許同名變量出現(xiàn)(否則有沖突);上例每個函數(shù)中都定義了相同名稱的局部變量,比如有3個a;但這個范圍中定義的a與另一個范圍中定義的a并不是同一個對象,即“此a非彼a”。整理ppt全局變量是定義在函數(shù)以外的變量(一般的全局變量也稱外部變量,而一類特殊的全局變量則叫靜態(tài)全局變量),它們原則上對整個文件的函數(shù)都是可見的,甚至對本程序的其它文件的函數(shù)也可見;但通常條件下的全局變量作用域是從定義變量的位置到該文件的結(jié)束。2.全局變量整理ppt【例3.11】全局變量的使用#include<iostream.h>//*****ex3_11.cpp*****inta;//a的作用域為整個文件voidfun1();//聲明fun1函數(shù)voidmain(){cout<<a<<endl;//main函數(shù)中使用了全局變量afun1();//調(diào)用fun1函數(shù)cout<<a<<endl;//main函數(shù)中再次使用全局變量a}voidfun1(){a=5;}//fun1函數(shù)中使用全局變量a程序運行結(jié)果如下:05

整理ppt說明:(1)上例中,在主函數(shù)中第一次輸出變量a時,a還沒有賦值,但是執(zhí)行結(jié)果顯示0。(2)全局變量可以定義在任何位置,但其作用域是從定義的位置開始到文件的末尾。而定義在文件中間的全局變量就只能被其下面的函數(shù)所使用,全局變量定義之前的所有函數(shù)不會知道該變量。(3)全局變量為函數(shù)間數(shù)據(jù)的傳遞提供了通道。由于全局變量可以被其定義后的函數(shù)所使用,所以可以使用全局變量進行函數(shù)間數(shù)據(jù)的傳遞。而且這種傳遞數(shù)據(jù)的方法可以傳遞多個數(shù)據(jù)的值。整理ppt【例3.12】分別寫兩個函數(shù)求給定兩個數(shù)的最大公約數(shù)和最小公倍數(shù)。其中,要求用全局變量存放最大公約數(shù)和最小公倍數(shù)。分析:由于求最小公倍數(shù)要依賴于最大公約數(shù),所以應(yīng)先求最大公約數(shù)。故應(yīng)將求最大公約數(shù)的函數(shù)寫在前面,求最小公倍數(shù)的函數(shù)放在后面。#include<iostream.h>//*****ex3_12.cpp*****intgreatest_common_divisor(int,int);//聲明求最大公約數(shù)的函數(shù)intlease_common_multiple(int,int);//聲明求最小公倍數(shù)的函數(shù)intmax,min;//全局變量分別存放最大公約數(shù)、最小公倍數(shù)voidmain(){inta;intb;cout<<"inputa,b:";cin>>a>>b;greatest_common_divisor(a,b);lease_common_multiple(a,b);cout<<"thegreatestcommondivisoris:"<<max<<endl;//使用全局變量maxcout<<"theleasecommonmultipleis:"<<min<<endl;//使用全局變量min}整理pptintgreatest_common_divisor(intx,inty){intt;intr;if(x<y){t=x;x=y;y=t;}r=x%y;while(r!=0){x=y;y=r;r=x%y;}max=y;returnmax;//使用全局變量max}intlease_common_multiple(intx,inty){min=x*y/max;//使用全局變量max求全局變量min,returnmin;//返回全局變量min}整理ppt程序運行結(jié)果如下:inputa,b:3615↙thegreatestcommondivisoris:3theleasecommonmultipleis:180本例中利用全局變量max和min存儲最大公約數(shù)和最小公倍數(shù)。最大公約數(shù)是在函數(shù)greatest_common_divisor()中賦給max的;最小公倍數(shù)是在函數(shù)lease_common_multiple()中賦給min的,而max和min又在main()函數(shù)中使用。本程序的整個過程就是利用全局變量max和min由greatest_common_divisor()函數(shù)和lease_common_multiple()函數(shù)向main()函數(shù)傳遞數(shù)據(jù)實現(xiàn)的。整理ppt(4)其它文件也可以使用文件外定義的全局變量,但要求該變量是外部變量類型的全局變量,而且要求在使用該變量的文件中要有對該變量的聲明。外部變量跨文件使用的例子,請參考本章后面的【例3.16】。(5)全局變量降低了函數(shù)的通用性,建議不在必要時不要使用全局變量。因為如果函數(shù)在執(zhí)行的時候使用了全局變量,那么其他程序使用該函數(shù)時也必須將該全局變量一起移過去。另外,全局變量在程序執(zhí)行的全部過程都占用存儲空間,而不是需要時才開辟存儲空間。整理ppt3.重名局部變量和全局變量作用域規(guī)則在C++中,雖然不允許相同作用域的變量同名,但允許不同作用域的變量同名。那么在一個特定的位置引用到某個有重名的變量時,到底是使用哪個變量呢?這由如下重名變量作用域規(guī)則決定:在某個作用域范圍內(nèi)定義的變量在該范圍的子范圍內(nèi)可以定義重名變量,這時原定義的變量在子范圍內(nèi)是不可見的,但是它還存在,只是在子范圍內(nèi)由于出現(xiàn)了重名的變量而被暫時隱藏起來,過了子范圍后,它又是可見的。整理ppt【例3.13】函數(shù)中變量和程序塊中變量重名#include<iostream.h>//*****ex3_13.cpp*****voidmain(){inta=1,b=2,c=3;cout<<a<<","<<b<<","<<c<<endl;{intb=4;cout<<a<<","<<b<<","<<c<<endl;a=b;{intc;c=b;cout<<a<<","<<b<<","<<c<<endl;}cout<<a<<","<<b<<","<<c<<endl;}cout<<a<<","<<b<<","<<c<<endl;}程序運行結(jié)果如下:1,2,31,4,34,4,44,4,34,2,3整理ppt【例3.14】全局變量和局部變量重名#include<iostream.h>//*****ex3_14.cpp*****voidfun1();floatx=3.5;voidmain(){floatx;cout<<"inputadata:";cin>>x;cout<<"xinmainis:"<<x<<endl;fun1();cout<<"xinmainis:"<<x<<endl;}voidfun1(){cout<<"xinfun1is:"<<x<<endl;}運行結(jié)果:inputadata:6.6↙xinmainis:6.6xinfun1is:3.5xinmainis:6.6整理ppt從變量的空間屬性考慮變量有作用域的概念。那么,從變量的時間屬性考慮變量還有存儲期(storageduration,也稱生命期)的概念,存儲期即變量值在內(nèi)存中存在的時間。而變量的存儲期是由變量的存儲類別決定的,有兩種存儲類別:動態(tài)存儲方式與靜態(tài)存儲方式。3.6.2變量的生存期

整理ppt1.短生存期變量――動態(tài)存儲方式所謂動態(tài)存儲方式,是指在程序運行期間動態(tài)地分配存儲空間給變量的方式。這類變量存儲在動態(tài)存儲空間(堆或棧),執(zhí)行其所在函數(shù)或程序塊時開辟存儲空間,函數(shù)或程序塊結(jié)束時釋放存儲空間,生存期為函數(shù)或程序塊的運行期間,主要有:函數(shù)的形參和函數(shù)或程序塊中定義的局部變量(未用static聲明)。使用動態(tài)存儲方式的變量有兩種:自動變量和寄存器類變量。

整理ppt(1)自動變量:函數(shù)中的局部變量默認是自動變量,存儲在動態(tài)數(shù)據(jù)存儲區(qū)。自動變量可以用關(guān)鍵字auto作為存儲類別的聲明。自動變量的生存期為函數(shù)或程序塊執(zhí)行期間,作用域也是其所在函數(shù)或程序塊。例如:intfun(){autointa;//a為自動類變量}

實際編程過程中,關(guān)鍵字“auto”可以省略。例如上述自動變量也可聲明為下面形式:intfun(){inta;}整理ppt(2)寄存器變量:寄存器變量也是動態(tài)變量,可以用register作為存儲類別的聲明。寄存器變量存儲在CPU的通用寄存器中,因此訪問效率高。寄存器變量的生存期和作用域為其定義所在的函數(shù)或程序塊。一般情況下,將局部最常用到的變量聲明為寄存器變量,如循環(huán)變量。下面main()函數(shù)中的循環(huán)變量i就使用了寄存器變量:#include<iostream.h>voidmain(){registerinti;intsum=0;for(i=1;i<=100;i++)sum+=i;cout<<"1+2+...+100="<<sum<<endl;}程序運行結(jié)果如下:1+2+...+100=5050整理ppt寄存器變量的使用應(yīng)注意以下問題:(1)寄存器變量不宜定義過多。計算機中寄存器數(shù)量是有限的,不能允許所有的變量都為寄存器變量。如果寄存器變量過多或通用寄存器被其他數(shù)據(jù)使用,那么系統(tǒng)將自動把寄存器變量轉(zhuǎn)換成自動變量。(2)寄存器變量的數(shù)據(jù)長度與通用寄存器的長度相當(dāng)。一般是char型和int型變量。整理ppt2.長生存期變量――靜態(tài)存儲方式所謂靜態(tài)存儲方式,是指在程序運行期間分配固定的存儲空間給變量的方式。這類變量存儲在全局數(shù)據(jù)區(qū),當(dāng)程序運行時開辟存儲空間,程序結(jié)束時釋放存儲空間,生存期為程序運行期間。采用靜態(tài)存儲方式的變量有:全局變量(含外部變量、靜態(tài)全局變量)和靜態(tài)局部變量。(1)外部變量:外部變量就是只用數(shù)據(jù)類型關(guān)鍵字而未用static關(guān)鍵字定義的全局變量。存儲在全局數(shù)據(jù)區(qū),生存期為程序執(zhí)行期間。如果不對外部變量另加聲明,則它的作用域是從定義點到所在文件的末尾。整理ppt其實,外部變量不管在何處定義,可以通過用extern關(guān)鍵詞加以聲明后將其作用域擴展到整個程序,聲明語句格式為:extern外部變量名;這種擴展作用域的聲明語句有兩種情況用到:①對文件內(nèi)容后面位置所定義的外部變量x,將其作用域擴展到本文件前面的函數(shù)。這時只要在該文件的前面用extern對該變量x聲明即可,這叫做提前引用聲明。②對本程序的另一個源文件B中定義的外部變量y,要想擴展到本文件A中使用,這時只要在本文件A的前面用extern對該變量y聲明即可,不妨稱此為跨文件引用聲明。

整理ppt【例3.15】對定義在同一文件中外部變量,作提前引用聲明以擴展其使用范圍到文件前面。#include<iostream.h>//*****ex3_15.cpp*****externx;//提前引用聲明voidmain(){x=4;cout<<x<<endl;}intx;//外部變量x的定義整理ppt【例3.16】對定義在另一文件中的外部變量,作跨文件引用聲明以擴展其作用域到本文件。文件file1.cpp的內(nèi)容:#include<iostream.h>//*****ex3_16.cpp*****externw;//跨文件引用聲明voidmain(){cout<<w<<endl;//使用file2.cpp文件中定義的變量w}文件file2.cpp的內(nèi)容:intw=10;//外部變量w的定義intfun(intx,inty){return(x+y);}程序運行結(jié)果如下:10整理ppt(2)靜態(tài)變量:靜態(tài)變量存儲在全局數(shù)據(jù)區(qū),使用static聲明。靜態(tài)變量有兩種:靜態(tài)局部變量和靜態(tài)全局變量。①靜態(tài)局部變量是在定義局部變量時開頭再添加一個static關(guān)鍵字所定義的。靜態(tài)局部變量的特點是:程序執(zhí)行時,為其開辟存儲空間直到程序結(jié)束,但只能被其定義所在的函數(shù)或程序塊所使用。所以靜態(tài)局部變量的生命周期為程序執(zhí)行期間,作用域為其定義所在的函數(shù)或程序塊內(nèi)。如果沒有定義靜態(tài)局部變量的初始值,系統(tǒng)將自動初始化為0。整理ppt【例3.17】靜態(tài)局部變量的使用#include<iostream.h>//*****ex3_17.cpp*****voidfun();voidmain(){inti;for(i=0;i<3;i++)fun();}voidfun(){inta=0;staticintb=0;//定義靜態(tài)局部變量

a=a+1;b=b+1;cout<<a<<","<<b<<endl;}程序運行結(jié)果如下:1,11,21,3整理ppt②靜態(tài)全局變量是在定義全局變量時開頭再添加一個static關(guān)鍵字所定義的。靜態(tài)全局變量的特點是:程序執(zhí)行時,為其在全局數(shù)據(jù)區(qū)開辟存儲空間并初始化為0,直存儲期仍與外部變量一樣一直延續(xù)到程序結(jié)束。但其作用域受限于只能被其定義所在的文件使用,而不能借助前面所講的跨文件引用聲明擴展到文件外。整理ppt【例3.18】靜態(tài)全局變量的演示。文件file1.cpp的內(nèi)容:#include<iostream.h>//*****ex3_18.cpp*****staticintu=10;//定義靜態(tài)全局變量voidfun(){cout<<”Thisisfile1”}文件file2.cpp的內(nèi)容:#include<iostream.h>externu;//試圖對u作跨文件引用聲明,此時行不通voidmain(){cout<<u<<endl;//出現(xiàn)“變量u未定義”錯誤}整理ppt【例3.18】中,文件file1.cpp中定義的全局變量u加了static關(guān)鍵字,成為靜態(tài)全局變量;因此不能擴展作用域到文件file2.cpp。去掉文件file1.cpp中第二句前的static關(guān)鍵字程序就正確。static作用的總結(jié):static關(guān)鍵字加在局部變量前是延長局部變量的存儲期(但不改變其作用域);static關(guān)鍵字加在全局變量前是限制全局變量的作用域(但不改變其存儲期)。整理ppt函數(shù)按其存儲類別也可以分為兩類:1、內(nèi)部函數(shù)2、外部函數(shù)

3.6.3內(nèi)部函數(shù)和外部函數(shù)

整理ppt如果一個函數(shù)只能被本文件中其他函數(shù)所調(diào)用,它稱為內(nèi)部函數(shù)。在定義內(nèi)部函數(shù)時,在函數(shù)名和函數(shù)類型的前面加static。函數(shù)首部的一般格式為static類型標(biāo)識符函數(shù)名(形參表)如staticintfun(inta,intb)內(nèi)部函數(shù)又稱靜態(tài)(static)函數(shù)。使用內(nèi)部函數(shù),可以使函數(shù)只局限于所在文件。如果在不同的文件中有同名的內(nèi)部函數(shù),互不干擾。通常把只能由同一文件使用的函數(shù)和外部變量放在一個文件中,在它們前面都冠以static使之局部化,其他文件不能引用。1內(nèi)部函數(shù)整理ppt【例3.19】靜態(tài)函數(shù)的例子。文件file1.cpp中的內(nèi)容:#include<iostream.h>//*****ex3_19.cpp*****staticvoidfun();voidmain(){fun();}staticvoidfun()//文件file1中定義靜態(tài)函數(shù),名稱為fun{cout<<"thisinfile1"<<endl;}文件file2.cpp中的內(nèi)容:#include<iostream.h>staticvoidfun()//文件file2中定義靜態(tài)函數(shù),名稱也為fun{cout<<"thisinfile2"<<endl;}程序運行結(jié)果如下:thisinfile1整理ppt2外部函數(shù)外部函數(shù)是可以被整個程序各文件調(diào)用的函數(shù)。(1)外部函數(shù)的定義。在函數(shù)類型前加存儲類型關(guān)鍵字extern,或缺省存儲類型關(guān)鍵字,定義格式如下:[extern]函數(shù)類型函數(shù)名([參數(shù)列表]){

函數(shù)體}如果定義時沒有寫上函數(shù)的存儲類型關(guān)鍵字,則系統(tǒng)默認為extern型,即extern可缺省。整理ppt(1)外部函數(shù)的聲明。文件A在需要調(diào)用文件B中所定義的外部函數(shù)時,需要在文件A中用關(guān)鍵字extern對被調(diào)函數(shù)提出聲明,聲明格式如下:extern函數(shù)類型函數(shù)名(參數(shù)類型列表)【例3.20】文件file1.cpp利用別的文件(file2.cpp)中的外部函數(shù)實現(xiàn)求階乘。文件file1.cpp中的內(nèi)容:#include<iostream>//*****ex3_20.cpp*****usingnamespacestd;voidmain(){externdoublefac(int);//聲明其他文件中定義的外部函數(shù)intn;cout<<"pleaseinputaintegerton:"<<endl;cin>>n;cout<<n<<"!="<<fac(n)<<endl;}整理ppt文件file2.cpp中的內(nèi)容:#include<iostream>usingnamespacestd;externdoublefac(intm)//定義fac函數(shù){intn;doubles;s=1;for(n=1;n<=m;n++)s=s*n;returns;}程序運行結(jié)果如下:pleaseinputaintegerton:5↙5!=120文件file2.cpp中也可以將extern省略,定義為:doublefac(intm);{}整理ppt3.7編譯預(yù)處理可以在C++源程序中加入一些“預(yù)處理命令”,以改進程序設(shè)計環(huán)境,提高編程效率。預(yù)處理命令是C++統(tǒng)一規(guī)定的,但是它不是C++語言本身的組成部分,不能直接對它們進行編譯(因為編譯程序不能識別它們)。現(xiàn)在使用的C++編譯系統(tǒng)都包括了預(yù)處理、編譯和連接等部分,因此不少用戶誤認為預(yù)處理命令是C++語言的一部分,甚至以為它們是C++語句,這是不對的。必須正確區(qū)別預(yù)處理命令和C++語句,區(qū)別預(yù)處理和編譯,才能正確使用預(yù)處理命令。C++與其他高級語言的一個重要區(qū)別是可以使用預(yù)處理命令和具有預(yù)處理的功能。整理pptC++提供的預(yù)處理功能主要有以下3種:(1)宏定義(2)文件包含(3)條件編譯分別用宏定義命令、文件包含命令、條件編譯命令來實現(xiàn)。為了與一般C++語句相區(qū)別,這些命令以符號“#”開頭,而且末尾不包含分號。整理ppt宏定義的作用是實現(xiàn)文本替換。有兩種格式:不帶參數(shù)的宏定義;帶參數(shù)的宏定義。1.不帶參數(shù)的宏定義不帶參數(shù)宏定義的格式如下:#define宏名字符串其中,define是關(guān)鍵字,“宏名”是一個標(biāo)識符,“字符串”是字符序列。該語句的意思是“宏名”代表“字符串”。執(zhí)行該預(yù)處理代碼時,編譯系統(tǒng)將對程序語句中出現(xiàn)的“宏名”統(tǒng)統(tǒng)用“字符串”替代。3.7.1宏定義整理ppt【例3.21】利用宏表示圓周率,求圓面積。#include<iostream.h>//*****ex3_21.cpp*****#definePI3.14159//宏定義。宏名是PI,PI將用3.14159替代voidmain(){doubles,r;cout<<"inputr:";cin>>r;s=PI*r*r;cout<<"theresultis:"<<s<<endl;}程序運行結(jié)果如下:inputr:3↙theresultis:28.2743整理ppt說明:(1)在定義宏時,“宏名”和“字符串”之間要用空格分開。而“字符串”中的內(nèi)容不要有空格。(2)宏名通常用大寫字母定義。(3)宏定義是在編譯前對宏進行替換的,但對程序中用雙引號括起來的字符串內(nèi)容,如果其中有與宏名相同的部分,是不進行文本替換的。例如:#include<iostream.h>#definePI3.14159voidmain(){cout<<"PI="<<PI<<endl;}程序運行結(jié)果如下:PI=3.14159上例中,對于雙引號中的PI沒有替換而直接輸出,只是把第二個PI進行了替換。整理ppt(4)宏定義后,可以在本文件各個函數(shù)中使用。也可以使用#undef取消宏的定義。(5)宏定義可以嵌套,已被定義的宏可以用來定義新的宏。例如:#include<iostream.h>#defineM3#defineNM+2//宏定義嵌套定義,用已定義的宏M來定義新的宏N#defineL4*N+6//宏定義嵌套定義,用已定義的宏

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論