第3章面向?qū)ο蟪绦蛟O計語言基礎(chǔ)_第1頁
第3章面向?qū)ο蟪绦蛟O計語言基礎(chǔ)_第2頁
第3章面向?qū)ο蟪绦蛟O計語言基礎(chǔ)_第3頁
第3章面向?qū)ο蟪绦蛟O計語言基礎(chǔ)_第4頁
第3章面向?qū)ο蟪绦蛟O計語言基礎(chǔ)_第5頁
已閱讀5頁,還剩382頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第3章面向?qū)ο蟪绦蛟O計語言基礎(chǔ)3.1面向?qū)ο蟪绦蛟O計語言3.2C++語言基礎(chǔ)3.3Java的基礎(chǔ)知識3.1面向?qū)ο蟪绦蛟O計語言掌握面向?qū)ο蟪绦蛟O計,首先應該學習面向?qū)ο蟪绦蛟O計語言。當今有很多種編程語言能體現(xiàn)基本的面向?qū)ο笏枷?,如C++、Java、Smalltalk、CLOS等,但普遍被推崇的、流行的有兩種,即C++和Java。下面將介紹C++和Java的一些基礎(chǔ)知識。3.1.1程序程序是有目的的動作序列,它是一種軟件。對于程序員來說,程序是以某種語言為工具編制出來的動作序列,它表達了人解決現(xiàn)實世界問題的思想。計算機程序是用計算機程序設計語言所要求的規(guī)范書寫出來的一系列動作,它表達了程序員要求計算機執(zhí)行的操作。對于計算機來說,一組機器指令就是程序。我們所說的機器代碼或者機器指令,都是指程序,它是按計算機硬件設計規(guī)范的要求編制出來的動作序列。在計算機中,程序通常以文件的形式保存。3.1.2語言及其分類語言按其等級可分為高級語言和低級語言。機器語言和匯編語言都是低級語言。程序語言越低級,程序的描寫越復雜,越難懂,程序描述的問題越接近機器。最早,程序員使用最原始的計算機指令,即機器語言程序。只有機器語言才能被機器識別和運行,這些指令以一串二進制數(shù)表示。不久,發(fā)明了匯編語言,它可以將機器指令映射為一些能被人讀懂的助記符。以后,各種高級語言迅速發(fā)展起來。發(fā)展過程中,經(jīng)歷了嚴酷的優(yōu)勝劣汰過程,最后剩下一些比較優(yōu)秀的高級語言。C++作為一種多范型語言,就是一種優(yōu)秀的高級語言。例如,我們用C++和匯編語言分別來實現(xiàn)表達式a=2b+3c?1,用C++實現(xiàn)為a=2*b+3*c?1;用匯編來實現(xiàn)為

moveax,DWORDPTRb_$[ebp]movecx,DWORDPTRc_$[ebp]muleax,2mulecx,3addeax,ecxdeceaxmovDWORDPTRb_$[ebp],eax語言越低級,就表明越靠近機器;越高級,就表明越靠近人的表達與理解、越自然。程序語言的發(fā)展,是從低級到高級,直到可用人的自然語言來描述。程序語言的發(fā)展也是從具體到抽象的發(fā)展過程。從上面的例子中可以看出,作為高級語言的C++在實現(xiàn)表達式時要比匯編語言簡潔得多。3.1.3C++是面向?qū)ο蟪绦蛟O計語言正如第1、2章所述,程序設計方法正在從結(jié)構(gòu)化程序設計走向面向?qū)ο蟪绦蛟O計。C語言能夠很好地支持結(jié)構(gòu)化范型程序設計,而C++能夠很好地支持面向?qū)ο蠓缎统绦蛟O計。在第4、5章中將介紹用C++來實現(xiàn)面向?qū)ο蠓缎偷某绦蛟O計。3.2C++語言基礎(chǔ)3.2.1C++的發(fā)展史

C++僅有二十幾年的歷史,它是C語言的擴展和完善。C語言是貝爾實驗室的DennisRitchie在B語言的基礎(chǔ)上開發(fā)出來的。1972年在一臺DECPDP-11計算機上實現(xiàn)了最初的C語言。到20世紀70年代末,C已經(jīng)演化為現(xiàn)在所說的“傳統(tǒng)的C語言”。Kernighan和Ritchie在1978年出版的《TheCProgrammingLanguage》一書中全面地介紹了傳統(tǒng)的C語言,1989年美國國家標準協(xié)會制定了C語言的標準(ANSIC)。Kernighan和Ritchie編著的第二版《TheCProgrammingLanguage》(1988年版)介紹了ANSIC的全部內(nèi)容。至此,C語言以其如下獨有的特點風靡了全世界:(1)語言簡潔、緊湊,使用方便、靈活。C語言只有32個關(guān)鍵字,程序書寫形式自由。(2)豐富的運算符和數(shù)據(jù)類型。(3)C語言可以直接訪問內(nèi)存地址,能進行位操作,能夠勝任開發(fā)操作系統(tǒng)的工作。(4)生成的目標代碼質(zhì)量高,程序運行效率高。(5)可移植性好。

C語言盛行的同時,也暴露出了其局限性:(1)類型檢查機制相對較弱,這使得程序中的一些錯誤不能在編譯時發(fā)現(xiàn);(2)C本身幾乎沒有支持代碼重用的語言結(jié)構(gòu),因此一個程序員精心設計的程序很難為其他程序所用;(3)當程序的規(guī)模達到一定的程度時,程序員很難控制程序的復雜性。為滿足管理程序復雜性的需要和克服C語言的以上缺點,就必須對C語言進行完善或以一種新的語言來代替C語言,C++就是在這種環(huán)境下應運而生的。1980年,貝爾實驗室的BjarneStroustrnp開始對C進行改進和擴充。最初的成果稱為“帶類的C”,1983年正式取名為C++。在對C++進行了三次修訂后,于1994年制定了ANSIC++標準的草案,以后又經(jīng)過不斷完善成為目前的C++。C++仍在不斷發(fā)展中。

C++包含了整個C,C是建立C++的基礎(chǔ);添加了對面向?qū)ο蟪绦蛟O計(OOP)的完全支持。下面介紹在用C++來實現(xiàn)面向?qū)ο蟪绦蛟O計中,必須掌握的C++的關(guān)于支持面向?qū)ο蠓矫娴鹊恼Z法基礎(chǔ)。對C缺乏了解的讀者,建議在本書之外,盡快瀏覽一下C語言的有關(guān)內(nèi)容。3.2.2C++基礎(chǔ)語法1.關(guān)鍵字關(guān)鍵字是預先定義好的標識符,這些標識符在C++編寫程序的時候,有特殊的含義。在C++中共有61個關(guān)鍵字。在程序設計的過程中應注意,程序中用到的其他名字不能與這些關(guān)鍵字有相同的拼法(包括大小寫都不能相同)。表3-1給出了C++中定義的關(guān)鍵字。表3-1C++中定義的關(guān)鍵字staticautobreakunsignedprotectedconstuniondefaultdoubleelseexplictcontinuefloatforgotointlongregistervolatileshortsignedsizeofstructswitchtypedefoperatorcasevoidreturnboolcatchclassconst_castdeleteenumfalseinlinemutablenamespacedynamic_castnewexternprivatepublicthistemplatereinterpret_castthrowturetrytypenameusingvirtualstatic_castwchar_tdoifwhilefriendchartypeid

2.基本數(shù)據(jù)類型在程序中要用到數(shù)據(jù),數(shù)據(jù)常以變量或常數(shù)的形式來描述。每個變量或常數(shù)都有數(shù)據(jù)類型。變量是存儲信息的存儲單元,它對應于某個內(nèi)存空間,用變量名代表其存儲空間,程序能在變量中存儲和取出值。數(shù)據(jù)類型用來告訴編譯器應為變量分配多少內(nèi)存空間、怎樣組織已分配的內(nèi)存空間,以及變量中要存儲值的類型。數(shù)據(jù)類型分為基本數(shù)據(jù)類型和非基本數(shù)據(jù)類型。非基本數(shù)據(jù)類型包括數(shù)組、指針和結(jié)構(gòu)等類型?;緮?shù)據(jù)類型有char、int、float、double、wchar_t和bool等。圖3-1描述了C++的數(shù)據(jù)類型的分類。圖3-1中的type表示非空的數(shù)據(jù)類型,是程序員可以自己定義的數(shù)據(jù)類型。在圖3-1中只是給出了常用數(shù)據(jù)類型和部分數(shù)據(jù)類型修飾符,它們用來改變基本類型的意義,用于適應各種情況的需要。修飾符有l(wèi)ong(長型符)、short(短型符)、signed(有符號)和unsigned(無符號)等。數(shù)據(jù)類型修飾符確定了該數(shù)據(jù)所占內(nèi)存空間的大小和可表示的數(shù)值范圍。表3-2是16位計算機中各數(shù)據(jù)類型所能表示的數(shù)值范圍。圖3-1C++的數(shù)據(jù)類型表3-2常用基本數(shù)據(jù)類型描述類型說明長度(字節(jié))表示范圍備注char字符型1-128~127-27~(27-1)unsignedchar無符號字符型10~2550~(28-1)signedchar有符號字符型1-128~127-27~(27-1)int整型2-32?768~32?767-215~(215-1)unsignedint無符號整型20~65?5350~(216-1)signedint有符號整型2-32?768~32?767-215~(215-1)shortint短整型2-32?768~32?767-215~(215-1)longint長整型4-2?147?183?648~2?147?483?647-231~(231-1)float浮點型(單精度)4-3.4×1038~3.4×10387位有效位double雙精度8-1.7×1038~1.7×103815位有效位longdouble長雙精度16-3.4×104932~3.4×10493219位有效位3.變量定義1)變量名的命名C++中變量的命名應該遵守以下規(guī)則:(1)不能是C++關(guān)鍵字;(2)第一個字符必須是字母或下劃線;(3)不要太長,一般不超過31個字符;(4)不能以數(shù)字開頭;(5)中間不能有空格;(6)變量名中不能包含“.;,"'+?'之類的特殊符號。(7)變量名不要與C++中庫函數(shù)名、類名、和對象名相同。2)變量定義方式在給變量命名時,通常用帶有描述性的字符串,例如用area命名一個面積變量,用time命名時間變量。這些變量在應用時,程序員和讀者對其意義一目了然。例如:

intnumber;doublesum;floatlength;

3)變量賦值與初始化用賦值運算符“=”給變量賦值。變量初始化是指在定義變量時直接給變量賦值,也可以先定義變量,然后用賦值語句給其賦值。并不是所有的變量都需要初始化,未初始化的變量在編譯器編譯時并不會出錯。例如:

unsignedshortwidth;doublearea,radius=23;width=4;

其中,變量width先定義后賦值;而變量radius在定義時初始化;變量area未初始化。這些變量在編譯時均不會出現(xiàn)錯誤。4)typedef

用typedef可以為一個已有的類型名提供一個同義詞,該同義詞可以代替該類型在程序中使用。用法是以typedef開始,隨后是要表示的類型,最后是同義詞和分號。typedef實際上沒有定義一個新的數(shù)據(jù)類型,在建立一個typedef類型時沒有分配內(nèi)存。例如:

typedefdoubleprofit;//定義double的同義類型

typedefintINT,integer;//定義int的兩個同義類型

INTa; //同inta;integera; //同inta;profitd; //同doubled;3.2.3常數(shù)1.實數(shù)常數(shù)實數(shù)常數(shù)的表示方法有兩種:(1)十進制小數(shù)。它由數(shù)字和小數(shù)點組成,如0.123,0.234,0.0等都是十進制數(shù)。(2)指數(shù)形式。如:425e4或425E4表示425×104。要注意E或e的前面必須是數(shù)字,且E或e后面的指數(shù)必須為整數(shù)。實數(shù)型常數(shù)常分為單精度(float)、雙精度(double)和長雙精度(longdouble)3類。在16位計算機中,float型數(shù)據(jù)在內(nèi)存中占4個字節(jié),double型數(shù)據(jù)在內(nèi)存中占8個字節(jié),longdouble數(shù)據(jù)類型在內(nèi)存中占16個字節(jié)。float型提供7位有效數(shù)字,double型提供15位有效數(shù)字,longdouble提供19位有效數(shù)字。在C++中,一個實數(shù)如果沒有說明,則其類型為默認類型double型。要表示float型數(shù),則必須在實數(shù)后面加上F或f;要表示longdouble型數(shù),則必須在實數(shù)后面加上L或l。例如:3.2f //float型實數(shù)3.2L

//longdouble型實數(shù)3.2 //沒有說明,故為默認類型double型2.字符常數(shù)字符常數(shù)是用單引號括起來的一個字符,它分為一般字符常數(shù)和特殊字符常數(shù)。一般字符常數(shù)有a、x等字符,特殊字符常數(shù)是以“\”開頭的字符。表3-3列出了常用的特殊字符。表3-3常用的特殊字符字符形式值功能\a0x07響鈴\n0x0A換行\(zhòng)t0x09制表符(橫向跳格)\v0x0B豎向跳格\b0x08退格\r0x0D回車\\0x5C反斜杠字符“\”\"0x22雙引號\'0x27單引號\ddd

1~3位八進制\xhh

1~2位十六進制表中列出的字符又稱為轉(zhuǎn)義字符,即將反斜杠后面的字符轉(zhuǎn)變成另外的意義。有些是控制字符,如“\n”;有些字符是在該字符前加轉(zhuǎn)義字符來表示的,如“\”、“'”、“"”。在內(nèi)存中,字符數(shù)據(jù)以ASCII碼存儲,即以整數(shù)表示,所以字符數(shù)據(jù)和整型數(shù)據(jù)在0~255(一個字節(jié)范圍內(nèi))之間可以相互賦值。只要注意其表示的范圍合理即可。例如:

inta='b'; //正確,將整型變量賦一個字符值(b的ASCII值為98)

charc=97; //正確,將一個字符變量賦一個整型值(97代表的ASCII字符是a)

在下列C++語句中,將自動根據(jù)變量定義時的數(shù)據(jù)類型,來確定輸出的究竟是字符類型值還是整型類型值。例如:

cout<<a<<endl; //輸出字符b的ASCII值98

cout<<c<<endl; //輸出ASCII值97的字符b

上面兩行語句自動根據(jù)a或c被定義的數(shù)據(jù)類型確定其輸出結(jié)果及類型。3.字符串常數(shù)字符串常數(shù)是由一對雙引號括起來的字符序列,字符串常數(shù)和字符常數(shù)是不同的,字符串常數(shù)總是以“\0”結(jié)束。如果一個字符串常數(shù)為“welcome”,那么它在內(nèi)存中占用連續(xù)8個內(nèi)存字節(jié)。在編程時應注意變量類型的匹配,不能將字符串常數(shù)賦給字符變量。4.枚舉常數(shù)枚舉常數(shù)是通過關(guān)鍵字enum來定義的。定義的格式為以enum開始,后跟類型名和花括號?;ɡㄌ杻?nèi)是要定義的枚舉常數(shù)(又稱為助記常數(shù),該助記常數(shù)往往代表一個整型常數(shù)值),各常數(shù)之間用逗號分隔,最后以分號結(jié)束。例如:enumCOLOR{RED=150,BULE=200,GREEN,WHITE=400};

其中,有一個枚舉常數(shù)BLUE,代表200;GREEN沒有被顯式寫出,在編譯時其值自動被確定為201。如果沒有顯式地為枚舉常量確定值,C++會為其自動確定,即花括號后的第一個枚舉常數(shù)會被確定為0,其后的每個枚舉常數(shù)的值為前一個枚舉常數(shù)值加1。在下面程序中,企圖用賦值語句給枚舉變量賦值為不是定義枚舉類型時規(guī)定的值,是不正確的。

COLORpaint=BULE; //正確

piant=200;//錯誤,因為200不是規(guī)定的枚舉類型常數(shù)5.常量定義

C++中,常量是代表固定值的變量,即表示變量的值已被固定。程序中如果想讓變量內(nèi)容初始化后一直保持不變,則可以將其定義成一個常量。本書對常量與常數(shù)進行了區(qū)分(這與其他書有所不同),常數(shù)代表了書寫時的字面含義。常量定義的格式是:在關(guān)鍵字const后接變量名,然后是常數(shù)值,最后以分號結(jié)束該語句。例如:

constfloatpi=3.1415926;在定義了常量pi之后,就可以在程序中用pi來代替3.1415926。常量不能放在賦值語句的左邊,即常量不能被賦值。常量定義中初始化的值可以是一個由常數(shù)和操作符構(gòu)成的表達式。在程序運行之前就已經(jīng)知道了常量值,因此編譯時就能求值。注意:該表達式中不能含有函數(shù),例如:

constintsize=20*sizeof(int); //oksizeof是運算符

constintnumber=max(23,34); //錯誤6.引用引用是變量的別名,用&符號來聲明。對別名的存取就是對變量的存取。別名沒有存儲空間,對引用聲明的同時需對其進行初始化。例3.1引用實例。intx=10;int&y=x; //聲明y是x的引用cout<<y<<endli; //y=10x=20;cout<<y<<endl; //y=20;y=30;cout<<x<<endl; //x=30使用引用比C語言中用指針來實現(xiàn)兩數(shù)交換容易理解且語句簡潔。例如:voidswap(int&xx,int&yy){inttemp;temp=xx;xx=yy;temp=xx;}voidmain(){inta=10,b=20;cout<<a<<"--"<<b<<endl;swap(a,b);//直接用a、b作為實參,而C語言用指針實現(xiàn)交換時,要用其地址

cout<<a<<"--"<<b<<endl;}3.2.4輸入/輸出1.輸入/輸出(I/O)的書寫格式

I/O流是輸入或輸出的一系列字節(jié)。當程序需要在屏幕上顯示輸出時,使用操作符“<<”向cout輸出流中插入字符;當程序需要執(zhí)行從鍵盤輸入時,使用操作符“>>”從cin輸入流中輸入字符。

例3.2I/O書寫格式實例。#include<iostream.h>voidmain(){charch;cout<<"inputthecharacteryouwanttoprint:"<<endl;cin>>ch;cout<<ch<<endl;}程序運行結(jié)果為:

inputthecharacteryouwanttoprint:aa

cout代表I/O的輸出對象(默認為屏幕),在例3.2中它輸出一行提示語句;cin代表I/O的輸入對象,在例3.2中從鍵盤輸入了一個字符a,最后我們有一行輸出語句輸出所輸入的字符。頭文件iostream.h包含涉及cout和cin的一些必要的定義內(nèi)容。在輸入和輸出時還可以使用控制符來控制輸入/輸出的格式,以滿足輸入/輸出的需要,表3-4中列出了常用輸入/輸出控制符。表3-4常用輸入/輸出控制符控制符描述dec置基數(shù)為10hex置基數(shù)為16oct置基數(shù)為8setfill設置填充字setiosflags(ios::fixed)固定的浮點顯示etw設置小數(shù)精度setiosflags(ios::left)左對齊setiosflags(ios::right)右對齊setiosflags(ios::scientific)指數(shù)表示setiosflags(ios::skipws)忽略前導空白setiosflags(ios::uppercase)十六進制數(shù)大寫輸出setiosflags(ios::lowercase)十六進制小寫輸出3.2.5表達式和語句程序是一些按次序執(zhí)行的語句,而大部分的語句是由表達式構(gòu)成的。表達式和語句是C++的重要內(nèi)容。表達式由操作符、操作數(shù)構(gòu)成,其目的是用來說明一個計算過程。在C++中操作符的優(yōu)先級和結(jié)合性等規(guī)則與C語言是完全一致的,使用方法與C語言中表達式的使用方法也是相同的。

C++中所有的操作運算都是通過表達式來實現(xiàn)的。由表達式組成的語句稱為表達式語句,由一個表達式和一個分號組成。大多數(shù)表達式語句是賦值語句和函數(shù)調(diào)用語句。語句用來規(guī)定程序執(zhí)行的控制流。復合語句又被稱為塊,它是一對花括號內(nèi)的語句序列。C++中的語句和C語言中的語句是大致相同的,其使用方法也是一樣的,在本書中不再贅述。下面對過程化語句進行介紹。1.過程化語句

語句按功能可分為兩大類:第一大類用于描述計算機執(zhí)行的操作運算,即操作語句;第二大類用于控制操作運算的執(zhí)行順序的控制語句,即流程控制語句。流程控制語句也被稱為過程化語句。圖3-2while語句的流程結(jié)構(gòu)1)while語句

while語句由4個部分組成:循環(huán)變量初始化、繼續(xù)條件、循環(huán)體、改變循環(huán)變量的算法。while用于判斷一個條件表達式,當條件成立的時候進入循環(huán)體,不滿足這個條件則不進入循環(huán)體。while語句的流程結(jié)構(gòu)如圖3-2所示。例3.3while語句應用實例。voidmain(){intj=1;intsum;while(j<=50){sum=sum+j;j++;}cout<<"sum="<<sum<<endl;}2)do-while語句do-while語句的格式如下:do循環(huán)體while(條件表達式);當流程到達do后,立即執(zhí)行循環(huán)體語句,然后對條件表達式進行測試,如滿足條件,則重復循環(huán),否則退出,該語句結(jié)構(gòu)至少使循環(huán)體執(zhí)行一次。do-while語句的流程結(jié)構(gòu)如圖3-3所示。圖3-3do-while語句的流程結(jié)構(gòu)例3.4do-while語句應用實例。#include<iostream.h>voidmain(){intj,sum=0;j=1;do{sum=sum+j;j++;}while(j<=50)

cout<<"sum="<<sum<<endl;}

例3.3和例3.4都是求sum=1+2+…+50的和的程序,它們使用了不同的循環(huán)控制語句,但結(jié)果是相同的。3)for語句for語句也可以用來控制循環(huán),for語句的格式如下:for(表達式1;表達式2;表達式3)循環(huán)體for語句的執(zhí)行過程如下:(1)求解表達式1;(2)求解表達式2,若為0則結(jié)束循環(huán)轉(zhuǎn)到(5);(3)若表達式2為真,則執(zhí)行循環(huán)體,然后求解表達式3;(4)轉(zhuǎn)回(2);(5)執(zhí)行for語句下面的語句。圖3-4for語句的流程結(jié)構(gòu)

for語句的流程結(jié)構(gòu)如圖3-4所示。在使用for語句時,并不是每個表達式都必須賦值,并且每個表達式都可以省略,但在省略表達式時,應該注意一些問題:在省略表達式1時,控制變量應該在使用之前的程序中被初始化;省略表達式2,即不進行判斷而使循環(huán)不停的進行下去,這樣在循環(huán)體中需要有跳出循環(huán)的控制語句,否則就會出現(xiàn)死循環(huán);在省略表達式3時,應該注意必須另外設法使循環(huán)控制變量變化,以保證循環(huán)能正常結(jié)束。不僅每個表達式可以單獨省略,而且它們可以同時省略。在省略表達式時,應注意表達式后面的分號不能省略。例3.5for語句應用實例。i=0;for(;i<=10;) //分號不能省略sum+=i++; //求值的同時改變循環(huán)變量//省略所有的表達式i=0;for(;;){sum+=i++; //求值的同時改變循環(huán)控制變量if(i>10) //控制結(jié)束條件break; //當i大于10時循環(huán)結(jié)束,跳出循環(huán)體}在本例中省略了表達式1和表達式3。4)switch語句當要實現(xiàn)多分支選擇語句時,就要用到switch語句。switch的格式如下:switch(表達式){case常量表達式1:執(zhí)行語句1case常量表達式2:執(zhí)行語句2

case常量表達式n:執(zhí)行語句ndefault:執(zhí)行語句n+1}

switch后面括號中的表達式只能是整型、字符型或枚舉類型。case后面的常量表達式必須與表達式匹配,如果不匹配,則在編譯時會出現(xiàn)錯誤。當表達式的值與某一個case后面常量表達式的值相等時,就執(zhí)行case后面的語句,若沒有與之匹配的常量表達式,則執(zhí)行default后的執(zhí)行語句。例3.6switch語句應用實例。#include<iostream.h>voidmain(){chargrade;cin>>grade;switch(grade){case'A':cout<<"85-100"<<endl;break;case'B':cout<<"70-84"<<endl;break;case'C':cout<<"60-69"<<endl;break;case'D':cout<<"<60"<<endl;break;default:cout<<"error"<<endl;}}在本例中,當輸入一個字符時如果它與A、B、C、D中的任何一個匹配,則輸出其后對應的語句;若不能與它們之中的任何一個匹配,則輸出default后的語句,即輸出出錯提示error。請讀者自行分析break語句的作用?,F(xiàn)在我們已經(jīng)了解了C++的基本語法,下面具體分析幾個例子。例3.7判明素數(shù)并輸出100內(nèi)中所有的素數(shù)。在判斷一個數(shù)m是否是素數(shù)時,就是檢驗它是否能被2~中的任意一個整數(shù)整除。如果存在一個數(shù)在范圍2~內(nèi)且能整除m,則m不是素數(shù);否則,m是素數(shù)。#include<iostream.h>#include<math.h>voidprime(longm){intsqrtm;sqrtm=sqrt(m);for(inti=2;i<=sqrtm;i++)if(m%i==0)break;if(sqrtm<i)cout<<m<<endl;elsecout<<m<<"itisnotaprime"<<endl;}voidmain(){longm;cout<<"inputthenumberm:"<<endl;cin>>m;

prime(m);for(intj=1;j<=100;j++)prime(j);}

函數(shù)prime()用來判斷一個數(shù)是否是素數(shù)。如果是,則輸出該數(shù);如果不是,則輸出“itisnotaprime”。在尋找1~100內(nèi)中的素數(shù)時,我們用了一個循環(huán)語言來控制輸入的數(shù)為1~100,然后判斷每個數(shù)是否為素數(shù)。例3.8猴子吃桃問題。猴子第一天摘下若干桃子,當即吃了一半,還不過癮,又多吃了一個。第二天早晨又將剩下的桃子吃掉一半,又多吃了一個。以后每天早上都吃了前一天剩下來的一半又多一個。這樣,到第10天早晨想再吃時,發(fā)現(xiàn)只剩下一個桃子了,問猴子第一天摘了多少個桃子。這個問題用程序能很輕易的解決,只需要用一個循環(huán)語句構(gòu)成的函數(shù)就可以實現(xiàn)。#include<iostream.h>intfn(intm){m=2*m;m++;returnm;}voidmain(){floatsum=1;for(inti=1;i<10;i++)sum=fn(sum);cout<<sum<<endl;}輸出結(jié)果為1023,這和用手工計算得到的值是一致的。在解決這個問題時,考慮到從第10天的桃子數(shù)起,以后每天的桃子數(shù)是后一天的2倍多一個,這樣就能用循環(huán)語句方便地解決這個問題。3.2.6函數(shù)

要編好程序,就要合理地劃分程序中的各個程序塊,即函數(shù)。C++程序是由函數(shù)組成的,一個C++程序由一個或若干個函數(shù)構(gòu)成,程序中的函數(shù)在程序運行時被調(diào)用,雖然main()也是函數(shù),但它并不是普通的函數(shù),它表示程序的入口。程序命令按照它們在源代碼中出現(xiàn)的順序一行行地順序執(zhí)行,直到遇到新的函數(shù)調(diào)用,然后程序分支去執(zhí)行函數(shù)調(diào)用。當函數(shù)調(diào)用完成時,程序控制立即返回調(diào)用函數(shù)下一行代碼。圖3-5C++程序中函數(shù)調(diào)用層次圖在C++中,一個函數(shù)必須在聲明后才能使用。函數(shù)聲明的作用是告訴編譯器,該函數(shù)是存在的。以后編譯器在遇到該函數(shù)被調(diào)用時就不會出錯了,同時編譯器還對函數(shù)調(diào)用進行正確性檢查。C++函數(shù)聲明總是由函數(shù)原型構(gòu)成的。

C++程序中函數(shù)調(diào)用的層次如圖3-5所示。1.函數(shù)原型

C++中的函數(shù)分為兩種:標準庫函數(shù)和用戶自定義的函數(shù)。標準庫函數(shù)在使用前可以用包含指令#include包含在頭文件中,而用戶自己定義的函數(shù)在使用前必須先聲明,即在使用前說明函數(shù)的原型。函數(shù)原型是一條程序語句,必須以分號結(jié)束。它由函數(shù)返回類型、函數(shù)名和參數(shù)構(gòu)成,其形式為返回類型function(參數(shù)表);參數(shù)表包含所有參數(shù)的數(shù)據(jù)類型,各參數(shù)之間用逗號分開。函數(shù)原型與函數(shù)定義在返回類型、函數(shù)名和參數(shù)表上必須完全一致。函數(shù)的返回值也稱為函數(shù)值,返回的不是函數(shù)本身而是一個值。我們經(jīng)常用return語句來返回函數(shù)的值。在使用函數(shù)時會涉及到變量的使用,在C++中變量的作用域和使用規(guī)則與C語言中是完全相同的,本書中不再贅述。2.函數(shù)的調(diào)用機制

C++中函數(shù)的調(diào)用過程就是??臻g操作的過程。在函數(shù)調(diào)用時,C++會進行如下操作:(1)建立被調(diào)用函數(shù)的??臻g;(2)保護調(diào)用函數(shù)的運行狀態(tài)和返回地址;(3)傳遞參數(shù);(4)將控制轉(zhuǎn)交給被調(diào)函數(shù)。例3.9函數(shù)調(diào)用實例。voidarea(int,int);voidsum(float,float);voidmain(){inta=4,b=5;area(a,b);sum(a,b);}在主函數(shù)調(diào)用兩個函數(shù)之前,先對這兩個函數(shù)的原型進行了聲明。主函數(shù)中調(diào)用了兩個函數(shù),其調(diào)用過程實際上就是一個對棧的操作過程。其他函數(shù)調(diào)用如遞歸調(diào)用在C語言中也有詳細的敘述。關(guān)于函數(shù)還應注意:任何函數(shù)之間不能嵌套定義,調(diào)用函數(shù)與被調(diào)用函數(shù)相互獨立,被調(diào)用函數(shù)和調(diào)用函數(shù)之間是靠參數(shù)傳遞和返回值來聯(lián)系的,函數(shù)被看作為一個黑盒。3.內(nèi)聯(lián)函數(shù)函數(shù)調(diào)用需要建立棧內(nèi)存環(huán)境,進行參數(shù)傳遞,并產(chǎn)生程序執(zhí)行轉(zhuǎn)移。這些工作都需要一定的時間開銷,若多次調(diào)用一個代碼很短的函數(shù),就會使程序的運行效率降低。為解決這個問題,應該使用內(nèi)聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)也稱為內(nèi)嵌函數(shù),是能提高程序的效率的一種特殊函數(shù)。內(nèi)聯(lián)函數(shù)用關(guān)鍵字inline來聲明,其具體的形式如下:

inline返回類型函數(shù)名(參數(shù)表){//函數(shù)體}在編譯時編譯器看到關(guān)鍵字inline后就為該函數(shù)創(chuàng)建一段代碼,在以后每次調(diào)用該函數(shù)時,都會用這段代碼來替代相應的函數(shù)。內(nèi)聯(lián)函數(shù)可以在一開始僅聲明一次。內(nèi)聯(lián)函數(shù)中不能含有復雜的結(jié)構(gòu)控制語句,如switch和while,若含有這些語句,在編譯時會將該函數(shù)視為普通函數(shù)一樣產(chǎn)生函數(shù)調(diào)用代碼;內(nèi)聯(lián)函數(shù)不能用作遞歸函數(shù)來使用;內(nèi)聯(lián)函數(shù)的返回值類型總是整型。例3.10內(nèi)聯(lián)函數(shù)舉例。#include<iostream.h>inlineintisnumber(charch){return(ch>='0'&&ch<='9')?1:0;}voidmain(){charc;while((c=cin.getc())!='\n') //cin.getc()是用于調(diào)用輸入對象的成員函數(shù){if(isnumber(c)) //調(diào)用一個小函數(shù)cout<<"youenteredadigit"<<endl;elsecout<<"youenteredanon-digit"<<endl;}}3.2.7函數(shù)的重載在C語言中,每個函數(shù)都必須有惟一的名字。為功能近似的問題定義函數(shù)時,不得不為這些既近似又有區(qū)別的問題定義多個函數(shù),為這些函數(shù)起不同的函數(shù)名。C++允許這些不同的函數(shù)使用相同的函數(shù)名。在函數(shù)調(diào)用時根據(jù)給定的實際參數(shù)自動匹配,究竟該調(diào)用哪一個函數(shù)。其匹配是嚴格按照這些函數(shù)定義時的參數(shù)類型、個數(shù)、順序來確定的。例3.11函數(shù)重載舉例。intabs(int);doubleabs(double);longabs(long);main(){abs(5); //自動匹配調(diào)用intabs(int)函數(shù)}這三個函數(shù)具有相同的名字,但它們的參數(shù)類型不相同。重載函數(shù)的匹配順序是靠將實參類型與所有被調(diào)用的具有相同函數(shù)名的函數(shù)的形參類型一一比較來判定的。它們在匹配時按以下的順序來尋找被匹配的函數(shù):(1)尋找一個嚴格的匹配,如果找到了,就用那個函數(shù);(2)通過內(nèi)部轉(zhuǎn)換尋求一個匹配,只要找到了,就用那個函數(shù);(3)通過用戶定義的轉(zhuǎn)換尋求一個匹配,若能查出有惟一的一組轉(zhuǎn)換,就用那個函數(shù)。在大多數(shù)情況下,函數(shù)的匹配是用尋找一個嚴格的匹配進行的。對于其它匹配,本書不述及。在匹配函數(shù)時,如果調(diào)用函數(shù)的實際參數(shù)與所有的重載函數(shù)在參數(shù)類型、參數(shù)個數(shù)、參數(shù)順序上都不相同,則認為不能匹配。編譯器無法分辨兩個完全一樣的重載函數(shù),因此重載函數(shù)應該在參數(shù)個數(shù)、參數(shù)類型或參數(shù)順序上有所不同。

C++是C的完善,因此C++繼承了C的許多知識點。數(shù)組、指針、引用、結(jié)構(gòu)體以及它們的使用范圍和使用方法,在C++中與C中是完全相同的。

C++除繼承C的所有知識外還有其自身的特點。正如前面章節(jié)所述及的,C++是支持多范型的語言。下面重點從實現(xiàn)面向?qū)ο蟮娜齻€主要特征來介紹C++的其他內(nèi)容。這三個主要特征為:(1)封裝;(2)繼承;(3)多態(tài)。3.2.8C++中的類學習了第1、2章,對類的概念已經(jīng)有了一個基本的了解,現(xiàn)在我們詳細描述C++類的語法,以及對類的一些簡單使用。

1.類的建立及其成員

C++中的類與C語言中的結(jié)構(gòu)體相似,類的定義方法如下:

classClassname

{//數(shù)據(jù)成員//成員函數(shù)

};其中,class為關(guān)鍵字,Classname為類名,在定義一個類時關(guān)鍵字和類名是必不可少的,一般用具有典型意義的名字來命名類。例如,定義一個學生類,可以用Student來命名。為編程的需要我們可以將類的成員定義成不同的存取屬性(public、private、protected),在后續(xù)章節(jié)我們將具體介紹各類存取屬性的使用范圍和使用方法。下面為大家介紹類的成員定義和類的作用域等。類似于函數(shù)聲明,類也有聲明,其形式如下:

classStudent;2.成員的定義在類中可以定義其數(shù)據(jù)成員和成員函數(shù),下面介紹類的成員的定義和使用。例3.12類的成員的定義和使用實例。#include<iostream.h>classStudent{

public:floatagre(floatmath,floatphy,floatEnglish,floatchinese){agv=(math+phy+English+chinese)/4;returnagv;}private:floatmath;floatphy;floatEnglish;floatchinese;floatagv;};在該例中我們定義了一個學生類,在類中又定義了一個成員函數(shù)agre()和5個成員變量。在定義成員函數(shù)和成員變量時,使用了兩個關(guān)鍵字public和private,它們分別將成員函數(shù)聲明為公有成員,將數(shù)據(jù)成員聲明為私有成員。在定義類的成員時,根據(jù)我們的需要可以用關(guān)鍵字private、public和protected來聲明成員的存取屬性。被private聲明后的成員,稱為私有成員,由該關(guān)鍵字聲明的成員僅被該類的成員函數(shù)調(diào)用;被protected聲明后的成員,稱為被保護成員,該成員除了能被該類的成員函數(shù)使用外,還有其他的用途;被public聲明后的成員,稱為公有成員,由它聲明的成員不僅能被該類的成員函數(shù)調(diào)用,而且還能被類外的函數(shù)調(diào)用。private聲明的成員和protected聲明的成員在這里沒有太大的區(qū)別,但在繼承中有較大的差別(詳見后續(xù)內(nèi)容)。3.類的作用域類的作用域是指類定義時一對花括號所形成的作用域。在該范圍內(nèi),類的成員對同一類的成員函數(shù)具有訪問權(quán)。類的所有成員位于這個類的作用域內(nèi)。類的所有成員是一個相關(guān)的整體,而類外的函數(shù)訪問類的作用域的成員時受到了限制。這種思想是把一個類的數(shù)據(jù)結(jié)構(gòu)和功能封裝起來,從而使得在類外訪問該類時,必須使用專用的接口(接口在這里指類中被public聲明為公有的成員函數(shù))。例3.13類的作用域舉例。classX{public:voidfn1(){n++;};voidfn2(){fn1();};intfn(){returnn;};private:intn;};4.類的封裝通過第1、2章的學習,我們了解了封裝的概念,下面用一個具體的實例來介紹封裝是怎樣實現(xiàn)的。例3.14對“點”(Point)的封裝。

classPoint //Point的類定義{

public: //外部接口voidset(doubleix,doubleiy);doublexoffset();doubleyoffset();doubleangle();doubleradius();private: //內(nèi)部數(shù)據(jù)doublex; //橫坐標doubley; //縱坐標};//Point類的成員函數(shù)定義#include<math.h>#definepi3.1415926voidPoint::set(doubleix,doubleiy){x=ix;y=iy;}doublePoint::xoffset(){returnx;}doublePoint::yoffset(){returny;}doublePoint::angle(){return(180/pi)*atan2(y,x);}doublePoint::radius(){returnsqrt(x*y+y*y);}每個成員函數(shù)前都加了類名。要使用這段代碼,應包含兩個頭文件,一個是point.h,因為所有成員函數(shù)的聲明都在類的定義中;另一個是math.h文件,因為在成員函數(shù)的定義中調(diào)用了math.h中聲明的函數(shù)。在本例中我們將數(shù)據(jù)和操作結(jié)合,構(gòu)成了一個不可分割的整體,即類。用這個類可生成具有不同屬性值的對象。類中的一些數(shù)據(jù)成員是私有的,它們被有效的屏蔽,外界不會對其產(chǎn)生干擾和誤操作;另一些成員(成員函數(shù))是公共的,它們作為接口提供給外界使用。5.構(gòu)造函數(shù)和析構(gòu)函數(shù)在OOP中,凡是創(chuàng)建的對象都需要作某種形式的初始化。為此需要構(gòu)造函數(shù)(ConstructorFunction),供創(chuàng)建類的實例對象時調(diào)用,用以自動完成對象的初始化。析構(gòu)函數(shù)(DestructorFunction)是與構(gòu)造函數(shù)相對應的一個概念,它用于釋放對象定義時通過構(gòu)造函數(shù)向系統(tǒng)申請的存儲空間以及有關(guān)的系統(tǒng)資源,它是在其有效范圍內(nèi)自動調(diào)用的。下面通過一個例子認識構(gòu)造函數(shù)和析構(gòu)函數(shù)。例3.15構(gòu)造函數(shù)和析構(gòu)函數(shù)舉例。classStack{chararray[size];int*tos;~Stack();public:Stack(); //這是一個構(gòu)造函數(shù)viodpush(char);charpop(cahr);};Stack::Stack()//說明函數(shù)所屬的類且與類名相同{cout<<"constructingastack"<<endl;tos=newint[10]; //分配堆空間}Stack::~Stack(){cout<<"destructingstack"<<endl;deletetos; //釋放堆空間}通過該例我們對構(gòu)造函數(shù)和析構(gòu)函數(shù)有了一個初步的認識,下面再來對它們進行詳細的討論。1)構(gòu)造函數(shù)的特性構(gòu)造函數(shù)是類的一個特殊的成員函數(shù),因此它除具有一般成員函數(shù)的受訪問限制、可重載等性質(zhì)外,還具有其自身的許多的特性:(1)構(gòu)造函數(shù)的名稱與它所屬的類名相同,在類對象被創(chuàng)建時自動調(diào)用,它不能用常規(guī)的方法調(diào)用,不能被繼承;

(2)構(gòu)造函數(shù)無返回類型(任何返回類型,包括void,都是非法的),不能帶有return語句;(3)一個類可以具有多個構(gòu)造函數(shù),重載時參數(shù)的個數(shù)或類型應不一樣,兩個具有相同參數(shù)類型和個數(shù)的構(gòu)造函數(shù)是非法的;(4)如果在編程時類中沒有顯式的定義構(gòu)造函數(shù),在編譯時系統(tǒng)會自動的生成一個不帶任何參數(shù)的構(gòu)造函數(shù);(5)構(gòu)造函數(shù)在調(diào)用時,控制成員變量的內(nèi)存分配,為定義的對象向系統(tǒng)申請內(nèi)存。

2)構(gòu)造函數(shù)的設計與使用類中的私有成員一般不作初始設置,需要在定義對象時初始化。采用顯式調(diào)用成員函數(shù)初始化對象容易遺漏,造成對象無意義,因此,使用構(gòu)造函數(shù)對對象進行初始化是最佳選擇。同時,一個類的不同對象需要有不同的初始化,因此可以采用帶參數(shù)的構(gòu)造函數(shù)和多構(gòu)造函數(shù)來解決這個問題。下面討論幾種構(gòu)造函數(shù)。(1)帶參數(shù)的構(gòu)造函數(shù)。例3.16帶參數(shù)的構(gòu)造函數(shù)舉例。classCourse{floatx,y;floatGDP;public:Course(ifloatox,floatoy);intGDP(floatx,floaty);};Course::Course(intx,inty){//以參數(shù)初始化變量

x=ox;y=oy;};intCourse::GDP(intx,inty){GDP=(x+y)/2;}voidmain(){CourseS(90,85);//定義對象時初始化S.GDP(90,85);}如果在定義對象S時不帶參數(shù),如CourseS;,那么,構(gòu)造函數(shù)就不能對x、y賦初值。構(gòu)造函數(shù)定義了缺省值,在函數(shù)調(diào)用時,若無特別指定參數(shù),便以缺省值作初始化,而且也可以防止遺漏初始賦值。缺省參數(shù)的構(gòu)造函數(shù)的用法與一般函數(shù)的用法相同。例如將上述函數(shù)改為帶缺省參數(shù)的構(gòu)造函數(shù)如下:classCourse{floatx,y;floatGDP;public:Course(intox=90,oy=85){x=ox;y=oy;}

};(2)多構(gòu)造函數(shù)(構(gòu)造函數(shù)重載)。對于一個類的不同對象,當其需要不同類型和不同個數(shù)的初始化參數(shù)時,可以在一個類中定義幾個構(gòu)造函數(shù),以適應不同的情況。例3.17多構(gòu)造函數(shù)舉例。

classCourse{public:Course();Course(float);Course(char,float);};voidmain(){Courseob1;Courseob2(78.5);Courseob3('M',87.5);}(3)復制構(gòu)造函數(shù)(CopyConstructor)。復制構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),它除了具有一般構(gòu)造函數(shù)所具有的性質(zhì)外,還具有一些特殊的性質(zhì):①具有將參數(shù)傳輸對象按位拷貝的功能。②編譯系統(tǒng)在編譯類時,產(chǎn)生一個缺省拷貝構(gòu)造函數(shù),例如,在main()中的語句

Courseob1('M',65.5);Courseob2(ob1);

對定義對象ob2,編譯系統(tǒng)自動調(diào)用缺省拷貝構(gòu)造函數(shù),實現(xiàn)對象的按位拷貝。ob2與ob1完全相同,但它們是兩個完全獨立的對象。③程序員也可以自己定義拷貝構(gòu)造函數(shù),定義格式如下:

classname(constclassname&obj){…}

其中,obj是引用對象,可以用于初始化其他對象,若有其他參數(shù),則在此后列出,若缺省,則這個引用對象不能省;const是習慣上的限定詞(即習慣上將被拷貝對象聲明為不可改寫),obj對象也可以不是const型。例3.18拷貝構(gòu)造函數(shù)舉例。classCourse{charx;flaoty;public:Course(charox,floatoy){x=ox;y=oy;}Course(constcourse&M){x=M.x;y=M.y;}

};voidmain(){Courseob1('M',67.5);Courseob2(ob1);}注意:如果類中包含有指針成員,那么就要慎用缺省的拷貝構(gòu)造函數(shù),因為編譯器提供的拷貝構(gòu)造函數(shù)只是簡單的按位拷貝成員數(shù)據(jù),它會使兩個對象的指針指向同一片內(nèi)存區(qū)域,而不是復制指針指向的內(nèi)容。若該內(nèi)存區(qū)是動態(tài)分配的,編程者有義務釋放它,但在釋放時會遇到麻煩,因為其中一個指針被釋放后,另一個指針所指的區(qū)域就失去了意義,這可能會導致嚴重的后果。3)析構(gòu)函數(shù)的特性和用法析構(gòu)函數(shù)是用于當對象離開其有效范圍時,釋放對象所占用的內(nèi)存空間的一個特殊函數(shù)。析構(gòu)函數(shù)也是成員函數(shù),它是與構(gòu)造函數(shù)相對應的,命名時在構(gòu)造函數(shù)名前加“~”。析構(gòu)函數(shù)只能是無返回類型,不能帶任何參數(shù),不能被重載,一個類只允許有一個析構(gòu)函數(shù)。析構(gòu)函數(shù)的定義一般是由一系列的delete組成的。例3.19析構(gòu)函數(shù)舉例。#include<iostream.h>#include<string.h>classsample{private:char*pointer_char;public:sample(){pointer_char=NULL;};sample(char*str){pointer_char=newchar[strlen(str)+1];strcpy(pointer_cahr,str);};sample(sample&ob){pointer_char=newchar[strlen(ob.pointer_char)+1];strcpy(pointer_char,ob.poiner_char);};~sample(){if(pointer_char!=NULL)deletepointer_char;};};3.2.9寫C++類代碼的相關(guān)基礎(chǔ)常識寫類代碼(主要考慮封裝性)會涉及到許多C++的語法知識細節(jié),本節(jié)敘述寫類代碼時應該理解的其中一些基礎(chǔ)C++知識。對于在C++中表現(xiàn)繼承性和多態(tài)性的內(nèi)容,在后幾節(jié)將進行討論。這些是面向?qū)ο蟪绦蛟O計的基礎(chǔ),要成為一個好的程序員,應對其有一定了解。1.const對象和const成員函數(shù)對對象的最低訪問權(quán)是良好軟件工程的一項基本原則。下面講述的就是這一原則在對象上的應用。某些對象是需要修改的,而有些對象是不需要修改的。可以在程序中用關(guān)鍵字const指明那些不允許修改的對象,任何試圖修改這種對象的嘗試都會導致編譯錯誤。例如:

constTimenoon(12,0,0);

聲明了類Time的一個const對象,并把該對象初始化成時針為12點的時間。用const聲明某個對象可強制實現(xiàn)最低訪問權(quán)原則。如果程序員不小心修改了這種對象,編譯器會發(fā)現(xiàn)這種錯誤,從而避免運行時的錯誤。盡管有的編譯器允許下列錯誤存在,但考慮到數(shù)據(jù)封裝的因素,在設計程序時應盡量避免下列錯誤:(1)定義一個const成員函數(shù),但該函數(shù)又修改了對象的數(shù)據(jù)成員;(2)定義一個const成員函數(shù),但該函數(shù)又調(diào)用了非const函數(shù);(3)const對象調(diào)用非const成員函數(shù);(4)試圖修改const對象。

const函數(shù)的聲明或定義規(guī)定必須使用關(guān)鍵字const,該關(guān)鍵字插在函數(shù)參數(shù)列表之后。例如,如下的成員函數(shù)被聲明為const成員函數(shù),它僅僅返回對象的一個數(shù)據(jù)成員的值:

intgetVuale()const{returnprivateDataMember;}如果在類的定義外部定義const成員函數(shù),那么該成員函數(shù)的定義也必須包含關(guān)鍵字const。

可以把非const成員函數(shù)重載為const成員函數(shù)。編譯器根據(jù)對象在聲明時是否使用了const來自動確定調(diào)用哪一個重載函數(shù)。由于為了能夠正確地初始化對象,構(gòu)造函數(shù)必須允許修改對象,析構(gòu)函數(shù)也必須要能夠做一些撤銷對象前的清理工作,因此,const對象的構(gòu)造函數(shù)和析構(gòu)函數(shù)不要用關(guān)鍵字const聲明。例3.20把不修改對象值的成員函數(shù)都聲明成const。classTime{public:Time(int=0,int=0,int=0);//默認構(gòu)造函數(shù)//"set"函數(shù)voidsetTime(int,int,int); //設置時間voidsetHour(int); //設置hour的值voidsetMinute(int); //設置minute的值voidsetSecond(int); //設置second的值//"get"函數(shù)intgetHour()const;//返回hour的值intgetMinute()const; //返回minute的值intgetSecond()const;//返回second的值//輸出函數(shù)(通常被聲明const成員函數(shù))voidprintMilitary()const; //輸出軍用格式的時間voidprintStandard()const; //輸出標準格式的時間private:

inthour;//0—23intminute;//0—59intsecond;//0—59};2.復合一個類可以把其他類的對象作為自己的成員,這就叫做復合。復合是軟件重用的一種形式。在建立對象的時候,其構(gòu)造函數(shù)自動被調(diào)用。如果一個對象有多個成員對象,那么這些成員對象應該以它們在該對象中的定義順序建立。但是,在編寫程序的時候,不應該編寫依賴于構(gòu)造函數(shù)調(diào)用順序的代碼。下面的程序用類Employee和Date演示了怎樣把對象變?yōu)槠渌麑ο蟮某蓡T。類Employee包括私有數(shù)據(jù)成員lastName、firstName、birthDate和hireDate。成員birthDate和hireDate是類Date的對象,它們包括私有數(shù)據(jù)成員month、day和year。程序建立了類Employee的一個對象,初始化并輸出了對象的數(shù)據(jù)成員。注意構(gòu)造函數(shù)頭部的語法形式:

Employee::Emplooyee(char*fname,char*lname,intbmonth,intbday,intbyear,inthmonthinthday,inthyear):birthDate(bmonth,bday,byear),hireDate(hmonth,hday,hyear)

這個構(gòu)造函數(shù)有8個參數(shù)(fname,lname,bmonth,bday,byear,hmonth,hday和hyear)。頭部的冒號用于把成員初始化值和參數(shù)列表分開。初始化值是Employee的構(gòu)造函數(shù)中傳遞給成員構(gòu)造函數(shù)的參數(shù)。因此,bmonth、bday和byear傳遞給了birthDate的構(gòu)造函數(shù),hmonth、hday和hyear傳遞給了hireDate的構(gòu)造函數(shù)。多個成員初始化值之間是用逗號分隔的。1)類Date的定義classDate{public:Date(int=9,int=1,int=2003); //默認構(gòu)造函數(shù)voidprint()const; //按格式"月/日/年"輸出日期private:intmonth; //1-12intday; //1-31(取決于月份)

intyear;

//任意年//根據(jù)年份和月份測試天數(shù)是否正確的工具函數(shù)

intcheckDay(int);};2)成員對象初始化值的用法//構(gòu)造函數(shù):檢查月份值的正確性//調(diào)用工具函數(shù)checkDay核對天數(shù)的正確性Date::Date(intmn,intdy,intyr){month=( mn>&&mn<=12)?mn:1;//檢驗正確性

year=y(tǒng)r; //也可以在這里檢驗正確性

day=checkDay(dy) //檢驗正確性

cout<<"Dateobjectconstructorfordate";print();cout<<endl;}3)檢驗天數(shù)正確性的工具函數(shù)intDate::checkDay(inttestDay){staticintdaysPerMonth[13]={0,31,28,31,30,31,30,31,30,31,30,31};if(month!=2){if(testDay>0&&testDay<=dayPerMonth[month])returntestDay;}else{//檢查是否是閏年intdays=(year%400==0||year%4==0&&year%100!=0)?29:28);if(testDay>&&testDay<=days)returntestDay;}cout<<"Day"<<testDay<<"invalid.Settoday1.\n";retrun1; //在值有誤的情況下讓對象處于穩(wěn)定狀態(tài)}4)以“月/日/年”的形式輸出對象DatevoidDate::print()const{cout<<month<<'/'<<day<<'/'<<year;}5)成員對象初始化值的用法之一classEmployee{public:Employee(char*,char*,int,int,int,int,int,int);voidprint()const;private:

charlastName[25];charfirstName[25];DatebirthDate;DatehireDate;};6)成員對象初始化值的用法之二Employee::Employee(char*fname,char*lname,intbmonth,intbday,intbyear,inthmonth,inthday,inthyear):birthday(bmonth,bday,byear),hireDate(hmonth,hday,hyear){strncpy(firstName,fname,24);firstName[24]='\

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論