




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
3.1函數(shù)的定義和聲明
(FunctionDefinitionandDeclaration)3.2函數(shù)的調(diào)用與參數(shù)傳遞
(FunctionCallandParameterPassing)
3.3內(nèi)聯(lián)函數(shù)(InlineFunctions)3.4函數(shù)重載(FunctionOverloading)
3.5帶默認(rèn)形參值的函數(shù)
(FunctionwithDefaultArguments)
3.6作用域與生存期(ScopesandLifetime)3.7多文件結(jié)構(gòu)(Multi-FileStructure)
3.8常見(jiàn)編程錯(cuò)誤(CommonProgrammingErrors)本章小結(jié)(ChapterSummary)習(xí)題3(Exercises3)
一個(gè)C++?程序可由一個(gè)或多個(gè)源程序文件組成。一個(gè)源程序文件可由一個(gè)或多個(gè)函數(shù)組成。函數(shù)是構(gòu)成C++?程序的基礎(chǔ),任何一個(gè)C++?源程序都是由若干函數(shù)組成的。C++?中的函數(shù)分為庫(kù)函數(shù)與自定義函數(shù)兩類。3.1函數(shù)的定義和聲明(FunctionDefinitionandDeclaration)3.1.1函數(shù)的定義(FunctionDefinition)
函數(shù)可以被看做是一個(gè)由用戶定義的操作。函數(shù)用一個(gè)函數(shù)名來(lái)表示。
函數(shù)的操作數(shù)稱為參數(shù),由一個(gè)位于括號(hào)中并且用逗號(hào)分隔的參數(shù)表指定。
在C++?程序中,調(diào)用函數(shù)之前首先要對(duì)函數(shù)進(jìn)行定義。如果調(diào)用此函數(shù)在前,定義函數(shù)在后,則會(huì)產(chǎn)生編譯錯(cuò)誤。
1.無(wú)參函數(shù)的一般形式
無(wú)參函數(shù)的一般形式如下:
類型說(shuō)明符
函數(shù)名()
{
類型說(shuō)明
語(yǔ)句
}類型說(shuō)明符指明了本函數(shù)的類型。函數(shù)的類型實(shí)際上是函數(shù)返回值的類型。此處的類型說(shuō)明符與第2章介紹的各種說(shuō)明符相同。
函數(shù)名是由用戶定義的標(biāo)識(shí)符。定義函數(shù)名與定義變量名的規(guī)則是一樣的,但應(yīng)盡量避免用下劃線開(kāi)頭,因?yàn)榫幾g器常常定義一些下劃線開(kāi)頭的變量或函數(shù)。在很多情況下都不要求無(wú)參函數(shù)有返回值,
此時(shí)函數(shù)類型說(shuō)明符可以寫為void。
例如:
void
Hello()
{
cout<<“Helloworld”<<endl;
}
2.有參函數(shù)的一般形式
有參函數(shù)的一般形式如下:
類型說(shuō)明符
函數(shù)名(形式參數(shù)表)
形式參數(shù)類型說(shuō)明
{
類型說(shuō)明
語(yǔ)句
}在進(jìn)行函數(shù)調(diào)用時(shí),主調(diào)函數(shù)將賦予這些形式參數(shù)實(shí)際的值。形參既然是變量,當(dāng)然必須給以類型說(shuō)明。
例如,定義一個(gè)函數(shù),
用于求兩個(gè)數(shù)中的大數(shù),程序如下:
int
max(a,b)
int
a,b;
{
if
(a>b)
return
a;
else
return
b;
}
這種格式不易進(jìn)行編譯系統(tǒng)檢查,從而會(huì)引起一些非常細(xì)微而且難以跟蹤的錯(cuò)誤。新標(biāo)準(zhǔn)中把對(duì)形參的類型說(shuō)明合并到形參表中,稱為“現(xiàn)代格式”。
例如,max函數(shù)用現(xiàn)代格式可定義如下:
int
max(int
a,int
b)
{
if(a>b)
return
a;
else
return
b;
}
【例3-1】max函數(shù)的位置示例。
#include<iostream>
usingnamespacestd;
int
max(int
a,int
b)
{
if(a>b)return
a;
else
return
b;
}
void
main()
{
int
max(int
a,int
b);
int
x,y,z;
cout<<“input
two
numbers:”<<endl);
cin>>x>>y;
z=max(x,y);
cout<<"maxmum="<<z<<endl;
}在C++?語(yǔ)言中,所有的函數(shù)定義(包括主函數(shù)main在內(nèi))都是平行的。但是函數(shù)之間允許相互調(diào)用,也允許嵌套調(diào)用。
因此,C++?程序的執(zhí)行總是從main函數(shù)開(kāi)始,完成對(duì)其他函數(shù)的調(diào)用后再返回到main函數(shù),最后由main函數(shù)結(jié)束整個(gè)程序。一個(gè)C++?源程序必須有且只能有一個(gè)主函數(shù)main。3.1.2函數(shù)的聲明(FunctionDeclaration)
C++中函數(shù)聲明又稱為函數(shù)原型。標(biāo)準(zhǔn)庫(kù)函數(shù)的函數(shù)原型都在頭文件中提供,程序中可以用?#include指令包含這些原型文件。對(duì)于用戶自定義函數(shù),程序員應(yīng)該在源代碼中說(shuō)明函數(shù)原型。函數(shù)原型是一條程序語(yǔ)句,它由函數(shù)首部和分號(hào)組成,其一般形式如下:
<函數(shù)類型>函數(shù)名(<形參列表>);函數(shù)聲明和函數(shù)首部的異同如下:
(1)兩者的函數(shù)名、函數(shù)類型完全相同。
(2)兩者中形參的數(shù)量、次序、類型完全相同。
(3)函數(shù)聲明中的形參可以省略名稱,只聲明形參類型,而函數(shù)首部不能。
(4)函數(shù)聲明是語(yǔ)句,而函數(shù)首部不是。
(5)當(dāng)函數(shù)定義在調(diào)用它的函數(shù)前時(shí),函數(shù)聲明不是必需的;否則,必須在調(diào)用它之前進(jìn)行函數(shù)聲明。如例3-1中max()函數(shù)定義在main()函數(shù)前,所以可以不用函數(shù)聲明。但是如果把max()函數(shù)定義在main()函數(shù)之后,則應(yīng)該寫成如下形式:
?#include<iostream>
usingnamespacestd;
int
max(int
a,int
b); //函數(shù)聲明
void
main() //主函數(shù)
{int
max(int
a,int
b);
int
x,y,z;
cout<<"input
two
numbers:"<<endl);
cin>>x>>y;
z=max(x,y);
cout<<"maxmum="<<z<<endl;}
int
max(int
a,int
b) //用戶定義函數(shù)
{
if(a>b)return
a;
else
return
b;
}【例3-2】
實(shí)現(xiàn)兩個(gè)數(shù)相加。
程序如下:
#include<iostream>
usingnamespacestd;
intadd(int,int); //函數(shù)原型
voidmain()
{ intsum,x,y;
cout<<"請(qǐng)輸入被加數(shù)和加數(shù):"<<endl;
cin>>x>>y;
sum=add(x,y); //函數(shù)調(diào)用
cout<<"Sum="<<sum<<endl;
}
intadd(inta,intb) //函數(shù)定義{
returna+b;
}
運(yùn)行結(jié)果:
請(qǐng)輸入被加數(shù)和加數(shù):
213625
Sum=8383.1.3函數(shù)值和函數(shù)類型
(FunctionValuesandFunctionTypes)
1.函數(shù)返回值與函數(shù)類型
通常函數(shù)被調(diào)用總是希望得到一個(gè)確定的值,即函數(shù)的返回值。函數(shù)的返回值確定了函數(shù)的類型,即函數(shù)類型就是返回值的類型。
1)有返回值函數(shù)
此類函數(shù)被調(diào)用執(zhí)行完后將向調(diào)用者返回一個(gè)執(zhí)行結(jié)果,即函數(shù)返回值,數(shù)學(xué)函數(shù)即屬于此類函數(shù)。例如:
intsum(inta,intb)//有返回值,返回類型為整型
{
return(a+b);
}
2)無(wú)返回值函數(shù)
此類函數(shù)用于完成某項(xiàng)特定的處理任務(wù),
執(zhí)行完成后不向調(diào)用者返回函數(shù)值。這類函數(shù)類似于其他語(yǔ)言的過(guò)程。
例如:
voidprintsum(inta,intb)//無(wú)返回值
{
cout<<a+b<<endl;
}
2.return語(yǔ)句
函數(shù)的返回值是通過(guò)return語(yǔ)句獲得的。return語(yǔ)句的一般格式如下:
return(表達(dá)式);
或
return表達(dá)式;
或
return;
說(shuō)明:
(1)返回值可以用括號(hào)括起來(lái),也可以不括起來(lái),還可以沒(méi)有返回值。
(2)一個(gè)函數(shù)如果有一個(gè)以上return語(yǔ)句,則當(dāng)執(zhí)行到第一條return語(yǔ)句時(shí)函數(shù)返回確定的值并退出函數(shù),其他語(yǔ)句不被執(zhí)行。例如,下面函數(shù)的第二條return語(yǔ)句不能執(zhí)行。
intfun()
{
inta,b;
…
returna;//該語(yǔ)句執(zhí)行且返回a的值
returnb;//該語(yǔ)句不被執(zhí)行
}
(3)?return語(yǔ)句可以返回一個(gè)表達(dá)式的值。
(4)在無(wú)返回值的函數(shù)體中可以沒(méi)有return語(yǔ)句,函數(shù)執(zhí)行到函數(shù)體的最后一條語(yǔ)句,遇到花括號(hào)“}”時(shí),自動(dòng)返回到主調(diào)用程序。
(5)如果return語(yǔ)句中表達(dá)式的值和函數(shù)的值其類型不一致,則以函數(shù)類型為準(zhǔn)。
(6)如果沒(méi)有使用return返回一個(gè)具體的值,而函數(shù)又不是void型,則返回值為一個(gè)隨機(jī)整數(shù)。在C++?語(yǔ)言中可從不同的角度對(duì)函數(shù)進(jìn)行分類。
(1)從函數(shù)定義的角度,函數(shù)可分為庫(kù)函數(shù)和用戶定義函數(shù)兩種。
(2)從主調(diào)函數(shù)和被調(diào)函數(shù)之間數(shù)據(jù)傳送的角度,函數(shù)又可分為無(wú)參函數(shù)和有參函數(shù)兩種。3.2.1函數(shù)的調(diào)用(FunctionCall)
函數(shù)調(diào)用用一個(gè)表達(dá)式來(lái)表示。函數(shù)調(diào)用的一般形式如下:
函數(shù)名(實(shí)際參數(shù)表)
其中,函數(shù)名是由用戶自定義或C++?提供的標(biāo)準(zhǔn)函數(shù)名;實(shí)際參數(shù)表是由逗號(hào)分隔的若干個(gè)表達(dá)式,每個(gè)表達(dá)式的值為實(shí)參。實(shí)參用來(lái)在調(diào)用函數(shù)時(shí)對(duì)形參進(jìn)行初始化,實(shí)參與形參的個(gè)數(shù)相同,類型一致,順序一致。3.2函數(shù)的調(diào)用與參數(shù)傳遞(FunctionCallandParameterPassing)
1.函數(shù)調(diào)用的格式
在C++?語(yǔ)言中,可以用以下幾種方式調(diào)用函數(shù)。
1)函數(shù)表達(dá)式
如果在函數(shù)定義時(shí)需要返回某個(gè)數(shù)值,則return語(yǔ)句后必須有表達(dá)式。
2)函數(shù)語(yǔ)句
函數(shù)調(diào)用的一般形式加上分號(hào)即構(gòu)成函數(shù)語(yǔ)句。
3)函數(shù)實(shí)參
函數(shù)實(shí)參是指函數(shù)作為另一個(gè)函數(shù)調(diào)用的實(shí)際參數(shù)出現(xiàn)。
2.函數(shù)調(diào)用的過(guò)程
當(dāng)調(diào)用一個(gè)函數(shù)時(shí),整個(gè)調(diào)用過(guò)程分為以下三步進(jìn)行:
(1)函數(shù)調(diào)用。
(2)函數(shù)體執(zhí)行,即逐條運(yùn)行函數(shù)體中語(yǔ)句的過(guò)程。
(3)返回,即返回到函數(shù)調(diào)用表達(dá)式的位置。返回過(guò)程執(zhí)行的是函數(shù)體中的return語(yǔ)句。3.2.2函數(shù)調(diào)用時(shí)的參數(shù)傳遞(ParameterPassing)
參數(shù)傳遞稱為“實(shí)虛結(jié)合”,即實(shí)參向形參傳遞信息,使形參具有確切的含義(即具有對(duì)應(yīng)的存儲(chǔ)空間和初值)。
1.按值傳遞
以按值傳遞方式進(jìn)行參數(shù)傳遞的過(guò)程為:首先計(jì)算出實(shí)參表達(dá)式的值,接著給對(duì)應(yīng)的形參變量分配一個(gè)存儲(chǔ)空間,該空間的大小等于該形參類型的長(zhǎng)度,然后把已求出的實(shí)參表達(dá)式的值一一存入到為形參變量分配的存儲(chǔ)空間中,成為形參變量的初值,供被調(diào)用函數(shù)執(zhí)行時(shí)使用?!纠?-3】
按值傳遞。
程序如下:
#include<iostream>
usingnamespacestd;
voidswap(int,int);
voidmain()
{inta=3,b=4;
cout<<"a="<<a<<",b="
<<b<<endl;
swap(a,b);
cout<<"a="<<a<<",b="
<<b<<endl;
}
voidswap(intx,inty)
{
intt=x;
x=y;
y=t;
}
運(yùn)行結(jié)果:
a=3,b=4關(guān)于按值傳遞應(yīng)當(dāng)注意下面幾個(gè)問(wèn)題:
(1)形參在沒(méi)有被調(diào)用時(shí),不占用存儲(chǔ)空間。
(2)調(diào)用函數(shù)時(shí),應(yīng)該注意函數(shù)的實(shí)參與形參類型一致,否則會(huì)出現(xiàn)錯(cuò)誤。
(3)?C++函數(shù)中參數(shù)的求值順序?yàn)樽杂抑磷螅碈++函數(shù)中實(shí)參的值是從右到左確定的?!纠?-4】函數(shù)參數(shù)的傳遞順序。
程序如下:
#include<iostream>
usingnamespacestd;
intsome_fun(inta,intb)
{
returna+b;
}
voidmain()
{
intx,y;
x=2;y=3;
cout<<some_fun(++x,x+y)<<endl;
x=2;y=3;
cout<<some_fun(x+y,++x)<<endl;
}
運(yùn)行結(jié)果:
8
9
2.地址傳遞
如果在函數(shù)定義時(shí)將形參的類型說(shuō)明成指針,則對(duì)這樣的函數(shù)進(jìn)行調(diào)用時(shí)就需要指定地址值形式的實(shí)參,這時(shí)的參數(shù)傳遞方式即為地址傳遞方式。與按值傳遞不同,地址傳遞把實(shí)參的存儲(chǔ)地址傳送給對(duì)應(yīng)的形參,從而使得形參指針和實(shí)參指針指向同一個(gè)地址。因此,被調(diào)用函數(shù)中對(duì)形參指針?biāo)赶虻牡刂分袃?nèi)容的任何改變都會(huì)影響到實(shí)參。
【例3-5】
地址傳遞。
程序如下:
#include<iostream.h>
voidswap(int*,int*);
voidmain()
{
inta=3,b=4;
cout<<"a="<<a<<",b="
<<b<<endl;
swap(&a,&b);
cout<<"a="<<a<<",b="
<<b<<endl;
}
voidswap(int*x,int*y){
intt=*x;
*x=*y;
*y=t;
}
運(yùn)行結(jié)果:
a=3,b=4
a=4,b=3
3.引用傳遞
1)引用的概念
引用作為C++?提供的一種新的特性,在程序設(shè)計(jì)中給人們帶來(lái)了很大的方便。
引用的語(yǔ)法格式如下:
數(shù)據(jù)類型&引用名=數(shù)據(jù)類型變量名;
例如,定義一個(gè)整型變量的引用:
inta;
int&refa=a;此時(shí)refa作為a的別名,系統(tǒng)沒(méi)有為refa分配內(nèi)存空間,它和a代表的是相同的內(nèi)存空間,對(duì)refa的改變即是對(duì)a的改變。又如:
refa=100;
a=a-50;
cout<<a<<endl;
輸出結(jié)果為50?!纠?-6】引用的建立和使用。
#include<iostream>
usingnamespacestd;
intmain()
{
inta=30,b=20;
int&refa=a,&refb=b;
refa=a+20;
b=refb+10;
cout<<refa<<""<<a<<endl;
cout<<refb<<""<<b<<endl; refa=b;
//此時(shí)引用refa仍舊是a的別名,只是把b的值給了?a
cout<<refa<<""<<a<<endl;
return0;
}
運(yùn)行結(jié)果:
5050
3030
3030
2)引用的傳遞方式
按值傳遞方式容易理解,但形參值的改變不能對(duì)實(shí)參產(chǎn)生影響。
【例3-7】
引用傳遞。
程序如下:
#include<iostream>
usingnamespacestd;
voidswap(int&,int&);
voidmain()
{inta=3,b=4;
cout<<"a="<<a<<",b="
<<b<<endl;
swap(a,b);
cout<<"a="<<a<<",b="
<<b<<endl;
}
voidswap(int&x,int&y){
intt=x;
x=y;
y=t;
}
運(yùn)行結(jié)果:
a=3,b=4
a=4,b=33.2.3函數(shù)的嵌套調(diào)用和遞歸調(diào)用
(FunctionNestingCallandRecursionCall)
1.函數(shù)的嵌套調(diào)用
若在一個(gè)函數(shù)調(diào)用中又調(diào)用了另外一個(gè)函數(shù),則稱這樣的調(diào)用過(guò)程為函數(shù)的嵌套調(diào)用。程序執(zhí)行時(shí)從主函數(shù)開(kāi)始執(zhí)行,遇到函數(shù)調(diào)用時(shí),如果函數(shù)是有參函數(shù),則系統(tǒng)先進(jìn)行實(shí)參對(duì)形參的替換,然后執(zhí)行被調(diào)用函數(shù)的函數(shù)體;如果函數(shù)體中還調(diào)用了其他函數(shù),則再轉(zhuǎn)入執(zhí)行其他函數(shù)體。
【例3-8】
函數(shù)的嵌套調(diào)用,求三個(gè)數(shù)中最大數(shù)和最小數(shù)的差值。
程序如下:
#include<iostream>
usingnamespacestd;
intmax(intx,inty,intz)
{
intt;
t=x>y?x:y;
return(t>z?t:z);
}intmin(intx,inty,intz)
{
intt;
t=x<y?x:y;
return(t<z?t:z);
}
intdif(intx,inty,intz)
{
returnmax(x,y,z)-min(x,y,z);
}
voidmain(){
inta,b,c;
cin>>a>>b>>c;
cout<<"Max-Min="<<dif(a,b,c)<<endl;
}
運(yùn)行結(jié)果:
5-615↙
21
2.函數(shù)的遞歸調(diào)用
C++程序中允許函數(shù)遞歸調(diào)用。例如:
intfun1()
{
… //函數(shù)其他部分
z=fun1(); //直接調(diào)用自身
…
//函數(shù)其他部分
}
則在函數(shù)fun1()中,又調(diào)用了fun1()函數(shù),這種調(diào)用稱為直接調(diào)用,調(diào)用過(guò)程如圖3-1所示。圖3-1直接調(diào)用過(guò)程示意圖又如:
intfun2()
{
x=fun3();
}
intfun3()
{
y=fun2();
}
即函數(shù)fun2()中調(diào)用了fun3(),而fun3()中又調(diào)用了fun2(),這種調(diào)用稱為間接遞歸調(diào)用,調(diào)用過(guò)程如圖3-2所示。圖3-2間接調(diào)用過(guò)程示意圖遞歸函數(shù)的一般形式如下:
函數(shù)類型遞歸函數(shù)名f(參數(shù)x)
{
if(滿足結(jié)束條件)
結(jié)果=初值;
else
結(jié)果=含f(x-1)的表達(dá)式;
返回結(jié)果;
}【例3-9】
編程計(jì)算某個(gè)正整數(shù)的階乘。
程序如下:
#include<iostream>
usingnamespacestd;
longintfac(intn)
{
inttotal;
if(n==1||n==0)total=1;
elsetotal=fac(n-1)*n;
returntotal;
}
voidmain()
{
intn;
cout<<"pleaseinputainteger:";
cin>>n;
cout<<n<<"!is"<<fac(n)<<endl;
}
運(yùn)行結(jié)果:
pleaseinputainteger:12↙
12!is479001600
(1)遞歸調(diào)用的兩個(gè)階段如下:
第一階段:遞推。將原問(wèn)題不斷分解為新的子問(wèn)題,逐漸從未知向已知遞推,最終達(dá)到已知的條件,即遞歸結(jié)束的條件,這時(shí)遞推階段結(jié)束。
第二階段:回歸。從已知條件出發(fā),按照遞推的逆過(guò)程,逐一求值回歸,最后到達(dá)遞歸的開(kāi)始處,結(jié)束回歸階段,完成遞歸調(diào)用。
圖3-3所示為以4的階乘為例的函數(shù)參數(shù)傳遞過(guò)程。
(2)遞歸可以使用非遞歸方法代替。圖3-3函數(shù)參數(shù)傳遞過(guò)程【例3-10】
用非遞歸方法求階乘。
程序如下:
longintfac(intn)
{
inttotal=1;
if(n>0)
{
while(n)
{
total*=n;
n--;
}
}
returntotal;
}
【例3-11】
漢諾塔問(wèn)題。有3個(gè)座A、B、C,開(kāi)始時(shí)A上有64個(gè)盤子,盤子大小不等,大的在下,小的在上,如圖3-4所示(為了便于表示,圖中只畫了4個(gè)盤子,64個(gè)盤子的情況其原理是一樣的)。問(wèn)題是如何把A上的64個(gè)盤子移到C上,要求每次只能移動(dòng)一個(gè)盤子,且在移動(dòng)過(guò)程中始終保持大的盤子在下,小的盤子在上。圖3-4漢諾塔問(wèn)題示意圖
分析:這個(gè)問(wèn)題的解決方法為:將63個(gè)盤子從A移到B上,再把最大的盤子從A移到C上,最后把B上的63個(gè)盤子移到C上。這個(gè)過(guò)程中,將A上63個(gè)盤子移到B上和最后將B上的63個(gè)盤子移到C上,又可以看成兩個(gè)有63個(gè)盤子的漢諾塔問(wèn)題,所以也用上述方法解決。依次遞推,最后可以將漢諾塔問(wèn)題轉(zhuǎn)變成將一個(gè)盤子由一個(gè)座移動(dòng)到另一個(gè)座的問(wèn)題。對(duì)于一個(gè)盤子移動(dòng)的問(wèn)題,可以直接使用A--->B表示,只要設(shè)計(jì)一個(gè)輸出函數(shù)即可。將n個(gè)盤子從A移到C可分解為三步,如圖3-5所示。圖3-5將n個(gè)盤子從A移到C示意圖程序如下:
#include<iostream>
usingnamespacestd;
voidmove(intn,charsource,chartarget)
{
cout<<"("<<n<<","<<source<<"--->"<<target<<")"<<endl;
}
voidhanoi(intn,charA,charB,charC)
{if(n==1)
move(1,A,C);
else
{
hanoi(n-1,A,C,B);
move(n,A,C);
hanoi(n-1,B,A,C);
}
}voidmain()
{
intnum;
cout<<"Inputthenumberofdiskes";
cin>>num;
hanoi(num,'A','B','C');
}運(yùn)行結(jié)果:
Inputthenumberofdiskes3
(1,A--->C)
(2,A--->B)
(2,C--->B)
(3,A--->C)
(1,B--->A)
(2,B--->C)
(1,A--->C)內(nèi)聯(lián)擴(kuò)展(inlineexpansion)簡(jiǎn)稱為內(nèi)聯(lián)(inline)。內(nèi)聯(lián)函數(shù)也稱為內(nèi)嵌函數(shù)。內(nèi)聯(lián)函數(shù)通過(guò)在編譯時(shí)將函數(shù)體代碼插入到函數(shù)調(diào)用處,將調(diào)用函數(shù)的方式改為順序執(zhí)行方式來(lái)節(jié)省程序執(zhí)行的時(shí)間開(kāi)銷,這一過(guò)程叫做內(nèi)聯(lián)函數(shù)的擴(kuò)展。
若把一個(gè)函數(shù)定義為內(nèi)聯(lián)函數(shù),則在程序編譯階段,編譯器就會(huì)把每次調(diào)用該函數(shù)的地方都直接替換為該函數(shù)體中的代碼,因此省去了函數(shù)的調(diào)用及相應(yīng)的保護(hù)現(xiàn)場(chǎng)、參數(shù)傳遞和返回等操作,從而加快了整個(gè)程序的執(zhí)行速度。3.3內(nèi)聯(lián)函數(shù)(InlineFunctions)【例3-12】
將字符數(shù)組str1中所有小寫字母('a'~'z')轉(zhuǎn)換成大寫字母。
程序如下:
#include<iostream>
usingnamespacestd;
#include<string.h>
intup_letter(charch);
voidmain()
{charstr[80];inti;
cout<<"pleaseinputastring:";
cin>>str;
for(i=0;i<strlen(str);i++)
{
if(up_letter(str[i]))
str[i]-=32;
}
cout<<"theresultis:"<<str<<endl;
}
intup_letter(charch){
if(ch>='a'&&ch<='z')
return1;
else
return0;
}
運(yùn)行結(jié)果:
Pleaseinputastring:goodMORNING3456
Theresultis:GOODMORNING3456這種調(diào)用過(guò)程需要保護(hù)現(xiàn)場(chǎng)和恢復(fù)現(xiàn)場(chǎng),因此函數(shù)的調(diào)用需要一定的時(shí)間和空間開(kāi)銷。特別是對(duì)于像up_letter()這樣函數(shù)體代碼不大但調(diào)用頻繁的函數(shù)來(lái)說(shuō),對(duì)程序效率的影響很大。這如何來(lái)解決呢?當(dāng)然,為了不增加函數(shù)調(diào)用給程序帶來(lái)的負(fù)擔(dān),可以把這些小函數(shù)的功能直接寫入到主調(diào)函數(shù)。例如,例3-12可以寫成下面的形式:#include<iostream>
usingnamespacestd;
#include<string.h>
voidmain()
{
charstr[80];
inti;
cout<<"pleaseinputastring:";
cin>>str;for(i=0;i<strlen(str);i++)
{
if(str[i]>='a'&&str[i]<='z')
str[i]-=32;
}
cout<<"theresultis:"<<str<<endl;
}函數(shù)up_letter()的功能由關(guān)系表達(dá)式str[i]>='a'&&str[i]<='z'代替。但這樣做的結(jié)果是使程序的可讀性降低了。
內(nèi)聯(lián)函數(shù)的定義形式如下:
inline函數(shù)類型函數(shù)名(形式參數(shù)表)
{
函數(shù)體;
}內(nèi)聯(lián)函數(shù)能避免函數(shù)調(diào)用從而降低程序的效率,這是因?yàn)椋涸诔绦蚓幾g時(shí),編譯器將程序中被調(diào)用的內(nèi)聯(lián)函數(shù)都用內(nèi)聯(lián)函數(shù)定義的函數(shù)體進(jìn)行替換。這樣做只是增加了函數(shù)的代碼,而減少了程序執(zhí)行時(shí)函數(shù)間的調(diào)用。所以,上面的問(wèn)題可以用內(nèi)聯(lián)函數(shù)來(lái)解決,具體程序如下:
#include<iostream>
usingnamespacestd;
#include<string.h>
inlineintup_letter(charch);
voidmain(){
charstr[80];inti;
cout<<"pleaseinputastring:";
cin>>str;
for(i=0;i<strlen(str);i++)
{
if(up_letter(str[i]))str[i]-=32;
}
cout<<"theresultis:"<<str<<endl;
}
inlineintup_letter(charch)
{
if(ch>='a'&&ch<='z')return1;
else return0;
}下面內(nèi)聯(lián)函數(shù)的聲明就是錯(cuò)誤的:
#include<iostream>
usingnamespacestd;
intup_letter(charch); //此處沒(méi)有聲明up_letter是內(nèi)聯(lián)函數(shù)
voidmain()
{charstr[80]; inti;
cout<<"pleaseinputastring:"; cin>>str;
for(i=0;i<strlen(str);i++) ?{
?if(up_letter(str[i])) //將按一般函數(shù)調(diào)用
str[i]-=32;
?}
?cout<<"theresultis:"<<str<<endl;
}【例3-13】
內(nèi)聯(lián)函數(shù)的應(yīng)用。
程序如下:
#include<iostream>
usingnamespacestd;
inlineintabs(intx)
{
returnx<0?-x:x;
}
voidmain(){
inta,b=3,c,d=-4;
a=abs(b);
c=abs(d);
cout<<"a="<<a<<",c="<<c<<endl;
}
運(yùn)行結(jié)果:
a=3,c=4使用內(nèi)聯(lián)函數(shù)應(yīng)注意以下三點(diǎn):
(1)在內(nèi)聯(lián)函數(shù)內(nèi)部不允許使用循環(huán)語(yǔ)句和分支語(yǔ)句,否則系統(tǒng)會(huì)將其視為普通函數(shù)。
(2)內(nèi)聯(lián)函數(shù)不能是遞歸函數(shù)。
(3)語(yǔ)句數(shù)盡可能少,一般不超過(guò)5行。
與處理register變量相似,是否對(duì)一個(gè)內(nèi)聯(lián)函數(shù)進(jìn)行擴(kuò)展完全由編譯器自行決定。因此,說(shuō)明一個(gè)內(nèi)聯(lián)函數(shù)只是請(qǐng)求,而不是命令編譯器對(duì)它進(jìn)行擴(kuò)展。3.4.1函數(shù)重載的定義
(DefinitionofFunctionOverloading)
重載是指同一個(gè)函數(shù)名對(duì)應(yīng)多個(gè)函數(shù)的現(xiàn)象。例如,求兩個(gè)整數(shù)之和的函數(shù)與求兩個(gè)實(shí)數(shù)之和的函數(shù)可以聲明如下形式:
intsum(int,int);
intsum(int);
doublesum(int,long);
doublesum(long);3.4函數(shù)重載(FunctionOverloading)3.4.2函數(shù)重載的綁定
(BindingofFunctionOverloading)
函數(shù)重載要求編譯器能夠唯一地確定調(diào)用一個(gè)函數(shù)時(shí)應(yīng)執(zhí)行哪個(gè)函數(shù)代碼。
例如,重載函數(shù)add()的綁定:
cout<<add(1,2)<<endl; //匹配intadd(int,int);
cout<<add(1.2,3.4)<<endl; //匹配doubleadd(double,double);
cout<<add('a','b')<<endl; //匹配intadd(int,int);【例3-14】
求三個(gè)操作數(shù)之和。
程序如下:
#include<iostream>
usingnamespacestd;
intsum(int,int,int);
doublesum(double,double,double);
voidmain()
{
cout<<"Int:"<<sum(2,3,4)<<endl;
cout<<"Double:"<<sum(1.4,2.7,3.8)<<endl;
}
intsum(inta,intb,intc)
{
returna+b+c;
}
doublesum(doublea,doubleb,doublec)
{
returna+b+c;
}
執(zhí)行結(jié)果:
Int:9
Double:7.9
C++語(yǔ)言允許在函數(shù)說(shuō)明或函數(shù)定義中為形參預(yù)賦一個(gè)默認(rèn)的值,這樣的函數(shù)叫做帶有默認(rèn)形參值的函數(shù)。在C++語(yǔ)言中調(diào)用函數(shù)時(shí),通常要為函數(shù)的每個(gè)形參給定對(duì)應(yīng)的實(shí)參。若沒(méi)有給出實(shí)參,則按指定的默認(rèn)值進(jìn)行工作。只有當(dāng)函數(shù)沒(méi)有聲明時(shí),才可以在函數(shù)定義中指定形參的默認(rèn)值,這就大大方便了函數(shù)的使用。3.5帶默認(rèn)形參值的函數(shù)(FunctionwithDefaultArguments)例如:
intfun(intx=15,inty=8)
{
returnx-y;
}
voidmain(void)
{
fun(34,22); //傳遞給形參x、y的值分別為34和22
fun(10); //傳遞給形參x、y的值分別為10和8
fun(); //傳遞給形參x、y的值分別為15和8
}
(1)若函數(shù)具有多個(gè)形參,則缺省形參值必須自右向左連續(xù)定義,并且在一個(gè)缺省形參值的右邊不能有未指定缺省值的參數(shù)。這是由C++語(yǔ)言在函數(shù)調(diào)用時(shí)參數(shù)是自右至左入棧這一約定所決定的。例如:
voidadd_int(inta=1,intb=5,intc=10);//正確的函數(shù)聲明
voidadd_int(inta,intb=5,intc=10);//正確的函數(shù)聲明
voidadd_int(inta=1,intb,intc=10);//錯(cuò)誤的函數(shù)聲明
voidadd_int(inta=1,intb,intc)//錯(cuò)誤的函數(shù)聲明
(2)在調(diào)用一個(gè)函數(shù)時(shí),如果省去了某個(gè)實(shí)參,則直到最右端的實(shí)參都要省去(當(dāng)然,與它們對(duì)應(yīng)的形參都要有缺省值)。
假如有如下聲明:
intfun(inta,floatb=5.0,charc='.',intd=10);
采用如下調(diào)用形式是錯(cuò)誤的:
fun(8,,,4);//語(yǔ)法錯(cuò)誤
(3)缺省形參值的說(shuō)明必須出現(xiàn)在函數(shù)調(diào)用之前。例如:
intsub(intx=8,inty=3); //缺省形參值在函數(shù)原型中給出
voidmain(void)
{
sub(20,15); //20-15
sub(10); //10-3
sub(); //8-3}
intsub(intx,inty) //缺省形參值沒(méi)有在函數(shù)定義時(shí)給出
{
returnx-y;
}
(4)在同一個(gè)作用域,一旦定義了缺省形參值,就不能再定義它。例如:
intfun(inta,floatb,char,intd=10);
intfun(inta,floatb,charc=‘.’,intd=10);//錯(cuò)誤:企圖再次定義缺省參數(shù)c和d
(5)如果幾個(gè)函數(shù)說(shuō)明出現(xiàn)在不同的作用域內(nèi),則允許分別為它們提供不同的缺省形參值。例如:
intfun(inta=6,floatb=5.0,charc='.',intd=10);
voidmain(void)
{
intfun(inta=3,floatb=2.0,charc='n',intd=20);
cout<<fun()<<endl;//fun函數(shù)使用局部缺省參數(shù)值
}
(6)對(duì)形參缺省值的指定可以是初始化表達(dá)式,甚至可以包含函數(shù)調(diào)用。例如:
//d參數(shù)的缺省值是函數(shù)調(diào)用
intfun(inta,floatb=5.0,charc=‘.’,intd=sub(20,15));
(7)在函數(shù)原型中給出了形參的缺省值時(shí),形參名可以省略。例如:
intfun(int,float=5.0,char=‘.’,int=sub(20,15));
(8)形參的默認(rèn)值可以是全局常量、全局變量、表達(dá)式、函數(shù)調(diào)用,但不能為局部變量。例如:
//下例不合法:
voidfun()
{
intk;
voidg(intx=k); //k為局部變量
}3.6.1標(biāo)識(shí)符的作用域(IdentifiersScopes)
作用域指標(biāo)識(shí)符定義(聲明)之后程序中有效的區(qū)域,即標(biāo)識(shí)符在該區(qū)域可見(jiàn)。
1.局部作用域(塊作用域)
當(dāng)標(biāo)識(shí)符的聲明出現(xiàn)在由一對(duì)花括號(hào)所括起來(lái)的一段程序(塊)內(nèi)時(shí),該標(biāo)識(shí)符的作用域從聲明點(diǎn)開(kāi)始,到塊結(jié)束處為止,該作用域的范圍具有局部性,該作用域就稱為局部作用域,又稱為塊作用域。3.6作用域與生存期(ScopesandLifetime)【例3-15】
塊作用域示例。
程序如下:
#include<iostream>
usingnamespacestd;
intmain(){ //1
inti,j; //2
i=1;j=2; //3
{
inta,b; //4
a=5; //5
b=j; //6
cout<<a<<"\t"<<b<<endl; //7
} //8
cout<<i<<"\t"<<j<<endl; //9
return0; //10
} //11【例3-16】
塊作用域示例。
程序如下:
#include<iostream>
usingnamespacestd;
intmain()
//1
{ //2
intx(3),y(5); //3
for(;x>0;x--) //4
{ //5
intx(4);
//6
cout<<x<<"\t"<<y<<endl; //7
}
//8
cout<<endl<<x<<"\t"<<y<<endl; //9
return0
;
//10
}
//11
運(yùn)行結(jié)果:
4
5
4
5
4
5
0
5
2.函數(shù)作用域
函數(shù)作用域是指在函數(shù)內(nèi)定義的標(biāo)識(shí)符的作用范圍,函數(shù)作用域從其定義開(kāi)始,到函數(shù)結(jié)束為止。
3.函數(shù)原型作用域
函數(shù)原型作用域是指在函數(shù)原型中所指定的參數(shù)標(biāo)識(shí)符的作用范圍。例如,函數(shù)原型:
doubleArea(doubleradius);
參數(shù)radius的作用域開(kāi)始于函數(shù)原型聲明的左括號(hào),結(jié)束于函數(shù)聲明的右括號(hào)。它不能用于程序正文其他地方,可以寫成:
doubleArea(double);
或
doubleArea(doubleradius=5);
也可簡(jiǎn)化成:
doubleArea(double=5);
4.文件作用域
在函數(shù)外定義的變量、static變量或用extern聲明的變量具有文件作用域,其作用域從聲明之處開(kāi)始,直到源文件結(jié)束。當(dāng)具有文件作用域的變量出現(xiàn)先使用、后定義的情況時(shí),要先用extern對(duì)其作外部聲明。
【例3-17】
文件作用域示例。程序如下:
#include<iostream>
usingnamespacestd;
inti;
//全局變量,文件作用域
intmain()
{
i=5;
{
inti;
//局部變量,塊作用域
i=7;
cout<<"i="<<i<<endl;
//輸出7
}
cout<<"i="<<i<<endl;
//輸出5
return0;
}
表3-1給出了四種作用域的作用范圍。表3-1四種作用域的作用范圍
【例3-18】
下面程序的每行前加有行號(hào),共20行。說(shuō)明程序中變量len、k、chk以及函數(shù)print_func()的作用域范圍的起止行號(hào)。
1.#include<iostream>
2.usingnamespacestd;
3.intlen;
4.voidprint_func();
5.voidmain()
6.{7.staticcharname[]="Zhang";
8.intk=0;
9.while(name[k]){
10.charchk;
11.chk=name[k];
12.cout<<chk;
13.k++;14.}
15.len=k;
16.print_func();
17.}
18.voidprint_func()
19.{
20.cout<<"Thestringlengh="<<len<<endl;
21.}3.6.2局部變量與全局變量
(LocalVariablesandGlobalVariables)
在討論函數(shù)的形參變量時(shí)曾經(jīng)提到,
形參變量只在被調(diào)用期間才分配內(nèi)存單元,調(diào)用結(jié)束立即釋放。
1.局部變量
在一個(gè)函數(shù)內(nèi)部說(shuō)明的變量是內(nèi)部變量,局部變量是在函數(shù)內(nèi)作定義說(shuō)明的,它只在該函數(shù)范圍內(nèi)有效。【例3-19】
使用局部變量示例。
程序如下:
#include<iostream>
usingnamespacestd;
int
f1(int
a)
/*函數(shù)f1*/
{
int
b,c;
…} //a、b、c的作用域
int
f2(int
x)
/*函數(shù)f2*/
{
int
y,z;
} //x、y、z的作用域
voidmain()
{
int
m,n;
}
(1)主函數(shù)中定義的變量也只能在主函數(shù)中使用,不能在其他函數(shù)中使用。
(2)形參變量是屬于被調(diào)函數(shù)的局部變量,實(shí)參變量是屬于主調(diào)函數(shù)的局部變量。
(3)允許在不同的函數(shù)中使用相同的變量名,它們代表不同的對(duì)象,分配不同的單元,互不干擾,也不會(huì)發(fā)生混淆。
(4)在復(fù)合語(yǔ)句中也可定義變量,其作用域只在復(fù)合語(yǔ)句范圍內(nèi)。例如:
voidmain()
{
int
s,a;
…
{
int
b;
s=a+b;
…
//b的作用域
}
…
//s、a的作用域
}【例3-20】
分析變量k的作用域。
程序如下:
#include<iostream>
usingnamespacestd;
voidmain()
{
int
i=2,j=3,k;
k=i+j;
{
int
k=8;
if(i==3)
cout<<k<<endl;
}
cout<<i<<endl<<k<<endl;
}
2.全局變量
全局變量也稱為外部變量,它是在函數(shù)外部定義的變量。
例如:
int
a,b;
/*外部變量*/
void
f1()
/*函數(shù)f1*/
{
…
}
float
x,y;
/*外部變量*/
int
fz()
/*函數(shù)fz*/
{
…
}
voidmain()
/*主函數(shù)*/
{
…
}
/*全局變量x、y的作用域,全局變量a、b的作用域*/
【例3-21】
輸入正方體的長(zhǎng)l、寬w、高h(yuǎn)。求體積及三個(gè)面x*y、x*z、y*z的面積。
程序如下:
#include<iostream.h>
usingnamespacestd;
int
s1,s2,s3;
int
vs(int
a,int
b,int
c)
{
int
v;
v=a*b*c;
s1=a*b;
s2=b*c;
s3=a*c;
return
v;
}
voidmain(){
int
v,l,w,h;
cout<<“input
length,width
and
height”<<endl;
cin>>l>>w>>h;
v=vs(l,w,h);
cout<<v<<s1<<s2<<s3;
}本程序中定義了三個(gè)外部變量s1、s2、s3,
用來(lái)存放三個(gè)面積,其作用域?yàn)檎麄€(gè)程序。函數(shù)vs用來(lái)求正方體體積和三個(gè)面積,
函數(shù)的返回值為體積v。對(duì)于全局變量,還有以下幾點(diǎn)說(shuō)明:
(1)對(duì)于局部變量的定義和說(shuō)明可以不加區(qū)分,而對(duì)于外部變量則不然,外部變量的定義和外部變量的說(shuō)明并不是一回事。
其一般形式如下:
[extern]
類型說(shuō)明符
變量名,變量名,…其中,方括號(hào)內(nèi)的extern可以省去不寫。
例如:
int
a,b;
等效于:
extern
int
a,b;
外部變量說(shuō)明出現(xiàn)在要使用該外部變量的各個(gè)函數(shù)內(nèi),
在整個(gè)程序內(nèi),可能出現(xiàn)多次。外部變量說(shuō)明的一般形式如下:
extern
類型說(shuō)明符
變量名,變量名,…;
(2)全局變量增加了函數(shù)之間數(shù)據(jù)聯(lián)系的渠道,但是使用全局變量降低了程序的可理解性,軟件工程學(xué)提倡盡量避免使用全局變量。
(3)全局變量存放在內(nèi)存的全局?jǐn)?shù)據(jù)區(qū)。在定義全局變量時(shí),若未對(duì)變量進(jìn)行初始化,則自動(dòng)初始化為0。
(4)在同一源文件中,允許全局變量和局部變量同名。在局部變量的作用域內(nèi),全局變量不起作用。【例3-22】
全局變量與局部變量使用示例。
程序如下:
#include<iostream>
usingnamespacestd;
int
vs(int
l,int
w)
{
extern
int
h;
int
v; //定義局部變量v
v=l*w*h; //引用全局變量w、h和局部變量v、l
return
v;
}
voidmain()
{
extern
int
w,h;
int
l=5;
//定義局部變量l
cout<<vs(l,w);
}
int
l=3,w=4,h=5;
//定義全局變量l、w、h3.6.3動(dòng)態(tài)變量與靜態(tài)變量
(DynamicVariablesandStaticVariables)
1.變量在內(nèi)存中的存儲(chǔ)
一個(gè)程序?qū)⒉僮飨到y(tǒng)分配給其運(yùn)行的內(nèi)存塊分為4個(gè)區(qū)域。
(1)代碼區(qū)(Codearea)。
(2)全局?jǐn)?shù)據(jù)區(qū)(Dataarea)。
(3)棧區(qū)(Stackarea)。
(4)堆區(qū)(Heaparea)。
2.動(dòng)態(tài)變量
動(dòng)態(tài)變量用來(lái)在程序執(zhí)行過(guò)程中,定義變量或調(diào)用函數(shù)時(shí)分配存儲(chǔ)空間。
3.靜態(tài)變量
在程序開(kāi)始執(zhí)行時(shí)就分配存儲(chǔ)空間,在程序運(yùn)行期間,即使變量處于其作用域之外,也一直占用為其分配的存儲(chǔ)空間,直到程序執(zhí)行結(jié)束時(shí),才收回為變量分配的存儲(chǔ)空間,這種變量稱為靜態(tài)變量。3.6.4變量的存儲(chǔ)類型(VariablesStorageTypes)
各種變量的作用域不同,
就其本質(zhì)來(lái)說(shuō)是因?yàn)樽兞康拇鎯?chǔ)類型不同。所謂存儲(chǔ)類型,是指變量占用內(nèi)存空間的方式,
也稱為存儲(chǔ)方式。
變量的存儲(chǔ)方式可分為靜態(tài)存儲(chǔ)和動(dòng)態(tài)存儲(chǔ)兩種。
在C++?語(yǔ)言中,對(duì)變量的存儲(chǔ)類型說(shuō)明有以下四種:
(1)?auto:自動(dòng)變量。
(2)?register:寄存器變量。
(3)?extern:外部變量。
(4)?static:靜態(tài)變量。存儲(chǔ)類型說(shuō)明符
數(shù)據(jù)類型說(shuō)明符
變量名,變量名,…;
例如:
static
int
a,b;
//說(shuō)明a、b為靜態(tài)類型變量
auto
char
c1,c2;
//說(shuō)明c1、c2為自動(dòng)字符變量
static
int
a[5]={1,2,3,4,5};
//說(shuō)明a為靜態(tài)整型數(shù)組
extern
int
x,y;
//說(shuō)明x、y為外部整型變量
1.自動(dòng)類型(auto)
自動(dòng)類型是C++?語(yǔ)言程序中使用最廣泛的一種類型。
例如:
{
int
i,j,k;
char
c;
…
}等價(jià)于:
{
auto
int
i,j,k;
auto
char
c;
…
}自動(dòng)變量具有以下特點(diǎn):
(1)自動(dòng)變量的作用域僅限于定義該變量的個(gè)體內(nèi)。
例如:
int
kv(int
a)
{
auto
int
x,y;
{
auto
char
c;
}
/*c的作用域*/
…
}
/*a、x、y的作用域*/
(2)自動(dòng)變量屬于動(dòng)態(tài)存儲(chǔ)方式,只有在使用它(即定義該變量的函數(shù)被調(diào)用)時(shí)才給它分配存儲(chǔ)單元,開(kāi)始它的生存期。
例如:
voidmain()
{
auto
int
a,s,p;
cout<<“input
a
number:”<<endl;
cin>>n;
if(a>0)
{
s=a+a;
p=a*a;
}
cout<<s<<p;
}
如果改成:
voidmain()
{
auto
int
a;
cout<<“input
a
number:”<<endl;
cin>>a;
if(a>0)
{
auto
int
s,p;
s=a+a;
p=a*a;
}
cout<<s<<p;
}
(3)由于自動(dòng)變量的作用域和生存期都局限于定義它的個(gè)體內(nèi)(函數(shù)或復(fù)合語(yǔ)句內(nèi)),因此不同的個(gè)體中允許使用同名的變量,而不會(huì)混淆。
即使在函數(shù)內(nèi)定義的自動(dòng)變量,也可與該函數(shù)內(nèi)部的復(fù)合語(yǔ)句中定義的自動(dòng)變量同名。【例3-23】
自動(dòng)變量使用示例。
程序如下:
#include<iostream>
usingnamespacestd;
voidmain()
{
auto
int
a,s=100,p=100;
cout<<“input
a
number:”<<endl;
cin>>a;
if(a>0)
{
auto
int
s,p;
s=a+a;
p=a*a;
cout<<s<<p;
}
cout<<s<<p;
}
(4)對(duì)構(gòu)造類型的自動(dòng)變量(如數(shù)組等),不可作初始化賦值。
2.寄存器類型(register)
變量一般都存放在存儲(chǔ)器內(nèi),因此當(dāng)對(duì)一個(gè)變量頻繁讀/寫時(shí),必然反復(fù)訪問(wèn)內(nèi)存儲(chǔ)器,從而花費(fèi)大量的存取時(shí)間。
register的使用形式如下:
[register]<數(shù)據(jù)類型><變量名表>
例如:
registerintm,n=3;【例3-24】
寄存器變量使用示例,求。
程序如下:
#include<iostream>
usingnamespacestd;
voidmain()
{
register
i,s=0;
for(i=1;i<=200;i++)
s=s+i;
cout<<s;
}
3.外部類型(extern)
用關(guān)鍵字extern聲明的變量稱為外部變量。外部變量是全局變量,具有文件作用域。用extern聲明外部變量的目的有兩個(gè):一是擴(kuò)展當(dāng)前文件中全局變量的作用域;二是將其他文件中全局變量的作用域擴(kuò)展到當(dāng)前文件中?!纠?-25】求兩個(gè)整數(shù)的最大值。
程序如下:
#include<iostream>
usingnamespacestd;
externinta,b; //第3行聲明a、b為外部變量
intmain()
{
intc;
intmax(intx,inty);
c=max(a,b); //第7行使用全局變量a、b
cout<<"max="<<c<<endl;
return0;
}inta=3,b=5;
//第11行定義全局變量a、b
intmax(intx,inty)
{
intz;
z=x>y?x:y;
returnz;
}
4.靜態(tài)類型(static)
靜態(tài)變量的類型說(shuō)明符是static。
靜態(tài)變量屬于靜態(tài)存儲(chǔ)方式,但是屬于靜態(tài)存儲(chǔ)方式的量不一定就是靜態(tài)變量。
靜態(tài)變量根據(jù)定義在函數(shù)內(nèi)還是函數(shù)外,分為靜態(tài)局部變量與靜態(tài)全局變量。【例3-26】
靜態(tài)局部變量使用示例。
程序如下:
#include<iostream>
usingnamespacestd;
voidmain()
{
int
i;
void
f();
/*函數(shù)說(shuō)明*/
for(i=1;i<=5;i++)
f();
/*函數(shù)調(diào)用*/
}void
f()
/*函數(shù)定義*/
{
auto
int
j=0;
++j;
cout<<j;
}上述程序中定義了函數(shù)f,其中的變量j
說(shuō)明為自動(dòng)變量并賦予初始值為0。當(dāng)main中多次調(diào)用f時(shí),j均賦初值為0,故每次輸出值均為1?,F(xiàn)在把j改為靜態(tài)局部變量,程序如下:
#include<iostream>
usingnamespacestd;
voidmain()
{
int
i;
void
f();
for
(i=1;i<=5;i++)
f();
}
void
f()
{
static
int
j=0;
++j;
cout<<j<<endl;
}
2)靜態(tài)全局變量
全局變量(外部變量)的說(shuō)明之前再冠以static
就構(gòu)成了靜態(tài)全局變量。
【例3-27】
靜態(tài)全局變量使用示例。
#include<iostream>
usingnamespacestd;
voidfn();
staticintn;//定義靜態(tài)全局變量
intmain(){
n=20;
cout<<n<<endl;
fn();
return0;
}
voidfn()
{
n++;
cout<<n<<endl;
}3.6.5生存期(Lifetime)
作用域針對(duì)標(biāo)識(shí)符而言,生存期則針對(duì)變量而言。
1.靜態(tài)生存期
這種生命期與程序的運(yùn)行期相同,只要程序一開(kāi)始運(yùn)行,這種生命期的變量就存在,當(dāng)程序結(jié)束時(shí),其生命期就結(jié)束。
2.局部生存期
在函數(shù)內(nèi)部聲明的變量或者塊中聲明的變量具有局部生命期。
3.動(dòng)態(tài)生存期
用new聲明獲得動(dòng)態(tài)存儲(chǔ)空間,在堆中分配某一類型變量所占的存儲(chǔ)空間,并將首地址賦給指針。3.6.6名字空間(NameSpace)
缺省情況下,在全局域(被稱做全局名字空間域)中聲明的每個(gè)對(duì)象、函數(shù)、類型或模板都引入了一個(gè)全局實(shí)體。
程序員可以通過(guò)使全局實(shí)體的名字很長(zhǎng)或在程序中的名字前面加個(gè)特殊的字符序列前綴,從而避免這些問(wèn)題。例如:
classcplusplus_primer_matrix{...};
voidinverse(cplusplus_primer_matrix&);例如:
namespacecplusplus_primer
{
classmatrix
{
/*...*/
};
voidinverse(matrix&);
}名字空間是一個(gè)命名范圍區(qū)域,其中所有的由程序員創(chuàng)建的標(biāo)識(shí)符可以確保是唯一的(假設(shè)程序員在名字空間中沒(méi)有聲明兩個(gè)重名的標(biāo)識(shí)符,并假設(shè)以前已定義的同名的名字空間已不存在)。例如,可以定義一個(gè)簡(jiǎn)單的名字空間:
namespaceMyNames
{
intval1=10;
intval2=20;
}【例3-28】
使用std名字空間。
#include<iostream>
usingnamespacestd;
intmain()
{
std::cout<<"Comingtoyoufromcout.";
return0;
}
1.usingnamespace語(yǔ)句
使用已在名字空間定義的標(biāo)識(shí)符的另一種方法是將usingnamespace語(yǔ)句包含在涉及到名字空間的源代碼文件中。
【例3-29】usingnamespace語(yǔ)句。
#include<iostream>
usingnamespacestd;
intmain()
{
cout<<"Comingtoyoufromcout.";
return0;
}【例3-30】usingnamespace語(yǔ)句的問(wèn)題。
程序如下:
#include<iostream>
usingnamespacestd;
namespaceMyNames
{
intval1=10;
intval2=20;
}
namespaceMyOtherNames
{intval1=30;
intval2=50;
}
usingnamespacestd;
usingnamespaceMyNames;
usingnamespaceMyOtherNames;
intmain()
{
cout<<"Comingtoyoufromcout.";
val1=100;
return0;
}【例3-31】
程序改寫。
程序如下:
#include<iostream>
usingnamespacestd;
namespaceMyNames
{
intval1=10;
intval2=20;
}namespaceMyOtherNames
{
intval1=30;
intval2=50;
}
usingnamespaceMyNames;
usingnamespaceMyOtherNames;
intmain()
{
std::cout<<"Comingtoyoufromcout.";
MyNames::val1=100;
return0;
}
2.定義名字空間
一個(gè)名字空間可以包含如下多種類型的標(biāo)識(shí)符:
(1)變量名;
(2)常量名;
(3)函數(shù)名;
(4)結(jié)構(gòu)名;
(5)類名;
(6)名字空間名。【例3-32】
名字空間定義。
程序如下:
#include<iostream>
usingnamespacestd;
namespaceMyNames
{
constintOFFSET=15;
intval1=10;
intval2=20;
charch='A';
intReturnSum()
{inttotal=val1+val2+OFFSET;
returntotal;
}
charReturnCharSum()
{
charresul
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)校家庭共育策略
- 創(chuàng)新創(chuàng)業(yè)模范企業(yè)家
- 一年級(jí)數(shù)學(xué)計(jì)算題專項(xiàng)練習(xí)集錦
- 創(chuàng)意禮品創(chuàng)業(yè)計(jì)劃書
- 2025年問(wèn)男生心理測(cè)試題及答案
- 2025年刺繡機(jī)電控項(xiàng)目發(fā)展計(jì)劃
- 幼兒園獲獎(jiǎng)公開(kāi)課:大班科學(xué)《動(dòng)物防身絕技大比拼》課件
- (高清版)DB11∕T2298-2024地震安全韌性建設(shè)指南 中小學(xué)校
- 2025年大規(guī)格石英玻璃擴(kuò)散管合作協(xié)議書
- 高粘度流體壓電超聲霧化系統(tǒng)的設(shè)計(jì)與研究
- 機(jī)電一體化專業(yè)課程改革調(diào)研報(bào)告及改革建議
- 2025年甘肅甘南州國(guó)控資產(chǎn)投資管理集團(tuán)有限公司招聘筆試參考題庫(kù)附帶答案詳解
- 《市場(chǎng)營(yíng)銷STP戰(zhàn)略》課件
- 《S中學(xué)宿舍樓工程量清單計(jì)價(jià)編制(附三維圖)》30000字
- 全國(guó)運(yùn)動(dòng)員注冊(cè)協(xié)議書范本(2篇)
- 《高點(diǎn)全景視頻監(jiān)控聯(lián)網(wǎng)技術(shù)要求》
- 白云山生態(tài)停車場(chǎng)工程施工組織設(shè)計(jì)施工方案
- 2024年四川省綿陽(yáng)市中考語(yǔ)文試卷(附真題答案)
- 【MOOC】Office高級(jí)應(yīng)用-成都信息工程大學(xué) 中國(guó)大學(xué)慕課MOOC答案
- 足球英語(yǔ)課件
- 盆底康復(fù)課件
評(píng)論
0/150
提交評(píng)論