




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領
文檔簡介
1C++語言的概要類、對象、構(gòu)造函數(shù)與析構(gòu)函數(shù)輸入/輸出函數(shù)、參數(shù)傳遞與函數(shù)返回值函數(shù)名重載與操作符重載動態(tài)存儲分配友元函數(shù)與內(nèi)聯(lián)函數(shù)結(jié)構(gòu)、聯(lián)合與類C++編程簡介2C++語言概要C++源于C語言。1970年,兩位程序員BrianKernighan和DennisRitchie首創(chuàng)了一種新的程序設計語言,取名為C語言。設計C語言的最初目的是編寫操作系統(tǒng)。由于其簡單、靈活的特點,C語言很快就被用于編寫各種不同類型的程序,從而成為世界上最流行的語言之一。3C語言是一個面向過程的語言。隨著軟件開發(fā)技術(shù)的進步,程序員們最終發(fā)現(xiàn),
把數(shù)據(jù)和施加在其上的操作結(jié)合起來,會得到更易于理解的程序,由此產(chǎn)生了面向?qū)ο蟮某绦蛟O計思想。1980年代初,美國AT&T貝爾實驗室的BjarneStroustrup設計并實現(xiàn)了C語言的擴充、改進版本,C++語言誕生了!C++改進了C的不足之處,增加了對面向?qū)ο蟮某绦蛟O計的支持,在改進的同時,保持了C的簡潔性和高效性。4//一個簡單的C++程序/*一個簡單的C++程序,該程序在標準輸出設備上輸出一句問候語“hello”*/#include<iostream.h>intmain(){ cout<<"hello!"; return0; //正常返回}這是一個只包含一個函數(shù)的程序,程序的基本元素是數(shù)據(jù)說明、函數(shù)和注釋。5注釋C++的第一次注釋格式源于C語言。注釋開始于“/*”,結(jié)束于“*/”,在兩者之間的任何內(nèi)容,包括換行符都被編譯器忽略。注意注釋符對不可以嵌套。第一種注釋符以“//”開頭,它是單行注釋符,在它同一行右側(cè)的任何信息都將被認為是注釋而由編譯器略去。注意:上面兩種注釋符的兩個標志符/和*,/和/之間不可以分開。6#include
語句C++將一些標準函數(shù)和變量說明放在頭文件中。頭文件中保存所有與標準函數(shù)或變量相關的信息,為了使用頭文件中定義的變量和函數(shù),必須將相應的頭文件include進主程序,作為程序的一部分進行編譯。用戶也可以定義自己的頭文件,把一些相關的函數(shù)和變量組織在一個文件中,當另外的程序要用到這些函數(shù)和變量時,可以將該文件作為頭文件include進來。7#include指令有兩種格式:
#include<頭文件名>#include“頭文件名”第一種文件名在
<>
中指定,表示該文件存放于系統(tǒng)設定的子目錄中,這類文件一般是由系統(tǒng)給出的,并已經(jīng)過編譯。第二種文件名在
“”
中給出,表示該文件存放在當前目錄中,這些頭文件通常由用戶自己給出。頭文件中可包含其它頭文件,即
#include可以直接嵌套。8C++源程序中還可包括各種編譯命令,這些命令被稱為預處理指令,常用的除
#include外,還有條件預處理指令
#if、#ifndef和#endif
等和宏替換指令
#define。預處理命令對編譯器起作用,它指示編譯器在正式編譯前做一些預先處理。#include
命令將指示編譯器將其后所跟的文件內(nèi)容插入到當前文件中;#define
定義一個常量或替換宏,它指示編譯器在使用該常量或宏的地方替換為其實際內(nèi)容;#if、#ifndef和
#endif
指示編譯器做條件編譯。9#define
用來定義一個常量或替換宏,如:
#definesize20
//定義一個常量size,其值永遠為20
#defineMAX(x,y)((x<y)?y:x)
//求x,y中的最大值經(jīng)過預編譯后,程序中所有出現(xiàn)
size
和MAX(x,y)
之處都會被
20
和
((x<y)?y:x)
代替,如:
intarray[size]; inti=MAX(4,55);經(jīng)預編譯后會變?yōu)?/p>
intarray[20]; inti=((4<55)?55:4);10函數(shù)原型下面的程序給出了典型的
C
程序結(jié)構(gòu),它是“Hello,world”程序的變型。這個程序由三個文件組成:
/*File:hello.h*/char*hello();
/*File:hello.c*/
#include<stdio.h>
/*包括sprintf()的原型*/
#include<stdlib.h>
/*包括malloc()的原型*/
#include<string.h>
/*包括strlen()的原型*/#include"hello.h"
/*包括hello()的原型*/11char*hello(name)char*name;{
char*value;
/*返回串
"Hello,name.".*/
value=(char*)(malloc(9+strlen(name));sprintf(value,"Hello,%s.",name);
returnvalue;}/*File:main.c*/#include<stdio.h>
/*包括printf()的原型*/#include"hello.h"
/*包括hello()的原型*/12main(argc,argv)
intargc;
char*argv[
];
{
printf("%s",hello("world"));
}頭文件名字的后綴用“.h”表示,程序文件名字的后綴用“.c”表示。hello.h:包含
hello函數(shù)的原型。main函數(shù)可通過“#include”定向到該原型的定義文件,取得對原型的訪問性。13hello.c:這是hello函數(shù)的定義文件。它通過一個string類型的形式參數(shù)接受需要打印的串,返回一個string類型的值作為打印串。返回類型必須與在#include定向的“.h”文件中所給出的原型的類型匹配。main.c:這是打印“Hello,world”的主程序,它構(gòu)造和返回一個歡迎詞字符串,其結(jié)果通過函數(shù)printf打印出來。C把函數(shù)和數(shù)據(jù)定義放在后綴為“.c”的代碼文件中。在各代碼文件中使用后綴為“.h”的include文件,定義對其它各模塊的調(diào)用接口。14C++的函數(shù)特征特征是函數(shù)參數(shù)表的描述。利用特征信息可進行嚴格的類型檢查。它允許編譯器檢驗實際參數(shù)的數(shù)目是否正確,對應的形參和實參是否相容,函數(shù)返回的類型與函數(shù)調(diào)用的環(huán)境是否相容。它克服了在許多C程序的開發(fā)中,由于在C原型中沒有定義參數(shù)的類型和數(shù)量,而造成的實參和形參之間不匹配,函數(shù)返回類型與使用之間不匹配等許多缺陷。15現(xiàn)用C++語句改寫前面的C程序。C++程序在“.h”文件中對
hello()
使用了函數(shù)特征。對于
hello()
的原型:
不要求形式參數(shù)的名字出現(xiàn)在特征中參數(shù)的數(shù)目和類型,以及返回類型,都完整地在函數(shù)說明中定義C++允許在函數(shù)說明時,在括號內(nèi)直接聲明形式參數(shù)的類型。16/*File:hello.h*/
char*hello(char*);
/*File:hello.cpp*/#include<stdio.h>//包含函數(shù)sprintf()的原型
#include<string.h>//包含函數(shù)strlen()的原型
#include“hello.h”//包含函數(shù)hello()的原型char*hello(char*name){
char*value=newchar[9+strlen(name)];
sprintf(value,"Hello,%s.",name);
returnvalue;
}17/*File:main.cpp*/
#include<iostream.h>//說明輸出流對象cout
#include"hello.h"http://包含函數(shù)hello()的原型main(intargc,char*argv[]){
cout<<hello("world");
}
18C++的數(shù)據(jù)聲明C++的數(shù)據(jù)聲明將數(shù)據(jù)名與數(shù)據(jù)類型聯(lián)系起來。其主要形式有:常數(shù)值:如25,13.4,“valueis”,它們的內(nèi)容保持不變。常量:數(shù)據(jù)聲明時在變量名前冠以保留字const,如constintMAX=500,可定義一個常量。其內(nèi)容在聲明時給定,在聲明它的程序運行時內(nèi)容再賦值無效。變量:數(shù)據(jù)類型的實例,在程序執(zhí)行時可以改變其內(nèi)容。19C++提供兩大類數(shù)據(jù)類型:基本數(shù)據(jù)類型和復合數(shù)據(jù)類型?;緮?shù)據(jù)類型有5種:整型(int)、浮點型(float)、字符型(char)、雙精度浮點型(double)和無值(void)。復合數(shù)據(jù)類型包括結(jié)構(gòu)(struct)、聯(lián)合(union)、位域、枚舉(enum)、類(class)和用戶自定義類型。還有由基本數(shù)據(jù)類型和復合數(shù)據(jù)類型引申而來的數(shù)據(jù)類型,包括數(shù)組、指針、引用等。20枚舉:是聲明一個整型常數(shù)序列的方式。例如,在程序開頭做如下聲明
enumBoolean{FALSE,TRUE}
則建立一個Boolean類型。FALSE,TRUE
都是Boolean類型整型常數(shù),默認值
0
和1。指針:存放對象的存儲地址,例如
inti=5;int*np;//np為一個指向整型量的指針
np=&i;//把整型變量
i的地址賦給它
//np
成為指向整型變量i
的指針
intk=*np;//k中存入np所指地址i的內(nèi)容21引用:它用來給一個對象提供一個替代的名字。例如
inti=5;int&j=i;
i=7;printf(“i=%d,j=%d”,i,j);
此時,j
是一個引用類型,它代表
i
的一個替代名。當i的值改變時,j的值也跟著改變。當printf語句執(zhí)行后,打印出的i
和j
的值都是7。22C++的作用域在C++中,每個變量都有一個作用域。區(qū)分一個變量時要同時考慮變量名及其作用域。在函數(shù)定義中聲明的變量,僅能在該函數(shù)內(nèi)部有效使用在類定義中聲明的變量,僅能在該類內(nèi)部有效使用在一個段中聲明的名字,也僅能在該段及其子段中有效使用。23在整個程序各處都能訪問的變量叫做全局變量。如果一個全局變量在文件1中聲明,在文件2中使用,那么在文件2中必須使用保留字extern對該變量進行聲明。如果在構(gòu)成一個程序的兩個文件中分別聲明了兩個同名的全局變量,這兩個變量分別代表兩個不同實體,此時需在兩個文件中分別使用保留字static對變量進行聲明。如果一個段中的局部變量與一個全局變量同名,且還要在此段中使用該全局變量,此時需利用域操作符::訪問該全局變量。24表達式與操作符表達式是用來說明簡單計算的。C++中的表達式由操作數(shù)和操作符組成,它將操作符施加于操作數(shù),最終得到一個結(jié)果。結(jié)果的數(shù)據(jù)類型由參加運算的數(shù)據(jù)類型決定。
aa+b*c+2002**R
(x+y)/(a–b)其中操作符執(zhí)行的先后順序由它們的優(yōu)先級和結(jié)合性決定。25C++提供了很多預定義的操作符,程序員也可以重新定義這些操作符。算術(shù)操作符:+、-、*、/、%。其中*、/、%優(yōu)先于+、-。括號用來改變計算順序。計算時,先計算括號內(nèi)表達式的值,再將計算結(jié)果與括號外的數(shù)一起計算,如:
4*(1+2)=4*3=12取模操作符(%)用于計算兩整數(shù)相除后得到的余數(shù),如:22%7=1。注意,%只能用于整數(shù)相除,不能對浮點數(shù)操作。26賦值操作符“=”
將其右側(cè)的表達式求出結(jié)果,賦給其左側(cè)的變量。例如:
intvalue;
value
=(2+3)*4;賦值表達式運算的結(jié)果是右運算元的值,而結(jié)果類型是左運算元的數(shù)據(jù)類型,例如:
value
=2.8*4
//結(jié)果為11,而不是11.2可以連續(xù)賦值,但必須保證各運算元的類型相同。它的處理結(jié)果是每個運算元的對象值都為最右側(cè)的運算元值,例如:
inti,j;
i
=j
=0;
//i,j都賦為027復合操作符:加
a+=b等價于 a=a+b減
a
-=b
等價于 a=a
-
b乘
a*=b
等價于 a=a*b除
a/=b
等價于 a=a/b取模
a%=b等價于 a=a%b左移一位
a<<=b等價于 a=a<<b右移一位
a>>=b等價于 a=a>>b按位與
a&=b等價于 a=a&b按位異或
a^=b
等價于 a=a^b按位或
a|=b
等價于 a=a|b28自增,自減操作符自增(++),自減(--):
a++等價于a=a+1a--
等價于a=a
-1自增、自減符號既可位于變量的前面,也可位于變量的后面。前綴++表示先將其后的變量值增1,然后將增1后的變量參與表達式運算;而后綴++表示將其前面的變量先參與表達式運算,然后變量本身增1。在單獨作為一個表達式時,++a和a++(或--a和a--
)效果一樣,都是將變量a自增1。29若自增(++),自減(--)符作為一個復雜表達式的一部分時,如:(a++)+b
和(++a)+b效果就不一樣:在a、b初值均為1的條件下結(jié)果不同。30條件操作符條件操作符是C++中唯一的具有三個運算元的操作符,其形式為:
表達式1?表達式2:表達式3它的運算方式為:先計算表達式1的值,如果其值為非零(true),則表達式2的值就是整個表達式的最終結(jié)果,否則表達式3的值就是整個表達式的值。常見的一個例子為:
#defineMIN(x,y)((x<y)?x:y)
上例定義了一個求兩個數(shù)x和y中的最小值的宏,其中決定哪一個是最小值用了條件操作符。31語句語句是C++程序中最小的可執(zhí)行單元。一條語句由一個分號結(jié)束。語句可以是簡單語句,也可以是復雜語句。
intradius;
是聲明語句;
circum=2*PI*radius;
是表達式語句;
它由一個表達式后接一個分號形成。
cout<<"hello,world";
cin>>Value;等都是簡單語句。這些語句告知計算機該如何定義變量以及如何執(zhí)行程序。32除簡單語句外,C++還定義了一些可以控制程序執(zhí)行流程的語句,這些語句提供對控制流的分支和循環(huán)功能。C++中默認,
語句都是順序執(zhí)行,如果碰到分支或循環(huán)語句,順序執(zhí)行的規(guī)則就要改變。此外,C++中還有一些跳轉(zhuǎn)語句。有時還有一些語句需要合在一起作為語法結(jié)構(gòu)中的一條語句,這時需要將這些語句用大括號括起來,形成一個復合語句,復合語句不需要以分號終結(jié)。33if語句
(二分支選擇型)if
語句的一般格式為:
if(條件表達式
)語句;如果條件表達式的結(jié)果為true
(非零值),則執(zhí)行語句語句,否則跳過這段語句。語句可以有多條,這時需用大括號{}將這些語句括起來,形成一條復合語句。
if(條件表達式){
語句1;
語句2;……}34如果希望在條件滿足和不滿足時分別執(zhí)行不同語句,則用
else引入條件不滿足時的語句:
if(條件表達式)
語句1;else
語句2;語句1,語句2也可以是復合語句,不過這時的語句不需以分號結(jié)尾。語句1、語句2中又可以出現(xiàn)
if語句,所以
if語句可以嵌套,不過這時容易帶來語義的歧義性。35例
if(ch>='0')if(ch<='9')cout<<“這是一個數(shù)字!”;
elsecout<<“這不是一個數(shù)字!”;這時
else與哪個
if匹配呢?為解決語義上的這種歧義性,C++中規(guī)定,else總是與最后一個出現(xiàn)的還沒有
else與之匹配的if匹配,所以上面一句的
else
與第二個
if匹配,如果程序員想讓它與第一個
if匹配,可以用大括號將不與else匹配的
if語句括起來,使之成為復合語句。36
if(ch>='0'){if(ch<='9')cout<<“這是一個數(shù)字!”;
}elsecout<<“這不是一個數(shù)字!”;條件表達式用于程序有分支語義的場合。下例判斷兩個數(shù)是否從小到大排列,如果不是,則交換兩個數(shù):
voidswap(int
x1,intx2){if(x1>x2){inttemp
=x1;x1=x2;x2=temp;}}37Switch語句(多分支選擇型)
switch語句用于有多重選擇的場合,形式為
switch(表達式){case值1:語句組;break; //break可沒有
case值2:語句組;break; //break可沒有
……case值n:語句組;break; //break可沒有
default:語句組;};注意case后的數(shù)值必須是一個整型的常量表達式,且任意兩個選擇項不能相等。38當switch語句執(zhí)行時,先計算其后的表達式值,將表達式的值與后面各
case關鍵字后所跟選擇常量依次比較。如果與某一選擇常量相等,則執(zhí)行其冒號后跟的語句。如果和任何選擇常量都不等,則執(zhí)行
default子句后的語句(如果
default子句存在)或什么也不做(如果
default
子句不存在)。每個case子句都以break語句結(jié)束。break子句的作用是終止當前switch語句的執(zhí)行。39例:統(tǒng)計文章中各字母出現(xiàn)的次數(shù)。程序每讀入一個字符ch,根據(jù)它的值,將相應的計數(shù)值增1,假定英文大小寫不區(qū)分。
int
aCnt=0,bCnt=0,…,zCnt=0;
switch(ch){case'a': case'A':aCnt++;break;case'b':
case’B':bCnt++;break;//case'z':case’Z':zCnt++;break;}40循環(huán)語句循環(huán)語句提供重復處理的能力,當某一特定條件為
true
時,循環(huán)語句就重復執(zhí)行,并且每循環(huán)一次,就會測試一下循環(huán)條件,如果為
false,則循環(huán)結(jié)束,否則繼續(xù)循環(huán)。C++支持三種格式的循環(huán)語句:while、
do和
for
語句。三者可以完成類似的功能,不同的是它們控制循環(huán)的方式。41while語句(先判斷循環(huán))while
語句的一般形式為:
while(條件表達式)
循環(huán)體語句
while
循環(huán)先計算條件表達式,當條件表達式的運算結(jié)果為
true
時,就執(zhí)行循環(huán)體語句。執(zhí)行一次循環(huán)體語句后,就會重新計算條件表達式,當表達式的值為
false
時,循環(huán)結(jié)束。while
循環(huán)可能一次也不執(zhí)行。42下列程序計算輸入文件的字符數(shù),并在標準輸出上輸出文件內(nèi)容:
#include<iostream.h>#include<fstream.h>
main(){charch;intcount=0;//字符數(shù)計數(shù)器
ifstreaminfile("data.in",ios::in);while(infile&&infile.get(ch)){cout<<ch;count++;}cout<<"count:"<<count;return(0);}43do語句(后判斷循環(huán))do語句的一般形式為:
do
循環(huán)體語句
while(條件表達式);do語句先執(zhí)行循環(huán)體語句,然后計算條件表達式是否為
true,如果是,則繼續(xù)執(zhí)行循環(huán),否則結(jié)束循環(huán)。與
while語句不同的是,do
循環(huán)中的循環(huán)體語句至少執(zhí)行一次,而while語句當條件第一次不滿足時循環(huán)體語句一次也不執(zhí)行。44對字符計數(shù)的程序也可以用do語句實現(xiàn)。
#include<iostream.h>#include<fstream.h>intmain(){charch;intcount=0;//字符個數(shù)計數(shù)器
ifstreaminfile("data.in",ios::in);if(infile&&infile.get(ch)){do{cout<<ch;count++;}while(infile&&infile.get(ch));cout<<"count:"<<count;}return(0);}45for語句for語句用于預先知道循環(huán)次數(shù)的情況,其一般形式為:
for(初始化語句;表達式1;表達式2)
循環(huán)體語句;其中初始化語句可以是一條聲明或表達式,用于對循環(huán)控制變量進行初始化或賦值。表達式1
用于控制循環(huán)結(jié)束,當它的值為
true
時,繼續(xù)循環(huán),為false時終止循環(huán)。表達式2
在每次循環(huán)執(zhí)行后改變循環(huán)控制變量的值。46具體來說,for循環(huán)的執(zhí)行過程為:
執(zhí)行初始化語句;
計算表達式1的值;
如果表達式
1的值為true:
先執(zhí)行循環(huán)體語句;
再執(zhí)行表達式2;
然后轉(zhuǎn)向步驟;如果表達式1的值為false,則結(jié)束循環(huán)。47例:數(shù)組初始化
for(int
i=0;i<size;i++)array[i]=0;
array[i]=0i++i<sizei=0TrueFalse48跳轉(zhuǎn)語句跳轉(zhuǎn)語句將中斷程序的執(zhí)行,跳轉(zhuǎn)到其他地方繼續(xù)執(zhí)行。包括break、continue和goto語句。break語句break語句將使程序從當前的循環(huán)語句
(do,while,for
)內(nèi)跳轉(zhuǎn)出來,接著執(zhí)行循環(huán)語句后面的語句。switch
語句中也用到了break語句,這時它表示終止當前switch語句的執(zhí)行,接著運行switch后的語句。49continue語句continue語句也用于循環(huán)語句,它不是結(jié)束循環(huán),而是結(jié)束循環(huán)語句的當前一次循環(huán),接著執(zhí)行下一次循環(huán)。在
while和
do循環(huán)中,執(zhí)行控制權(quán)轉(zhuǎn)至對條件表達式的判斷,在
for
循環(huán)中,轉(zhuǎn)去執(zhí)行表達式2。
goto語句goto語句無條件轉(zhuǎn)移程序的執(zhí)行控制,它總是與一標號(label)相匹配,其形式為:
goto標號;
50標號是一個用戶自定義的標識符,它可以處于goto語句的前面,也可以處于其后面,但是標號必須與goto語句處于同一個函數(shù)中。標號定義時,由一個標識符后面跟一冒號組成,如:
gotonext; ……next:語句
//標號51下面程序要從鍵盤讀入用戶輸入的數(shù),對其求和,當用戶輸入數(shù)0時,表示輸入結(jié)束。
#include<iostream.h>intmain(){intsum=0;intiVal;while(1){ //永遠循環(huán)
cout<<“請輸入一個整數(shù)或0:”;cin>>iVal;if(iVal==0)break; //循環(huán)出口條件
sum+=iVal;}cout<<”Thesum:”<<sum<<‘\n’;return0;}52下面程序?qū)τ脩糨斎氲乃姓龜?shù)求和,如果輸入的是負數(shù),則忽略該數(shù)。
intsum=0;intiVal=1;while(iVal!=0){cout<<"請輸入一個整數(shù)或0:";cin>>iVal;if(iVal<0)continue;
sum+=iVal;}cout<<“Thesum:”<<sum<<‘\n’;53C++的類C++的核心部分是類的定義。類定義體現(xiàn)了抽象數(shù)據(jù)類型的思想。為達到信息隱蔽的原則。規(guī)定對類的成員有三級存取:共有(public)私有(private)保護(protected)在
public
域中聲明的數(shù)據(jù)成員和函數(shù)成員(成員函數(shù)),程序中其它類的對象或操作都能請求該類的對象執(zhí)行它們,因此這些數(shù)據(jù)成員和成員函數(shù)構(gòu)成類的界面部分。54在private域和protected域中聲明的數(shù)據(jù)成員和成員函數(shù)構(gòu)成類的私有部分,只能由該類的對象和成員函數(shù),以及聲明為友元(friend)的函數(shù)或類的對象才能訪問它們。在protected域中聲明的數(shù)據(jù)成員和成員函數(shù),還允許該類的派生類訪問它們;在private域中聲明的數(shù)據(jù)成員和成員函數(shù),則不允許該類的派生類訪問它們。下面給出一個point類的聲明。Point類中點的表示由兩個整數(shù)變量x,y
組成。類的用戶不能直接訪問它們。55#ifndefPOINT_H#definePOINT_H//Intheheaderfilepoint.hclassPoint {//類定義
private: //私有域
int
x;//數(shù)據(jù)成員:點坐標
int
y;
public://共有域
Point(int,int);//構(gòu)造函數(shù)
Point(Point&);//復制構(gòu)造函數(shù)
~Point();//析構(gòu)函數(shù)
intget_x();//取x坐標
intget_y();//取y坐標56
Pointoperator+(point);//點加點
Pointoperator/(int);//點除整數(shù)
Pointoperator*(int);//點乘整數(shù)
intoperator>(Point);//點比較
intoperator<(Point);//點比較
intoperator==(Point&);//點比較
friendistream&operator>>(istream&,Point&);//輸入友元函數(shù)
friendostream&
operator<<(ostream&,Point&);//輸出友元函數(shù)
};#endif
57為了存取一個點的x,y分量,類提供了兩個函數(shù)get_x,get_y。這樣可用private域來保護數(shù)據(jù)的表示,防止類的用戶直接使用數(shù)據(jù)的內(nèi)部表示來編寫代碼,通過使用存取函數(shù)來操作數(shù)據(jù)來維持類的抽象性。private是聲明默認的存取級別。系統(tǒng)開發(fā)時,把類的聲明放在頭文件中,成員函數(shù)的實現(xiàn)放在源程序文件中。在源程序文件中函數(shù)的實現(xiàn)通過作用域設定命令“::”而被歸屬到某一個類。58
例,對于Point類的輸出友元函數(shù)的實現(xiàn)可以在源程序文件中給出,形為:
ostream&
operator<<(ostream&strm,Pointp){returnstrm<<"("<<p.get_x()<<","<<p.get_y()<<")";
}這個函數(shù)把點p的值以“x,y”的格式送到strm指明的輸出流中去。59C++中的對象建立類的對象(亦稱為實例化)時采用的方式類似于定義C變量的方式,可以自動地,或靜態(tài)地,或通過動態(tài)分配來建立。建立一個
Point類實例的語句是:
Pointp(6,3);自動地
Pointq; 自動地
staticPoints(3,4); 靜態(tài)地
Point*t=newPoint(1,1);通過動態(tài)分配對象p、q和s都是Point類的對象。60構(gòu)造函數(shù)當遇到以上的每一個語句時,將隱式地調(diào)用一個構(gòu)造(constructor)函數(shù),這個構(gòu)造函數(shù)屬于一個與它同名的類。在Point類的定義中聲明了兩個構(gòu)造函數(shù),構(gòu)造函數(shù)的參數(shù)用于初始化表達式的值。例如,當使用聲明
Pointp(6,3)
建立
Point類的對象
p時,調(diào)用了構(gòu)造函數(shù)
Point(int,int);通過以下函數(shù)定義,將其x,y分量設定為6,3:
Point::Point(inta,intb){x=a;y=b;}Point::Point(inta,intb):x(a),y(b){}61構(gòu)造函數(shù)可以定義默認值。例如
Point::Point(inta=0,intb=0):x(a),y(b){}當定義實例時給定初始值,則該實例以給定初始值來初始化其數(shù)據(jù)成員
Pointp(6,3);
則有
x=a=6,y=b=3當定義實例時未給出初始值。則該實例以默認值來初始化其數(shù)據(jù)成員
Pointq;
則有
x=a=0,y=b=062析構(gòu)函數(shù)當要放棄對象時,需隱式地調(diào)用另一個函數(shù),叫做析構(gòu)(destructor)函數(shù),它屬于名字相同的類,但在名字前面加上了一個“~”。例如~Point。為一個類可定義幾個構(gòu)造函數(shù),但只能定義一個析構(gòu)函數(shù)。當控制要退出自動變量的作用域時,或當通過delete命令釋放一個動態(tài)分配的變量時,就要調(diào)用析構(gòu)函數(shù)。當main函數(shù)執(zhí)行結(jié)束時,將釋放靜態(tài)聲明的變量。一個析構(gòu)函數(shù)用于在刪除一個類的對象時做清除工作。63C++的輸入/輸出在C++中執(zhí)行輸入/輸出操作,需用#include預處理指令包括一個<iostream.h>頭文件。用它可支持C++的流(stream)操作?!傲鳌笔莻€簡單的字符序列。在C++中有兩個預定義的類istream和ostream,它們定義了輸入流和輸出流?;据斎?輸出方式:鍵盤屏幕輸入/輸出文件輸入/輸出64鍵盤屏幕輸入/輸出在C中有用于定向到鍵盤輸入設備、屏幕輸出設備和錯誤文件的命令stdin、stdout和stderr。在C++中用cin,cout和cerr來定義鍵盤輸入類、屏幕輸出類和錯誤信息輸出類。操作符<<用于寫出類ostream的一個對象,對于一系列輸出對象,可用<<分開。操作符>>用于讀入類istream的一個對象。65在下面程序中使用了流cin>>,相繼從標準輸入設備上輸入兩個整型變量a和b,并將它們打印到標準輸出設備上。
#include<iostream.h>voidmain
(){inta,b;cin>>a>>b;cout<<”a:"<<n<<
"f:"<<f<<endl;}在輸出語句中最后輸出的endl是C++的I/O操作符,它的用途是輸出一個換行符并清空流。66C++中的輸入/輸出可以是自由格式,程序員不需要使用格式化符號來指定輸入/輸出項的類型和順序。與其它C++操作符一樣,輸入/輸出操作符能夠被重載。67文件輸入/輸出C++中的文件輸入/輸出方式如下所示。在程序開頭必須用預處理指令#include包含頭文件<fstream.h>,它定義了類ifstream、ofstream和fstream。要創(chuàng)建一個輸入流,必須聲明它為ifstream類的實例;要創(chuàng)建一個輸出流,必須聲明它為ofstream類的實例。執(zhí)行輸入和輸出操作的流必須聲明它為fstream類的實例68#include<fstream.h>#include<iostream.h>#include<stdlib.h>voidmain
(){ifstreaminFile;//inFile為輸入流對象
ofstream
outFile;//outFile為輸出流對象
outFile.open("my.dat",ios::out);
//建立輸出文件my.dat
charuniv[]=Tsinghua,name[10];
intcourse=2401,number;outFile<<univ<<endl;//輸出到my.datoutFile<<course<<endl;69
inFile.open("my.dat",ios::in|ios::nocreate);
//打開輸入文件my.dat
if
(!inFile
){cerr<<“不能打開my.dat”<<endl;
exit(1); }charc;
inFile>>name>>c>>number;outFile<<"name:"<<name<<endl;outFile<<"number:"<<number<<endl;}70ifstream類、ofstream
類和fstream類都是從istream類和
ostream類派生出來的;而類istream和ostream
又是從類ios
派生出來的,因此這些類都可使用類ios
的所有運算。在調(diào)用打開文件函數(shù)open()時,函數(shù)參數(shù)表包括實際文件名和數(shù)據(jù)流動的方向,函數(shù)返回文件的開始地址。系統(tǒng)在存儲文件時,在其末尾添加有文件結(jié)束標記。如果文件未被打開,則outFile
=0;如果文件被成功地打開,則它將代替cout,將輸出引導到文件my.dat中。71在文件打開的操作中,指定的文件模式有以下幾種:
iso::app:把所有對文件的輸出添加在文件尾。它只用于輸出文件。
iso::binary:文件以二進制方式打開。此項缺省時文件以文本方式打開。
iso::nocreate:若文件不存在則將導致打開操作失敗。
iso::out:表明該文件用于輸出。此項可缺省。
iso::in:表明該文件用于輸入。此項可缺省。72C++中的函數(shù)
在C++中有兩種函數(shù):
常規(guī)函數(shù)和成員函數(shù)不論哪種函數(shù),其定義都包括4個部分:函數(shù)名、形式參數(shù)表、返回類型和函數(shù)體。函數(shù)的使用者通過函數(shù)名來調(diào)用該函數(shù);調(diào)用時把實際參數(shù)傳送給形式參數(shù)表作為數(shù)據(jù)的輸入;通過函數(shù)體中的處理程序?qū)崿F(xiàn)該函數(shù)的功能;最后得到返回值作為輸出。73下面給出一個函數(shù)的例子。Max是函數(shù)名,inta和intb是形式參數(shù)表,函數(shù)名前面的int是返回類型,在花括號內(nèi)括起來的是函數(shù)體,它給出了函數(shù)操作的實現(xiàn)。
intmax(inta,intb){
//函數(shù)返回
a
與b
中的大值
if(a>b)returna;elsereturnb;}在C++中所有函數(shù)都有一個返回值,或者返回計算結(jié)果,或者返回執(zhí)行狀態(tài)。74如果函數(shù)不需要返回值,可使用
void
來表示它的返回類型。函數(shù)的返回值通過函數(shù)體中的
return
語句返回。return
的作用是返回一個與返回類型相同類型的值,并中止函數(shù)的執(zhí)行。函數(shù)返回時可以通過引用方式,參看下面程序,此時在函數(shù)類型后面加上一個“&”。
#include<iostream.h>char&replace(intm);chars[80]=“HelloThere”;75main(){
replace(5)=‘x’;cout<<s;
//用x代替Hello后面的空格}char&replace(intm){returns[m];}函數(shù)replace()的返回類型說明為返回一個字符的引用類型,在函數(shù)執(zhí)行時返回參數(shù)m指定的s數(shù)組元素的值。main()執(zhí)行時把字符“x”送給s[5]。76C++中的參數(shù)傳遞函數(shù)調(diào)用時傳送給形參表的實參必須與形參在類型、個數(shù)、順序上保持一致。參數(shù)傳遞有兩種方式。一種是傳值,這是缺省的參數(shù)傳遞方式;一種是引用類型。使用傳值方式時,把實參的值傳送給函數(shù)局部工作區(qū)相應的副本中,函數(shù)使用這個副本執(zhí)行必要的功能。這樣,函數(shù)修改的是副本的值,實參的值不變。77使用引用類型方式傳遞時,需將形參聲明為引用類型,即在參數(shù)名前加一個“&”。參看下面的程序示例。當一個實參與一個引用型形參結(jié)合時,被傳遞的不是實參的值,而是實參的地址,函數(shù)通過地址存取被引用的實參。函數(shù)執(zhí)行后實參的值將發(fā)生改變。當一個函數(shù)的返回值多于一個時,其中一個可由return語句返回,其它返回值可使用引用型參數(shù)返回。#include<iostream.h>voidswap(int&i,int&j);78main(){inta=1,b=2;cout<<"aandb:"<<a<<""<<b<<"\n";
swap(a,b);
//調(diào)用時實際參數(shù)不需要加&cout<<"aandb:"<<a<<""<<b<<"\n";}voidswap(int&i,int&j){//對換
i與
j的內(nèi)容
intt=j;j=i;i=t; //不需要加*}79一種特殊的引用調(diào)用方式叫做常值引用,其格式為constType&a,其中Type為參數(shù)的數(shù)據(jù)類型。在函數(shù)體中不能修改常值參數(shù)。一種特殊情況是數(shù)組參數(shù)的傳遞。數(shù)組作為形參可按傳值方式聲明,但實際采用引用方式傳遞,傳遞的是數(shù)組第一個元素的地址。在函數(shù)體內(nèi)對形參的數(shù)組所做的任何改變都將反映到作為實參的數(shù)組中。此外,在參數(shù)表中一般按形如intR[]
的形式聲明,因此需要顯式地聲明數(shù)組的大小。80若傳送的值參是一個對象
(作為類的實例)時,在函數(shù)中就創(chuàng)建了該對象的一個副本。在創(chuàng)建這個副本時不調(diào)用該對象的構(gòu)造函數(shù),但在函數(shù)結(jié)束前要調(diào)用該副本的析構(gòu)函數(shù)撤消這個副本。若采用引用方式傳遞對象,在函數(shù)中不創(chuàng)建該對象的副本,也不存在最后撤消副本的問題。但是,通過引用傳遞的是對象時,函數(shù)對對象的改變將影響調(diào)用的對象。81
成員函數(shù)的返回值當成員函數(shù)的返回值為傳值方式時,允許改變該對象的私有數(shù)據(jù)成員。當成員函數(shù)的返回值為常值傳值方式時,需加const
標識,該對象的私有成員不能改變。當成員函數(shù)的返回值為引用方式時,該成員函數(shù)的返回值應是一個已存在變量(或?qū)ο?的別名。當該成員函數(shù)被重新賦值時,其對應變量(或?qū)ο?的值將改變。當成員函數(shù)的返回值為常值引用方式時,其返回值與引用方式的成員函數(shù)返回值類同。但該成員函數(shù)不能改變該對象的私有成員。82當成員函數(shù)返回值為常值傳值方式或常值引用方式時,const標識符一般放在最后。
#include<iostream.h>classTemperature{private:floathighTemp,lowTemp;//數(shù)據(jù)成員
public:
Temperature(inthi,intlo)//構(gòu)造函數(shù)
{highTemp=hi;lowTemp=lo;}voidUpdateTemp(floattemp);//傳值返回
floatGetHighTemp()const;//常值返回83
floatGetLowTemp()const;//常值傳值返回};voidTemperature::UpdateTemp(floattemp){
if(temp>highTemp)highTemp=temp;
if(temp<LowTemp)LowTemp=temp;}floatTemperature::GetHighTemp()const{
returnhighTemp;}floatTemperature::GetHighTemp()const{
returnhighTemp;}84C++中的函數(shù)名重載函數(shù)名重載允許C++程序中多個函數(shù)取相同的函數(shù)名,但其形參或返回類型可以不同。例如,C標準函數(shù)庫中有3個標準函數(shù)abs(
)、labs()和fabs(
),分別計算整型數(shù)、長整型數(shù)和雙精度型數(shù)的絕對值。在C中因處理的數(shù)據(jù)類型不同,必須取不同的函數(shù)名。在C++中,可以把這3個函數(shù)都命名為abs(
):
intabs(int);longabs(long);doubleabs(double);85C++的操作符重載
C++提供了一種能力,可用同一個名字定義多個函數(shù),這種能力叫做操作符重載。例如,可以命名一個函數(shù):clear(*int),它將一個整數(shù)清零。還可以再命名另一個函數(shù)clear(int[
]),它把一個整數(shù)數(shù)組清零。編譯器能夠比較具有同名的函數(shù)的特征,通過識別實參的數(shù)目和每個實參的類型,來標識使用于一個特定調(diào)用的是哪一個版本的abs()。
86
在C中,必須使用名字clearIntArray()
和clearInt()
來區(qū)分這兩個函數(shù)。在C++中,編譯器能夠比較同名函數(shù)的特征,通過識別實參的數(shù)目和每個實參的類型,來標識一個特定調(diào)用中用的是哪一個版本的clear。為了支持面向?qū)ο?,C++提供了雙目重載操作符(如‘+’和‘<’)。這種操作可使得程序更可讀、寫得更自然。例如,可定義“點(Point)”的運算,像
p1+p2:把兩個點(x1,y1)和(x2,y2)相加成一個點(x1+x2,y1+y2)。87
p1<p2:兩個點p1和p2
的“小于”關系,表示p1比p2更靠近原點(0,0)。
p1/i:一個點p=(x,y)除以一個整數(shù)i
的除法(x/i,y/i)??梢园匆韵路绞绞褂弥剌d操作:
Pointoperator+(Pointp);Pointoperator/(inti);
intoperator<(Pointp);使用這些新的操作的表達式如:PointmidPoint=(point1+point2)/2;
或if(midPoint<referencePoint)...88注意:每一個這樣的操作符在調(diào)用時可看成是該操作符左邊對象的成員函數(shù)。例如,(point1+point2)實際上是一個消息。由類Point的實例point1調(diào)用成員函數(shù)“+”,該對象的屬性確定第一個操作數(shù)的值。函數(shù)參數(shù)表中指定的Point的實例point2的屬性確定第二操作數(shù)的值。這種重載能力允許像使用內(nèi)建類型(如int,float)那樣來使用用戶自定義類型。與在不允許重載操作的語言中相同的語句比,這樣可以改善程序的可讀性。89C++的動態(tài)存儲分配在C程序中,使用一個函數(shù)malloc,為程序分配它所需要的空間,一旦程序執(zhí)行結(jié)束需要返回到它的調(diào)用者時,必須釋放這個空間。C++為動態(tài)存儲分配提供了兩個新的命令:new和delete。它們可用于取代C中的庫函數(shù)malloc和free。在C++中沒有無用單元收集,使用new分配的存儲必須顯式地使用delete釋放。90操作new要求以被建立對象的類型做為參數(shù),并返回一個指向新分配空間的指針。作為對比,在C中,函數(shù)malloc要求它的調(diào)用者提供所需存儲空間的數(shù)量。例如,為動態(tài)分配一個整數(shù)或一個點,可編寫如下語句:
int*ip=newint;
或Point*p=newPoint;它們組成了指針變量的聲明(如*name)和動態(tài)存儲分配(new類型)。91Delete命令必須能夠知道要釋放動態(tài)分配的是一個數(shù)組,還是一個簡單變量。例如,如果已建立下列有100個點的數(shù)組:
Point*p=newPoint[100];則通過以下命令釋放該存儲:delete[]p;若遺漏了“[]”,則將只釋放p
所指示的第一個元素,將“失去”其它99個點所占據(jù)空間,以致不能再復用它們。若使用時元素下標超出100,程序?qū)鲥e且結(jié)果不可預測。92友元(friend)函數(shù)在類的聲明中可使用保留字friend
定義友元函數(shù)。友元函數(shù)實際上并不是這個類的成員函數(shù),它可以是一個常規(guī)函數(shù),也可以是另一個類的成員函數(shù)。如果想通過這種函數(shù)存取類的私有成員和保護成員,則必須在類的聲明中給出函數(shù)的原型,并在該函數(shù)原型前面加上一個friend。參看Point類的聲明,有兩個重載操作符<<
與>>,它們都被聲明為友元函數(shù)。93內(nèi)聯(lián)(inline)函數(shù)在函數(shù)定義前加上一個inline前綴就成為內(nèi)聯(lián)函數(shù)。編譯程序在編譯時將會把這個函數(shù)語句直接插入到普通代碼中,因而減少了與函數(shù)調(diào)用和參數(shù)傳遞有關的系統(tǒng)開銷。直接插入代碼所需要的空間比不直接插入的調(diào)用方式所需要的空間要多,這取決于函數(shù)定義的大小。除了加上inline保留字外,內(nèi)聯(lián)函數(shù)的定義與其它任何函數(shù)定義的方式一樣。
inlinePointoperator+(Pointp);94結(jié)構(gòu)(struct)與類C++擴充了C中結(jié)構(gòu)(struct)型的功用,加進成員函數(shù)以說明一個類(class)。在C++中struct與class的區(qū)別在于:在struct中,默認的訪問級別是public。若在struct內(nèi)部自始至終缺省訪問級別,則所有的成員都是共有的。在class中,缺省的訪問級別是private。除此之外,struct與class是等價的。例如,下面給出定義矩形類的三種等價的類聲明。95classRectangle{intx1,y1,h,w;public:
Rectangle(
);~Rectangle(
);intGetX(
);intGetY(
);voidSetX(intx);voidSetY(inty);intGetHeight(
);intGetWidth(
);…………}96structRectangle{
Rectangle(
);~Rectangle(
);intGetX(
);intGetY(
);voidSetX(intx);voidSetY(inty);intGetHeight(
);intGetWidth(
);…………private:intx1,y1,h,w;}97聯(lián)合(Union)與類與結(jié)構(gòu)一樣,用Union也可以定義類。在C++中,Union可包含函數(shù)和變量,還可包含構(gòu)造函數(shù)和析構(gòu)函數(shù)。C++的Union保留了所有C的特性,主要是讓所有的數(shù)據(jù)成員共享相同的存儲區(qū)。與cla
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 收納師考試實例分享與分析試題及答案
- 2024年秘書證考試備考技巧分享試題及答案
- 關于珠寶鑒定師考試的試題及答案詳解
- 2024年檔案管理員工作經(jīng)驗分享試題及答案
- 2024年多媒體設計師考試信息來源試題及答案
- 多媒體制作中的團隊溝通技巧試題及答案
- 2024年稅務師考試技能提升試題及答案
- 2024年建造師考試預測試題及答案
- 檔案信息準確性的保障試題及答案
- 2024年建筑行業(yè)新規(guī)試題及答案
- 食堂7s管理標準
- 藥店托管合同協(xié)議書
- DEEPSEEK了解及使用攻略高效使用技巧培訓課件
- 玉盤二部合唱簡譜
- 《飼料標簽》國標
- 實施批準文號管理的中藥飲片
- 淺析重復性隱患問題發(fā)生的原因及防治措施
- 老年服務與管理專業(yè)實習報告
- 厭氧塔計算手冊
- 壓力管道施工方案(完整版)
- 2021-2021歷年專四語法真題參考答案
評論
0/150
提交評論