在日常學(xué)習(xí),、工作或生活中,,大家總少不了接觸作文或者范文吧,通過文章可以把我們那些零零散散的思想,,聚集在一塊,。寫范文的時候需要注意什么呢,?有哪些格式需要注意呢?接下來小編就給大家介紹一下優(yōu)秀的范文該怎么寫,,我們一起來看一看吧,。
c++24點游戲代碼 24點游戲百科篇一
二、選擇題(每小題2分,,共20分)
1.假設(shè)已經(jīng)有定義char *const pname=”student”;下面的語句正確的,。
a.pname[3]=’t’;=”score”;
=new char[5];=new char(‘p’);
2.在下面有關(guān)對構(gòu)造函數(shù)的描述中,正確的a.構(gòu)造函數(shù)可以帶有返回值
b.構(gòu)造函數(shù)的名字與類名完全相同
c.構(gòu)造函數(shù)必須帶有參數(shù)
4.構(gòu)造函數(shù)必須定義,,不能缺省
3.在下面有關(guān)析構(gòu)函數(shù)特征的描述中,,錯誤的。
a.一個類中只能定義一個析構(gòu)函數(shù)
b.析構(gòu)函數(shù)名與類名完全相同
c.析構(gòu)函數(shù)不能指定返回類型
d.析構(gòu)函數(shù)不能帶有參數(shù)
4.假定ab為一個類,,則執(zhí)行“aba(4), b[3] , * p[2];”語句時,,自動調(diào)用該類構(gòu)造函數(shù)的次數(shù)為。
a.3b.4c.6d.9
5.假定要對類ab定義加號操作符重載成員函數(shù),,實現(xiàn)兩個ab類對象的加法,,并返回相加結(jié)果,則該成員函數(shù)的聲明語句為,。
operator+(ab&a,ab&b)ator+(ab&a)
or+(aba)& operator+()
6.假設(shè)定義了函數(shù)模版:
template
t max(t x, t y){return(x>y)?x:y;}并定義了:int i,;char c;那么下列錯誤的調(diào)用該模版的是。
a.max(i,i);b.max(c,c);
c.max(int(c),i);d.max(c,i);
7.模版的主要用途是為,。
a.提高代碼的運行效率
b.實現(xiàn)多態(tài)性
c.提高代碼的重用性
d.加強類的封裝性
8.下列說法錯誤的,。
a.申明為指向基類對象的指針可以指向它的公有派生的對象,,但不允許指向它的私有派生的對象
b.允許將一個聲明為指向基類的指針指向其公有派生類的對象,但是不能將一個聲明為指向派生類對象的指針指向其基類的一個對象,。
c.聲明為指向基類對象的指針,,當(dāng)其指向公有派生類對象時,只能用它來直接訪問派生類中從基類繼承來的成員,,而不能直接訪問公有派生類中定義的成員
d.以上說法都不對
9.現(xiàn)有程序如下:
#include
#include void main(){int kk=1234;
cout<
cout<
}
以上程序的運行結(jié)果是,。
a.1234b.**1234c.**1234d.以上都不對
12341234**123
410.在公有繼承的情況下,基類成員在派生類中的訪問權(quán)
a.受限制b.保持不變c.受保護(hù)d.不受保護(hù)
1.1.三,、填空題(每空1分,,共10分)假定類ab中有一個公有屬性的靜態(tài)數(shù)據(jù)成員bb,在類外不通過對象名訪問該成員bb的寫法為(1),。
通常情況下,,當(dāng)創(chuàng)建派生類對象時,首先執(zhí)行(2)的構(gòu)造函數(shù),,隨后再執(zhí)行(3)的構(gòu)造函數(shù),,當(dāng)撤銷派生類對象時,則先執(zhí)行(4)的析構(gòu)函數(shù),,隨后再執(zhí)行(5)的析構(gòu)函數(shù),。
ios類中有幾個成員函數(shù)可以用來對輸入輸出進(jìn)行格式化控制,格式控
制主要是通過對(6)的操作來完成的,。
所謂賦值兼容規(guī)則是指在需要基類對象的任何地方都可以使
用(7)來替代,。
純虛函數(shù)是一個在基類中說明卻沒定義的虛函數(shù),但要求在它的派生類
中必須定義自己的版本,,或重新說明為純虛函數(shù),。那么,,純虛函數(shù)的定義形式為(8),。2.3.4.5.6.分別寫出類ab的單目運算符”++”的前綴方式和后綴方式的友元函數(shù)重載一般形式:(9)、(10),。
2.四,、寫出下面程序的運行結(jié)果(每小題5分,共20分)
1,、#include
class myclass{public:
myclass(){}
myclass(int a, int b, int c);
void getnumber();
void getsum();
private:
int x,y,z;
static int sum;
};
int myclass::sum=0;
myclass::myclass(int a, int b, int c){
x=a;y=b;z=c;
sum+=x+y+z;
}
void myclass::getnumber(){
cout<<“number=”<
}
void myclass::getsum(){
cout<<“sum=”<
}
void main(){
myclass m(3,7,10);
ber();
();
myclass n(14,9,11);
ber();
();
();
}
2,、#include
class tdate1{public:
tdate1(int y,int m, int d);
~tdate1();
void print();
private:
int year, month,day;
};
tdate1::tdate1(int y,int m,int d){
year=y;
month=m;
day=d;
cout<<“contructor called.n”;
}
tdate1::~tdate1(){
cout<<“destructor called.n”;
}
void tdate1::print(){
cout<
}
void main(){
tdate1 today(2005,7,1),tomorrow(2005,7,2);
cout<<“today is ”;
();
cout<<“tomorrow is ”;
();
}
3、#include
class date{public:
date(){
cout<<“date called.”<
}
private:
unsigned int year, month, day;
};
class employee{
public:
employee(){
cout<<“employee called.”<
}
private:
date birthday;
};
class manager: public employee{
public:
manager(){
cout<<“manager called.”<
}
private:
unsigned int allowance;
};
int main(){
manager susan;
return 0;
}
4,、#include
class complex{public:
complex(int r,int i):real(r),imag(i){}
friend complex operator++(complex);
friend complex operator--(complex &);
void print(){
cout<<“(”<
}
private:
int real,imag;
};
complex operator++(complex o){
++;
++;
return o;
}
complex operator--(complex &o){
--;
--;
return o;
}
void main(){
complex obj(10,20),obj_b(30,40);
++obj;
();
--obj_b;
();
}
1.五,、編程題(每小題10分,共30分)
1,、構(gòu)建一個類book,,其中含有兩個私有數(shù)據(jù)成員qu和price,,建立一個有5個元素的對象數(shù)組,將qu初始化為1~5,,將price初始化為qu的10倍,。顯示每個對象的qu*price。
2,、編寫一個程序,,用成員函數(shù)重載運算符“+”和“-”將兩個二維數(shù)組相加和相減,要求第一個二維數(shù)組由構(gòu)造函數(shù)設(shè)置,,另一個二維數(shù)組的值由鍵盤輸入,。
3、寫一個函數(shù)模板,,求數(shù)組中的最大元素,。使得函數(shù)調(diào)用時,數(shù)組類型和返回類型可以是整數(shù)也可以是雙精度類型,。
1.一,、簡答題(每小題5分,共20分)
1.答:類就是相同的數(shù)據(jù)和相同的一組對象的集合,,即,,類是對具有相同數(shù)據(jù)結(jié)構(gòu)和相同操作的一類對象的描述;對象是描述其屬性的數(shù)據(jù)以及對這些數(shù)據(jù)施加的一組操作封裝在一起構(gòu)成的統(tǒng)一體,,對象可以認(rèn)為是:數(shù)據(jù)+操作,;類和對象之間的關(guān)系是抽象和具體的關(guān)系。
2.答:構(gòu)造函數(shù)主要用于為對象分配空間,,進(jìn)行初始化,。構(gòu)造函數(shù)除了具有一般成員函數(shù)的特征外,還具有一些特殊的性質(zhì):(1)構(gòu)造函數(shù)的名字必須與類名相同(2)構(gòu)造函數(shù)可以有任意類型的參數(shù),但不能指定返回類型,。它有隱含的返回值,該值由系統(tǒng)內(nèi)部使用。(3)構(gòu)造函數(shù)是特殊的成員函數(shù),函數(shù)體可寫在類體內(nèi),也可寫在類體外,。(4)構(gòu)造函數(shù)可以重載,即一個類中可以定義多個參數(shù)個數(shù)或參數(shù)類型不同的構(gòu)造函數(shù),。(5)構(gòu)造函數(shù)被聲明為公有函數(shù),但它不能像其他成員函數(shù)那樣被顯式地調(diào)用,它是在定義對象的同時被調(diào)用的。
析構(gòu)函數(shù)也是一種特殊的成員函數(shù),。它執(zhí)行與構(gòu)造函數(shù)相反的操作,通常用于撤消對象時的一些清理任務(wù),如釋放分配給對象的內(nèi)存空間等。析構(gòu)函數(shù)有以下一些特點:(1)析構(gòu)函數(shù)與構(gòu)造函數(shù)名字相同,但它前面必須加一個波浪號(~);(2)析構(gòu)函數(shù)沒有參數(shù),也沒有返回值,而且不能重載,。因此在一個類中只能有一個析構(gòu)函數(shù);(3)當(dāng)撤消對象時,編譯系統(tǒng)會自動地調(diào)用析構(gòu)函數(shù),。
答:略.詳見教材p151.4.答:略.詳見教材p192.二、選擇題(每小題2分,,共20分)
1~10.a(chǎn)bbbbccdbb
1.三,、填空題(每空1分,共10分)
(1)ab::bb(2)基類(3)派生類(4)派生類(5)基類(6)狀態(tài)標(biāo)志字(7)公有派生類對象(8)virtual 函數(shù)類型 函數(shù)名(參數(shù)表)=0;(9)ab operator++();(10)ab operator++(int);
1.四,、寫出下面程序的運行結(jié)果(每小題5分,,共20分)
1.number=3,7,10
sum=20
number=14,9,11
sum=54
sum=54
2.contructor ctor is 2005.7.1
tomorrow is 2005.7.2
destructor ctor called.3.date ee r called.4.(10,20)
(29,39)
c++24點游戲代碼 24點游戲百科篇二
1類和對象之間的關(guān)系
類是對某一類對象的抽象;對象是某一種類的實例,、類的定義方法
class類名{ private:私有數(shù)據(jù)成員和成員函數(shù)public:公有數(shù)據(jù)成員和成員函數(shù) },;
類中成員的訪問權(quán)限
對于public類成員來說,他們是共有的,,能被外面的程序訪問:@對于private類成員來說,,他們是私有的,只能被類中的函數(shù)所使用,,不能被外面的程序所訪問,。對象成員的訪問方法 訪問對象的成員變量,@成員函數(shù)和訪問變量和函數(shù)的方法是一樣的,,只不過要在成員前面加上對象名和成員運算符“.”表示方式如下
<對象名>.<成員變量><對象名>.<成員函數(shù)>(<參數(shù)表>)運作有關(guān),,如創(chuàng)建窗口,繪制窗口,,銷毀窗口,通常,,消息是從系統(tǒng)發(fā)到窗口,,或從窗口發(fā)到系統(tǒng)。
命令消息:命令消息通常與處理用戶請求有關(guān),,當(dāng)用戶單擊一個菜單或工具欄時,,命令消息就產(chǎn)生了。并發(fā)送到能處理該消息的類或函數(shù),。
控件消息:由控件產(chǎn)生的消息,,例如,按鈕的單擊,列表框的選擇等均產(chǎn)生此類消息,,為的是向其父窗口通(通常是對話框)通知事件的發(fā)生,。
6.使用一個對話框的一般過程: ①添加對話框資源; ②設(shè)置對話框的屬性,; ③添加和布局控件,; ④創(chuàng)建對話框類; ⑤添加對話框代碼,; ⑥在程序中調(diào)用對話框,。7模式對話框和無模式對話框
1.什么是類?類的定義格式?類的成員一般分為哪兩部分?它們的區(qū)別如何?
⑴“類”是對具有共同的屬性特征和行為特征的對象的概括和抽象。
⑶類的成員一般分為數(shù)據(jù)成員和成員函數(shù)兩部分,。
⑷數(shù)據(jù)成員一般用來表示對象屬性特征,,而成員函數(shù)一般表示了對象的可以進(jìn)行的操作,即行為特征,。
3.什么是對象?如何定義一個對象?對象的成員如何表示?
⑴對象是類的實例,,是類的變量。⑵對象的定義:類名對象名稱;或:類名 * 對象指針;⑶對象成員的表示:對象名稱.成員名字;或: 對象指針→成員名字;9.如何對對象進(jìn)行初始化?
對象的初始化都是通過構(gòu)造函數(shù)進(jìn)行的,,只要在聲明對象時,,逐個添好構(gòu)造函數(shù)的實運算符重載。(2)運行時的多態(tài)性:虛函數(shù),。即在程序執(zhí)行之前,,根據(jù)函數(shù)和參數(shù)無法確定應(yīng)該調(diào)用哪個函數(shù),必須在程序的執(zhí)行過程中,,根據(jù)執(zhí)行情況動態(tài)的確定,。第3章mfc基本應(yīng)用程序的建立4.用appwizard創(chuàng)建一個多文檔應(yīng)用程序項目(mdi)ex_mdihello,比較mdi與sdi有哪些區(qū)別?
sdi應(yīng)用程序由應(yīng)用程序類(cwinapp),、框架窗口類(cframewnd),、文檔類(cdocument)、視圖類(cview)和文檔模板類(csinsledoctemplate)共同作用,。mdi應(yīng)用程序與sdi應(yīng)用程序的主要差別在于:mdi有cmdiframewnd和cmdichildwnd兩個框架窗口類,,前一個派生cmainframe類,,負(fù)責(zé)菜單等界面元素的主框架窗口管理,;后一個派生cchildframe類,,負(fù)責(zé)相應(yīng)的文檔及其視圖的子框架窗口維護(hù)。而sdi由框架窗口類cframewnd派生cmainframe類,。輯文本的矩形窗口,。編輯框?qū)儆赾edit類的鍵盤快捷鍵也稱為加速鍵,加速鍵一般是幾“窗口控件”,,可以獲得輸入焦點,。個按鍵的組合,用于激活特定的命令,。12.什么是列表框和組合框?它們的通知消息用ctrl+r進(jìn)入資源編輯器,,選擇accelerator有何異同? 的資源項,雙擊idr_mainframe,,進(jìn)行加列表框控件提供了文本項目的列表供用戶選速鍵資源的添加,。擇,可以單選也可以多選,。列表框是clistbox8.狀態(tài)欄的作用是什么?狀態(tài)欄的窗格分為類的,;組合框可以看成是編輯框和列表框的幾類?如何添加和減少相應(yīng)的窗格? 組合,它提供了列表框,,允許用戶從中選擇⑴狀態(tài)欄是一條位于應(yīng)用程序的主窗口底部項目,;也提供了編輯框,允許用戶直接輸入,,的水平條,,可以分割成幾個窗格,用來顯示它是ccombobox類的,。應(yīng)用程序的當(dāng)前狀態(tài)信息或提示信息,。這兩個控件發(fā)送的都是通知消息⑵狀態(tài)欄窗格分為“信息行窗格”和“指示器(wm_notify)。當(dāng)列表框中發(fā)生了某個動窗口”,。作,,比如雙擊了列表框中某項時,列表框就⑶要增加一個信息行窗格,,則只需在狀態(tài)欄會向其父窗口發(fā)送一條通知消息,;而在組合數(shù)組中適當(dāng)?shù)奈恢迷黾右粋€框的通知消息中,有的是列表框發(fā)出的,,有id_separator標(biāo)識即可,;要增加指示器窗的是編輯框發(fā)出的。格,,則在狀態(tài)欄數(shù)組的適當(dāng)位置增加一個在14.什么是滾動條,、進(jìn)展條,、滑動條和旋轉(zhuǎn)“字符串表”中定義過的資源id。若要減少窗按鈕控件? 格,,只需減少數(shù)組元素即可,。⑴滾動條:是csrollbar類的控件,它有一個9.如何在狀態(tài)欄的窗格顯示文本? 構(gòu)造函數(shù)和析構(gòu)函數(shù)
⑴模式對話框:所謂的模式對話框是指對話構(gòu)造函數(shù)是類的成員函數(shù),,功能是在創(chuàng)建對框彈出時,,用戶必須向?qū)υ捒蜻M(jìn)行相應(yīng)的操象時,實用給定的值將對象初始化,。它有以作,,在退出對話框之前,其所在的應(yīng)用程序下特點:
是不能往下執(zhí)行的,。
構(gòu)造函數(shù)的名字必須與類名相同,。
⑵無模式對話框:無模式對話框是指對話框構(gòu)造函數(shù)可以有任意的形參,但不能具有返彈出后,,一直保留在屏幕上,,用戶可以在對回值。
話框所在的應(yīng)用程序中進(jìn)行其他的操作,。定義對象時,,編譯系統(tǒng)會自動地調(diào)用構(gòu)造函兩種對話框在編輯器設(shè)計和使用
數(shù)。
classwizard進(jìn)行編程時方法基本一致,,但在構(gòu)造函數(shù)可以重載
創(chuàng)建和退出對話框窗口時的方式不同,。析構(gòu)函數(shù)也是類的成員函數(shù),功能是用于釋在創(chuàng)建時,,模式對話框是由系統(tǒng)自動分配內(nèi)放一個對象,,在對象刪除前,用它來做一些存空間,,因此在對話框退出時,,對話框?qū)ο髢?nèi)存釋放等清理工作,與構(gòu)造函數(shù)功能相自動刪除,。而無模式對話框則需要用戶來指反,。,它有以下特點:
定內(nèi)存,,退出時還要自己刪除對話框?qū)ο?。析?gòu)函數(shù)名也應(yīng)與類名相同,只是在函數(shù)名在退出時,,兩種對話框所用的終止函數(shù)不一前面加一個波浪符~,。
樣。模式對話框通過調(diào)用
析構(gòu)函數(shù)不能帶任何參數(shù),,也沒有返回值,。cdialog::enddialog來終止,,而無模式對話每個類有而且只能有一個析構(gòu)函數(shù)。析構(gòu)函框則是通過調(diào)用cwnd::destroywindow來終數(shù)不能重載,。
止,。
清理內(nèi)存空間時,會自動地調(diào)用析構(gòu)函數(shù) 8.靜態(tài)控件的類型單繼承和派生類的構(gòu)造函數(shù)與析構(gòu)函數(shù) 靜態(tài)文本組框靜態(tài)圖片 基類的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被派生類繼9.按鈕的分類,、消息
承
按鈕控件是cbutton類的控件,。
派生類對象在建立時,,先執(zhí)行基類構(gòu)造函數(shù),,按鍵按鈕 單選按鈕 復(fù)選框按鈕(復(fù)選框的再執(zhí)行派生類構(gòu)造函數(shù)。析構(gòu)函數(shù)執(zhí)行順序外形是在文本前有一個空心方框,,當(dāng)它被選與構(gòu)造函數(shù)相反,,先執(zhí)行派生類析構(gòu)函數(shù),中時,,復(fù)選框中就加上一個標(biāo)記,,通常再執(zhí)行基類的析構(gòu)函數(shù)。復(fù)選框只有選中和未選中兩種狀態(tài),,若復(fù)選兩種多態(tài)性
框前面有一個是灰色,,則這樣的復(fù)選框編譯時的多態(tài)性和運行時的多態(tài)性。編譯時是三態(tài)復(fù)選框,,它表示復(fù)選框的選擇狀態(tài)是的多態(tài)性是通過函數(shù)的重載或運算符的重載“不確定”,。)
來實現(xiàn)的。運行時的多態(tài)性是通過虛函數(shù)來bn_clicked(單擊按鈕)
實現(xiàn)的,,它是只在程序執(zhí)行前,,根據(jù)函數(shù)和bn_double-clicked(雙擊按鈕)參數(shù)還無法確定應(yīng)該調(diào)用哪一個函數(shù),date函數(shù)
在程序的執(zhí)行過程中,,根據(jù)執(zhí)行情況動態(tài)地updatedata 函數(shù)只有一個true或false的確定,。
參數(shù)。當(dāng)調(diào)用updatedata(false)時,,s的應(yīng)用程序特點有哪些?由控件相關(guān)聯(lián)的成員變量向控件傳輸,,當(dāng)調(diào)消息驅(qū)動機制
用updatedata(true)或不帶參數(shù)的圖形設(shè)備接口(gdi)updatedata時,數(shù)據(jù)由控件向相關(guān)聯(lián)的成員基于資源的程序設(shè)計 變量復(fù)制,。
動態(tài)鏈接庫
11,、工具欄和菜單項的結(jié)合方法
進(jìn)程和線程 的appwizard(exe)提供了哪幾種類型樣即可。的應(yīng)用程序?
12,、狀態(tài)欄的設(shè)定方法
(1)單文檔界面的應(yīng)用程序(sdi,,single 用mfc appwizard創(chuàng)建的單文檔和多文檔應(yīng)document interface);
用程序框架中,,有一個靜態(tài)的indicators數(shù)(2)多文檔界面的應(yīng)用程序(mdi,,multiple 組,,文件中定義的,被documents interface),;
mfc用作狀態(tài)欄的定義(3)基于對話框的應(yīng)用程序(dialog ),。
要增加一個信息行窗格,應(yīng)用程序項目組織:dsp 項目文件 dsw 組中適當(dāng)?shù)奈恢迷黾右粋€id_separator標(biāo)識項目工作區(qū)文件 cppc++文件,,c++頭文件 即可,;要增加指示器窗格,則在狀態(tài)欄數(shù)組工作區(qū)窗口的標(biāo)簽頁面:classview頁 的適當(dāng)位置增加一個在“字符串表”中定義resourceview頁和fileview頁 過的資源id,。若要減少窗格,,程序類結(jié)構(gòu)
元素即可。
對話框類caboutdlg 應(yīng)用程序類2.如何在狀態(tài)欄的窗格顯示文本?(3種)cex_sdihelloapp應(yīng)用程序文檔類1.)調(diào)用cwnd::setwindowtext更新信息行cex_sdihellodoc
窗格(或窗格0)中的文本 應(yīng)用程序視圖類cex_sdihelloview2.)手動處理狀態(tài)欄的cmainframe類(用于負(fù)責(zé)主框架窗口的顯示on_update_commadnd_ui更新消息,,并在處理和管理)
函數(shù)中調(diào)用ccmdui::setpanetext函數(shù),。5.消息的分類有哪些:
3.可以調(diào)用cstatusbar::setpanetext函數(shù)標(biāo)準(zhǔn)(窗口)消息:窗口消息一般與窗口內(nèi)部更新任何窗格中的文本.(通用)參。
20.派生類是如何定義的?它有哪些特點?⑴定義派生類的一般形式為:
class派生類名:[引用權(quán)限] 基類名{派生類新增的數(shù)據(jù)成員
派生類新增的成員函數(shù)};
⑵派生類繼承了基類的所有數(shù)據(jù)成員和成員函數(shù),,并增加新的成員,。
21.派生類的繼承方式有哪些?它們各有哪些特點?
①當(dāng)引用權(quán)限為public時,稱為“公用派生類”,。在公用派生類中,,基類的public成員和protected成員仍然成為派生類中的public成員和protected成員;然而基類中的私有成員卻成為了派生類中的“不可訪問的成員”,,不能被派生類使用,。
②當(dāng)引用權(quán)限為private時,稱為“私有派生類”,。在私有派生類中,,基類的公用成員和保護(hù)成員成為了派生類中的私有成員,基類的私有成員成為派生類“不可訪問的成員”,。③從以上兩點可以看出,,基類中的私有成員在派生類中都成為了“不可訪問的成員”。因此在繼承中經(jīng)常使用另外一種封裝字protected,,被protected封裝的成員稱為“保護(hù)成員”,,保護(hù)成員和私有成員相似,不能被外界引用,,但它卻可以被派生類的成員函數(shù)引用,。
22.在定義派生類的過程中,如何對基類的數(shù)據(jù)成員進(jìn)行初始化?
基類的數(shù)據(jù)成員初始化往往是通過基類的構(gòu)造函數(shù)進(jìn)行的,,但是在么在建立派生類的對象時,,是不會自動執(zhí)行基類的構(gòu)造函數(shù),因而就會使基類中成員變量未初始化,。所以在設(shè)計派生類的構(gòu)造函數(shù)時,,不僅要考慮派生類所增加的成員變量初始化,,還應(yīng)當(dāng)考慮基類的成員變量初始化。在執(zhí)行派生類的構(gòu)造函數(shù)時,,應(yīng)當(dāng)調(diào)用基類的構(gòu)造函數(shù),。
因此考慮到基類成員變量初始化后,派生類的構(gòu)造函數(shù)一般形式為:
派生類構(gòu)造函數(shù)名(參數(shù)表):基類構(gòu)造函數(shù)名(參數(shù)表)
23.在派生類中能否直接訪問基類中的私有成員?在派生類中如何實現(xiàn)訪問基類中的私有成員?
在派生類中是不能直接訪問基類中的私有成員的,,要在派生類中訪問基類中的私有成員,,只能通過基類所提供的public或protected封裝的成員函數(shù)進(jìn)行。
24.什么是虛基類?它的作用如何?
在聲明派生類時,,在基類的引用權(quán)限前面加上virtual,,就將基類聲明成了虛基類,即:class 派生類名:virtual [引用權(quán)限]基類名虛基類的引入主要是針對多重派生的,,是為了消除派生類的二義性使用的,。通過虛基類派生出來的新類,,同一個成員變量在不同的派生類中都只有一個復(fù)制,,當(dāng)通過普通基類派生的新類,同一個成員變量,,在不同的派生類中的副本是不一樣的,。
25.多態(tài)性:不同類型的對象接收相同的信息時產(chǎn)生不同的行為。例如函數(shù)重載,。
分類:(1)編譯時的多態(tài)性:函數(shù)重載或第4章對話框及常用控件
1.什么是對話框?它分為哪兩類?這兩類對話框有哪些不同?
(2)對話框是cdialog類的派生類,,它的主要功能是輸出信息和接收用戶的輸入。對話框是一個特殊類型的窗口,,任何對窗口的操作都可以在對話框中進(jìn)行,。對話框與控件是密不可分的,在每個對話框內(nèi)一般都有一些控件,,對話框依靠這些控件與用戶進(jìn)行交互,。2.什么是對話框模板、對話框資源和對話框類?
⑴對話框模板:mfc develop studio提供的對話框模板是用來創(chuàng)建用戶對話框資源,,用對話框模板創(chuàng)建的基本界面上,,包括一個ok(確定)按鈕和一個cancel(取消)按鈕等??梢砸苿?、修改、刪除這些控件,,或者是增加新的控件到對話框模板,,構(gòu)成應(yīng)用程序所需的對話框資源。
⑵對話框資源:對話框資源是一個用戶輸入或取得數(shù)據(jù)的圖形界面,。這個圖形界面是使用
對話框編輯器在對話框模板上創(chuàng)建的,,程序員可以在對話框模板上增加并編輯控件,,生成對話框資源。當(dāng)應(yīng)用程序運行時,,就可以得到一個對話框,。⑶對話框?qū)ο?/p>
mfc使用cdialog類來描述對話框,它是cwnd類的派生類,。在cwnd類的基礎(chǔ)上增加了數(shù)據(jù)交換的功能,。當(dāng)創(chuàng)建一個新的對話框資源后,使用classwizard可以創(chuàng)建一個對話框類的派生類,。對話框?qū)ο髮崿F(xiàn)了對話框和應(yīng)用程序之間的通信,。在應(yīng)用程序中定義一個對話框?qū)ο蠛螅趯υ捒蜿P(guān)閉后,,可以通過訪問對話框?qū)ο蟮某蓡T變量獲得用戶的輸入數(shù)據(jù),。
4.什么是控件?根據(jù)控件的性質(zhì)可以將控件分為幾類?
控件是系統(tǒng)內(nèi)部定義的能完成特定功能的一些組件,控件能夠放置在一個對話框中,,提供應(yīng)用程序與用戶交互的某種功能的類,,根據(jù)控件的特性和功能,一般可以將其分為3類:windows通用控件,、activex控件以及mfc新增控件,,windows通用控件一般都是從cwnd派生而來的。6.什么是ddv/ddx技術(shù)?如何使用這種技術(shù)?
為了能方便地操作一個控件,,mfc采用了獨特的ddx(dynamic data exchange,,動態(tài)數(shù)據(jù)交換)和ddv(dynamic data verify,動態(tài)數(shù)據(jù)交換)技術(shù),。ddx將數(shù)據(jù)成員變量與對話類模板內(nèi)的控件相連接,,這樣使得數(shù)據(jù)在控件之間很容易傳輸。ddv用于數(shù)據(jù)的校驗,,它能自動校驗數(shù)據(jù)成員變量數(shù)值的范圍,,并給出警告。
7.什么是控件的通知消息?它在編程中起哪些作用?
當(dāng)控件狀態(tài)發(fā)生改變時,,控件就會向其父窗口發(fā)送消息,,這就是控件的通知消息??丶耐ㄖ⒖梢允且粭lwm_command消息,,也可以是一條wm_notify消息。9.什么是編輯框控件?它有哪些功能?
編輯框是一個允許用戶從鍵盤輸入數(shù)據(jù)和編獨立的窗口,,兩端有兩個箭頭按鈕,,中間有一個可移動的滾動塊,具有直接的輸入焦點,分為垂直滾動條和水平滾動條兩種類型,。⑵進(jìn)展條:用于說明一個操作的進(jìn)度,,在操作過程中不斷地從左到右填充進(jìn)展條,可以讓用戶看到還有多少任務(wù)要完成,。⑶滑動條:由滑動塊和可選的刻度線組成的,,它是csliderctrl 類的。⑷旋轉(zhuǎn)按鈕控件:是cspinbuttonctrl類的,,由一對箭頭按鈕組成,,它通常與一個相伴的控件一起使用。15.什么是旋轉(zhuǎn)按鈕的“伙伴”控件?如何設(shè)置? 與旋轉(zhuǎn)按鈕控件一起使用的控件稱為“伙伴(buddy)控件”,,單擊旋轉(zhuǎn)按鈕控件的箭頭按鈕,,可以增大或減小其伙伴控件中某個值?;锇?buddy)控件的設(shè)置有兩種方法: ①setbuddy:設(shè)置旋轉(zhuǎn)控件的伙伴窗口,。②在對話框中用ctrl+d進(jìn)行設(shè)置
16.在mfc中,通用對話框有哪些?如何在程序中使用它們?
windows提供了一組標(biāo)準(zhǔn)用戶界面對話框,,它們都有相應(yīng)的mfc庫中的類來支持,,所有這些通用對話框類都是從一個公共的基類ccommondialog派生而來的。
17.如果消息對話框只有“是”和“否”兩個按鈕,,則如何設(shè)置messagebox函數(shù)的參數(shù)?答:可以將messagebox函數(shù)中的參數(shù)ntype設(shè)置為mb_yesno,。
消息對話框用于顯示信息有兩種類型afxmessagebox和messagebox,前者為全程函數(shù),messagebox只能在控件對話框,,窗口等一些窗口類中使用
1.菜單有哪些常見的規(guī)則?p221
為了使windows程序更容易操作,菜單的顯示都遵循下列一些規(guī)則:
⑴若單擊某菜單項后,,將彈出一個對話框,,那么在該菜單項文本后有“…”,。
⑵若某項菜單有子菜單,那么在該菜單項文本后有。
⑶若菜單項需要助記符,,則用括號將帶下畫線的字母括起來。助記符與alt構(gòu)成一個組合鍵,,當(dāng)按住“alt”鍵不放,,再敲擊該字母時,對應(yīng)的菜單項就會被選中,。
⑷若某項菜單需要快捷鍵的支持,,則一般將其列在相應(yīng)菜單項文本之后。
2.什么是助記符?它是如何在菜單中定義的?菜單項的助記符是用括號和帶下畫線的字母括起來的符號,,助記符與alt構(gòu)成一個組合鍵,。
3.菜單項的消息有哪些?
菜單項產(chǎn)生的消息有:command 消息和update_command_ui消息。
4.若對同一個菜單用class wizard分別在視圖類和主框架窗口類cmainframe都處理其 command消息,并在它們的函數(shù)中添加相同的代碼,,則當(dāng)用戶選擇該菜單后,,會有什么樣的結(jié)果?為什么?
命令消息處理的優(yōu)先級別為:命令→視圖類→文檔類→文檔模板類→框架窗口類→應(yīng)用程序類。因此,,視圖類的消息處理函數(shù)會執(zhí)行,,而
5.什么是鍵盤快捷鍵?它是如何定義的?
可以調(diào)用cstatusbar::setpanetext函數(shù)更新任何窗格中的文本。11.什么是命令更新消息?它的作用是什么? update_command_ui消息又稱為“更新命令ui消息”,,該消息映射函數(shù)中有一個ccmdui類的對象pcmdui,,ccmdui類中包含了一個指向菜單項或工具欄按鈕的指針,于是利用該指針對菜單項或工具欄按鈕的顯示形式進(jìn)修正
c++24點游戲代碼 24點游戲百科篇三
c++24點游戲
#include “iostream” #include “string” using namespace std;
//定義stack類
const maxsize=20;
enum error_code { success, overflow, underflow };
template
class stack { public: stack();
bool empty()const;bool full()const;int size()const;void clear();error_code top(t &item)const;error_code pop();
error_code push(const t &item);private: int count;t entry[maxsize];};
template
stack
::stack(){ count=0;}
template bool stack::empty()const { return count==0;}
template bool stack::full()const { return count==maxsize;}
templateint stack
::size()const { return count;}
templatevoid stack
::clear(){ count=0;}
template error_code stack::top(t &item)const { if(empty())return underflow;item= entry[count-1];return success;}
template error_code stack::pop(){ if(empty())return underflow;count--;return success;}
template error_code stack::push(const t &item){ if(full())return overflow;entry[count++]=item;return success;}
stacksign;stack
num;
int set;// 判斷程序中的異常,,以便適時退出,?//
void process(char c)
//計算兩個數(shù)的 +-* / 運算// { int k=0;double a,b;();
if((b)==success){
();
if((a)==success){ ();k=1;} } if(k){ switch(c){
case '+': (a+b);break;case '-': (a-b);break;case '*': (a*b);break;case '/': if(b==0){ set=4;(-1);} else
(a/b);break;} }
else {set=1;(-1);} }
void get_command(string &str){
cout<<“n請輸入要進(jìn)行運算的表達(dá)式,包括” +,-,*,/,=,(,)“和數(shù)字,”<
<<“注意: 以數(shù)字開頭,等號結(jié)尾,中間括號要匹配.”<
>str;}
double do_command(const string &str){ string s=“";double outcome=-1;char c;
for(int i=0;str[i]!='';i++){
if(set!=0)break;//例外 則停止運行
while(1){ //分離數(shù)據(jù)與運算符
if(str[i]<='9' && str[i]>='0' || str[i]=='.'){ s+=str[i];i++;} else { if(s!=”“){
if((atof(s.c_str()))==overflow)set=3;s=”“;} break;} }
char ch= str[i];
switch(ch){ //處理運算的優(yōu)先級,并注意例外拋出
case '*': case '/':
if((c)==success)if(c=='*'||c=='/')process(c);if((ch)==overflow)set=3;break;case '+': case '-':
while((c)==success){ if(c!='(')process(c);else break;}
if((ch)==overflow)set=3;break;case '(':
if((ch)==overflow)set=3;break;case ')':
while((c)==success){ if(c!='(')process(c);else break;}
();break;case '=':
while((c)==success){ if(c!='(')process(c);else break;} break;
default: set=2;break;} }
if(()==1 && ()==0)(outcome);else set=1;
if(set==0)cout<<”運算結(jié)果是:n“<
if(set==1)cout<<”n您輸入的不匹配,,有錯誤發(fā)生,。result lost!“<
if(set==4)cout<<”n 分母為0,,不能進(jìn)行除法運算,,出現(xiàn)溢出,lost result,!“<
return outcome;}
void main()int f(){ double out;do { string str,s;set=0;
get_command(str);s=str;
if(str[0]=='-')str='0'+str;//處理表達(dá)式中的負(fù)號
for(int i=1;str[i]!='';i++){ if(str[i]=='-' && str[i-1]=='('){ (i,”0“);i++;} } out= do_command(str);
cout<
我gai過此行
cout<<”如果你算的結(jié)果不等于24,,需要重新計算請輸入你算出的結(jié)果,程序有漏洞,,請合作,。“<
>out;cout<<”謝謝合作“<
return out;}
int main(void)
{
int ii,zz,jj;
printf(”0-12的4個數(shù)字nn“);
for(jj=0;jj<2;)
{
for(ii=0;ii<4;ii++)
{
zz=rand()()% 12;
cout<
}
cout<<”請用這4個數(shù)字算出24“<
f();
cout<<”是否繼續(xù),;是1否2"<
cin>>jj;
cout<
}
c++24點游戲代碼 24點游戲百科篇四
第3章 “速算24”撲克游戲--單元,、異常、邏輯
3.1 “速算24”撲克游戲效果說明
“速算24”是一個考察心算能力,、有助于開發(fā)智力的撲克游戲,。在給出4張撲克牌之后,要求應(yīng)用這些撲克牌數(shù)字做數(shù)學(xué)運算,,迅速構(gòu)造出一個數(shù)學(xué)表達(dá)式,,得出結(jié)果24。這個游戲的關(guān)鍵在于迅速判斷用戶輸入的表達(dá)式是否正確,,并做出相應(yīng)的反饋,,告訴用戶是算對了還是算錯了。游戲的初始界面如圖3.1所示,。
圖3.1 游戲的初始界面
當(dāng)用戶單擊“開始”按鈕時,,系統(tǒng)開始發(fā)牌,隨機發(fā)出4張牌,如圖3.2所示為隨機開始的一局游戲,,給出的4張紙牌分別為“9”,,“8”,“9”,,“2”,。在文本框中輸入運算表達(dá)式,比如,,輸入“8*(2+(9-9))”,,單擊“計算”按鈕,系統(tǒng)會出現(xiàn)提示框,,顯示“您輸入的表達(dá)式的計算結(jié)果為16!”,,告訴你該表達(dá)式的結(jié)果不是“24”,如圖3.3所示,。單擊“確定”按鈕,,再次在文本框中輸入表達(dá)式,比如“8*(2+(9/9))”,,單擊“計算”按鈕,,系統(tǒng)會出現(xiàn)提示框,顯示“您真行,,我服了您,!”,表明運算正確,,如圖3.4所示,。
圖3.2 系統(tǒng)隨機發(fā)4張紙牌
圖3.3 運算式不正確
圖3.4 運算式正確
這個游戲具體的規(guī)則如下:
(1)單擊“開始”按鈕,游戲開始,,系統(tǒng)將隨機發(fā)牌,。
(2)請迅速在文本框中輸入運算表達(dá)式,然后單擊“計算”按鈕,。
(3)這時系統(tǒng)會提示您的運算是對了還是錯了,在彈出的對話框中單擊“ok”按鈕,,再次輸入新的運算表達(dá)式,,重復(fù)上一步,直到您的運算表達(dá)式結(jié)果正確,,這時系統(tǒng)會恭喜您,!
(4)如果結(jié)果錯了還想繼續(xù)或者中途想計算另一局撲克牌,就單擊“重新開始”按鈕,,得到新一局撲克牌進(jìn)行游戲,。
下面,我們開始循序漸進(jìn)地創(chuàng)建這個小游戲。在最開始,,游戲的界面和效果都會非常簡單,,在后面我們會逐漸地完善它。
第3章 “速算24”撲克游戲--單元,、異常,、邏輯
3.2 生成和建立程序(1)在程序中用到了image組件,用于放置圖片,。還用到了timer組件,,用于計算用戶操作時間。下面我們來生成游戲的基本框架,。
3.2.1 image組件
image組件在additional頁上,,用來在窗口中顯示一幅圖片。它擁有如下幾個主要屬性: e屬性
可以在picture屬性中調(diào)入圖像文件,。delphi支持多種圖像格式,,如位圖(.bmp)、圖標(biāo)(.ico),、圖元(.wfm),、動畫光標(biāo)(.ani)、jpeg圖片(.jpg,、.jpeg)等,。
ze屬性
當(dāng)autosize為true時,image組件將根據(jù)它所包含的圖像的大小來調(diào)整自身的大??;當(dāng)autosize為false時,不論圖像有多大,,組件將保持設(shè)計時的大小,。如果組件比圖像小,那么只有一部分圖像是可見的,。
h屬性
當(dāng)stretch為true時,,位圖圖像將根據(jù)組件的大小調(diào)整自身的大小,當(dāng)組件大小改變時,,上述三種文件也做相應(yīng)變化,。stretch屬性對圖標(biāo)沒有作用。
上述的autosize和stretch屬性決定了圖像在窗口中的顯示尺寸,。
圖3.5演示的3個image分別為:autosize為true,autosize為false,,stretch為true的情形,??梢钥吹剑琲mage的原始尺寸比圖片寬,,矮,,在上面的屬性設(shè)置下,就會有不同的顯示效果,。
圖3.5 autosize和stretch的設(shè)置 3.2.2 timer組件
在delphi中,,組件分可視組件和非可視組件??梢暯M件是指那些在運行期間仍然能顯示的組件,,例如label,,button,image組件等,。非可視組件是指那些在程序界面設(shè)計期間可見,,而在程序運行時不可見的組件,,例如在system頁上的timer組件,。
timer組件能夠有規(guī)律地觸發(fā)ontimer事件,發(fā)送信息給應(yīng)用程序,,它是編制應(yīng)用程序時最為重要的組件之一,。
組件的屬性
enabled屬性表示timer是打開還是關(guān)閉。用interval屬性設(shè)置兩個ontimer事件間的間隔,,單位是毫秒,。將間隔設(shè)置為0相當(dāng)于關(guān)閉計時器,interval是cardinal類型的,,最大值可到4294967295,,當(dāng)然程序中一般不會把interval設(shè)成很大的值。組件的使用
timer是獨立的對象,,在啟動與windows無關(guān)的邏輯和應(yīng)用事件時極其有用,。可以模擬時鐘或計時器,,可視地顯示經(jīng)過的時間;可以用作系統(tǒng)延時,,delphi提示信息出現(xiàn)只需在該區(qū)域停頓幾秒,,就是timer組件應(yīng)用的一個例子,;可以檢查系統(tǒng)環(huán)境、事件,,根據(jù)結(jié)果進(jìn)行響應(yīng),;也可以在窗口中閃爍一段正文或圖像,提示某種操作或處理正在進(jìn)行等等,。
盡管delphi的計時器每秒可以產(chǎn)生1000次激發(fā),,在編程中還必須注意程序?qū)imer觸發(fā)的響應(yīng)。如果程序處理ontimer事件的時間超過interval的設(shè)定值,,就可能錯過事件,,因為當(dāng)下一次觸發(fā)到來時,系統(tǒng)正忙于處理上一事件,,則這次觸發(fā)就會被忽略,。同時要注意其他的windows應(yīng)用程序是否會影響timer的觸發(fā)。如果后臺正運行著一個占用處理器的程序,,就可能會導(dǎo)致timer的觸發(fā)不準(zhǔn)確,,從而使前臺程序運行出現(xiàn)錯誤。
這里要強調(diào)的是timer組件是一個非可視組件,,可以把它放置到窗體或者其他容器組件上的任何位置,。3.實現(xiàn)游戲計時功能
在本章的游戲中,我們加入一個timer組件,,實現(xiàn)游戲的計時功能,。
在窗體中加入一個label組件,將此組件的caption屬性設(shè)置為“使用時間”,,然后從組件面板上選擇system頁中的timer組件,。
在unit1中加入form1的一個私有成員spendtime,記錄用戶計算所用的時間,。代碼如下所示:
private { private declarations } spendtime:integer;在form1的oncreate事件中加入如下代碼,。將spendtime設(shè)置為0,并將timer1的enabled屬性設(shè)置為false,,使timer1組件不能響應(yīng)ontimer事件,;并將timer1的interval屬性設(shè)置為1000,表示當(dāng)timer1有效時,,每間隔1000ms(即1秒)發(fā)生一次ontimer事件:
procedure eate(sender: tobject);var i:integer;begin //初始化,,設(shè)置數(shù)組randomdata的長度為4 //并將每個數(shù)組元素初始化為零
setlength(randomdata,4);for i := 0 to 3 do randomdata[i]:=0;spendtime:=0;d:=false;al:=1000;end;然后在標(biāo)題為“開始”的“開始”按鈕的onclick事件中,加入如下所示的代碼,,將timer1的enabled屬性設(shè)置為true,,使timer1組件有效,即現(xiàn)在timer1能響應(yīng)ontimer事件,,計時開始,。并將spendtime重新設(shè)置為0:
d:=true;al:=1000;spendtime:=0;//將spendtime重新設(shè)為0 再在“計算”按鈕的onclick事件句柄中,,增加下面的語句,使timer1無效:
d:=false;最后雙擊timer1組件,,創(chuàng)建timer1的ontimer事件句柄,,在其中加入如下所示的代碼,將spendtime加1,,并設(shè)置label5的caption屬性:
procedure tform1timer(sender: tobject);begin spendtime:=spendtime+1;n:='使用時間:'+inttostr(spendtime)+'秒';end;這樣,,每隔1秒鐘,程序就刷新一次使用時間,。
3.2.3 設(shè)計初始界面
按住shift鍵,,然后單擊組件面板中additional頁中的image組件,這時該組件邊緣出現(xiàn)藍(lán)色的邊框,,并且凹陷下去,,表示可以在窗體上連續(xù)加入幾個image組件。選擇好image組件后,,在窗體的左上角單擊,,加入1個image組件,然后依次向右單擊鼠標(biāo)3次,,再加入3個image組件,。最后再單擊組件面板中最左邊的箭頭。
為了排列這4個image組件,,先利用shift鍵將它們同時選上,,然后右擊,選擇align命令,,在隨后出現(xiàn)的alignment對話框中的horizontal選項組中選擇space equally,,在vertical選項組中選擇tops,表示這4個組件頂端對齊,,水平方向上間距相等,。
按照同樣的方法加入4個label組件、3個button組件和1個edit組件,。按照表3.1所示設(shè)置各個組件的屬性,。
表3.1 各個組件的屬性
組件名 form1 label1 屬性名 caption caption autosize wordwrap caption
屬性值 速算24
1.單擊“開始”按鈕,游戲開始,,系統(tǒng)將發(fā)出4張撲克牌
false false
2.要求用戶利用撲克牌顯示的數(shù)字,,通過加減乘除運算,以最快的速度得出24(可以使用括號),,jqka和“王”算做1,。然后在文本框中寫好表達(dá)式,接
著單擊“計算”按鈕
label2
label3 autosize wordwrap caption
false true
3.這時系統(tǒng)會計算輸入表達(dá)式的結(jié)果,,告訴用戶是對還是錯了,。在彈出的對話框中單擊“ok”按鈕,,如果錯了可以再次輸入新的表達(dá)式,重復(fù)上一步,。直
到您的表達(dá)式正確,這時系統(tǒng)會恭喜算對了,!
label4 autosize wordwrap caption autosize caption caption caption text
false true 在下面輸入數(shù)學(xué)表達(dá)式
false 開始 計算 退出游戲 空
button1 button2 button3 edit1
現(xiàn)在同時選擇label1,,label2和label3,將它們左對齊,,垂直方向等距離排列,。將button1,button2和button3左對齊,,垂直方向等距離排列,。
下面放置4個image組件,用于放置4張紙牌的圖片,。
先選擇image1,,然后切換到對象查看器中的屬性編輯器,選擇屬性選項頁中的picture屬性,,然后在picture屬性值欄中雙擊,,或單擊此屬性值旁邊的帶有省略號的按鈕,打開picture editor對話框,,如圖3.6所示,。然后單擊load按鈕,彈出load picture對話框,,文件,。最后單擊ok按鈕,退出picture editor對話框,。
圖3.6 指定圖片
使用同樣的方法,,設(shè)定其他3個image組件的picture屬性。
保存我們的新項目,,運行之后界面如圖3.7所示,,與運行時的界面圖3.1稍有不同。這里是設(shè)計時界面,,只有界面沒有事件響應(yīng),。是程序創(chuàng)建過程中的一個步驟的檢驗。但是,,這個程序還沒有什么具體的功能,,為了讓游戲運行起來,必須添加代碼,,創(chuàng)建相應(yīng)的事件處理程序,。
第3章 “速算24”撲克游戲--單元,、異常、邏輯
????生成和建立程序????
???????
3.2.4 事件處理
需要添加?個事件:第一個用于響應(yīng)單擊?開始?按鈕,,在此事件中完成發(fā)牌,,即隨機顯示圖片;第二個用于響應(yīng)單擊?計算?按鈕,,解析用戶在文本框中輸入的表達(dá)式,,計算表達(dá)式的結(jié)果,并判斷表達(dá)式的結(jié)果是否等于??,;第三個用于響應(yīng)單擊?退出游戲?按鈕,,退出游戲(程
序)。?
1.數(shù)據(jù)初始化
創(chuàng)建窗體的????????事件處理程序,,在這里進(jìn)行必要的初始化,。?第一步先在unit1中添加form1的私有成員數(shù)組:
private
{ private declarations }
randomdata:array of integer;然后,在對象查看器中選中form1,,選中event選項卡,,在oncreate一欄對應(yīng)的右邊的空白欄中雙擊,創(chuàng)建oncreate函數(shù),。添加如下代碼,。
procedure eate(sender: tobject);
var
i:integer;
begin //初始化,設(shè)置數(shù)組randomdata的長度為4
//并將每個數(shù)組元素初始化為零
setlength(randomdata,4);
for i := 0 to 3 do
randomdata[i]:=0;
end;這里使用一個for循環(huán)語句,,i是循環(huán)變量,,格式是:for循環(huán)變量:=初值to末值do循環(huán)體。你也可以借助delphi的自動完成功能,,在輸入for之后按下ctrl+j鍵,,生成如下代碼:
procedure eate(sender: tobject);
begin
for := to do
begin end;
end;在上述代碼中,程序首先利用setlength函數(shù)設(shè)定可變數(shù)組randomdata的數(shù)組長度為4,,然后,,將數(shù)組的每一個單元都設(shè)置為0。這樣,,就完成了數(shù)組的數(shù)據(jù)初始化工作,。
2.“開始”按鈕的click事件處理
(?)功能?單擊?開始?按鈕時,系統(tǒng)就隨機地發(fā)出?張紙牌,,顯示在?個?????組件中,。?
(?)代碼?首先,我們需要一個循環(huán)變量?,,一個字符串變量存放隨機選取的圖片的文件名,。?創(chuàng)建“開始”按鈕的onclick事件處理程序,在begin前頭添加需要的變量,然后在此事件
中加入如下所示的代碼,。
procedure 1click(sender: tobject);
var
i:integer;
filename:string;
begin
randomize;//初始化隨機數(shù)
for i := 0 to 3 do
begin randomdata[i]:=random(13)+1;//產(chǎn)生一個1到13的隨機數(shù)
filename:=inttostr(randomdata[i])+'.bmp';//根據(jù)隨機數(shù),,得到文件名
//根據(jù)i的不同為不同的image組件載入圖像文件
case i of 0 : omfile(filename);1 : omfile(filename);2 : omfile(filename);3 : omfile(filename);
end;
:='';
us;
end;
end;在delphi內(nèi)部,隨機數(shù)的產(chǎn)生實際上也是在一套算法的控制之下,,randomize函數(shù)用于初始化產(chǎn)生隨機數(shù)的種子,,保證兩次產(chǎn)生的隨機數(shù)不同,而random(i:integer)則利用初始化過后的隨機數(shù)種子產(chǎn)生一個1~i之間的隨機數(shù),。這里i設(shè)定為13,,以配合撲克牌的張數(shù)13。
???????????????????用來將一個整數(shù)轉(zhuǎn)換成一個字符串,,和上一章中的??????????????????的功能恰好相反。?我們已經(jīng)預(yù)先準(zhǔn)備了位圖文件,,它們都是???形式,,文件名則是利用數(shù)字????命名。??????中特殊的字符串運算符???將兩個字符串串聯(lián)起來,,產(chǎn)生一個新的字符串,,我們需要的位圖文件后綴是???,因此,,在產(chǎn)生文件名的時候,,在數(shù)字后面加上??????這個字符串。?????語句在上一章中已經(jīng)講過,,單擊?開始?按鈕后,,準(zhǔn)備接受用戶的輸入,然后利用????????方法,,把焦點設(shè)置到?????上,。????????是??????提供的方法之一,用于設(shè)置輸入
焦點到某個指定的組件,。?
3.“計算”按鈕的onclick事件
雙擊“計算”按鈕,,創(chuàng)建此組件的onclick事件響應(yīng)句柄,然后在代碼編輯器中加入如下所
示的代碼,,用于計算用戶輸入的表達(dá)式,。
procedure 2click(sender: tobject);
var
result:integer;
answer:string;
begin
result:=totalcompute();
if(result=24)then ebox('您真行,我服了您!','對了',mb_ok)
else
begin answer:='您輸入的表達(dá)式的計算結(jié)果為'+inttostr(result)+'!';ebox(pchar(answer),'錯了',mb_ok);
end;
end;這段程序根據(jù)自定義函數(shù)的計算結(jié)果判斷用戶的輸入正確與否,,并且輸出相應(yīng)的結(jié)果以提示
用戶,。
在語句“result:=totalcompute()”中用到了一個自定義的函數(shù)totalcomp-ute,我們用它來計算用戶輸入的表達(dá)式?,F(xiàn)在我們還沒編寫這個函數(shù)的代碼,,所以,目前這段代碼是無法運行的。沒關(guān)系,,可以先把它用“//”注釋掉,,然后隨便給 result賦一個值,測試這個事件處理程序的其他部分是否運行正常,,例如:
//result:=totalcompute();
result:=24;這樣,,運行后,單擊“計算”按鈕后的顯示如圖3.8所示,。
圖3.8 成功的提示信息
我們用一個??????類型的??????變量存放出錯信息,,但是???????函數(shù)的第一個參數(shù)要求是?????(????????????????字符指針)類型,因此,,我們用一個強制類型轉(zhuǎn)換將??????轉(zhuǎn)換
成?????,。?4.“退出游戲”按鈕的onclick事件
雙擊“退出游戲”按鈕,創(chuàng)建此組件的onclick事件處理程序,,然后在代碼編輯器中加入如
下所示的代碼,,用于退出程序。
procedure 3click(sender: tobject);
begin
close;
end;在上一章中我們提到可以用?????????????????????代替?????,,但這里使用?????來結(jié)束程序的運行,。這樣,可以通過????????????事件來指定在什么條件下窗體可以關(guān)閉,。
第3章 “速算24”撲克游戲--單元,、異常、邏輯
????生成和建立程序???????????equery事件
當(dāng)調(diào)用?????方法來關(guān)閉窗體時,,????????????事件發(fā)生,。利用????????????事件來指定在什么條件下窗體可以關(guān)閉。????????????事件包含一布爾型的????????參量,,可以用它來決定窗體是否關(guān)閉,。????????的默認(rèn)值為????。?可以利用????????????事件來詢問用戶是否真的希望馬上關(guān)閉窗體,。?我們在這里彈出一個對話框,,代碼如下所示:
procedure osequery(sender: tobject;var canclose: boolean);begin if(messagedlg('現(xiàn)在要退出游戲嗎?', mtconfirmation, [mbok, mbcancel], 0)= mrok)then canclose:=true else canclose:=false;end;messagedlg是一種提示對話框,第一個參數(shù)是對話框詢問的訊息,,是一個字符串,;第二個參數(shù)則代表對話框的類型,mtconfirmation是一個tmsgdlgtype的枚舉類型,,表示這個對話框是個確認(rèn)對話框,。tmsgdlgtype類型如下所示:
type tmsgdlgtype =(mtwarning, mterror, mtinformation, mtconfirmation, mtcustom);以上定義的對話框類型分別表示:警告、錯誤,、提示,、確認(rèn)和自定義類型,。
第三個參數(shù)是tmsgdlgbtn類型的集合,這個集合包含了類型為tmsgdlgbtn的按鈕,,tmsgdlgbtn的定義如下:
type tmsgdlgbtn =(mbyes, mbno, mbok, mbcancel, mbabort, mbretry, mbignore, mball, mnnotoall, mbyestoall, mbhelp);在我們的程序中,,利用了一個集合[mbok, mbcancle],表示在對話框中顯示兩個按鈕:ok和cancel的組合,。
最后一個參數(shù)是用來描述幫助索引的長整型變量,,用來獲取提示用戶的幫助信息,這里我們沒有任何幫助信息,,先不管它,。??????????函數(shù)和用戶交互,返回一個????類型的數(shù)字,,??????預(yù)先定義了一套數(shù)字,,用來直觀地表示對話框返回信息。如果用戶單擊了??按鈕,,這個對話框返回????,,效果如圖???所示。?
圖3.9 關(guān)閉窗口時詢問用戶
現(xiàn)在,,我們已經(jīng)完成了程序的主體部分。??第3章 “速算24”撲克游戲--單元,、異常,、邏輯
????單元間的互相引用????????3.3.1 單元引用的概念
在第?章關(guān)于單元的知識里,我們已經(jīng)知道??????可以定義不包含窗體的單元,,它集中定義了程序中使用的函數(shù),,這一節(jié)里,我們就要實現(xiàn)這樣的一個單元,,用來實現(xiàn)上面提到的????????????函數(shù),。?我們可以在任何單元中編寫自己的函數(shù),當(dāng)然包括與窗體相連的單元,??墒俏覀兂3P枰玫揭恍┏S玫暮瘮?shù),這時最好是創(chuàng)建一個不與窗體相連的獨立單元,,用它來容納自己的函數(shù),,這稱為獨立的單元文件。當(dāng)創(chuàng)建了不與窗體相連的獨立單元文件后,,項目中的其他單元就能很容易地共享這些函數(shù),,其他項目也可以很容易地調(diào)用這些函數(shù)了。?對于單元間的引用,,要用到????語句,。?3.3.2 uses語句
????語句告訴程序在最終的執(zhí)行代碼中需要用到哪些函數(shù)和過程。??????會自動把一些必須的單元包括進(jìn)來,例如???????,,????????,,????????等。對于我們自己編寫的單元,,如果程序中使用了該單元的函數(shù)或代碼,,也需要包括在????部分中。?????語句具有兩種類型:公有引用和私有引用,。?在?????????部分包含的????語句代表的是本單元的公有引用,,就是說,這部分的引用可以被其他引用本單元的單元繼承性地引用,。在?????????部分的????語句應(yīng)包含在?????????部分中的代碼所需要的單元,,去掉那些??????可以自動加入到程序中的單元。?在?????????部分包含的????語句代表的是本單元的私有引用,,就是說,,這部分的引用只能被本單元內(nèi)部使用。在??????????????部分的????語句應(yīng)只包含在??????????????部分中的代碼所需的單元的名字,。?對于單元間的引用,,要避免交叉引用。假設(shè)有兩個單元?和?,,如果?出現(xiàn)在?的?????????部分的????語句中,,那么單元?便不能出現(xiàn)在單元?的?????????的????語句中。因為這樣會產(chǎn)生對單元的循環(huán)訪問,,編譯時會出現(xiàn)錯誤信息,。?3.3.3 創(chuàng)建另一個單元
創(chuàng)建一個不與窗體相連的單元文件的方法是,首先選擇主菜單的????命令,,然后選擇???命令,,此時??????彈出一個?????????對話框,如圖????所示,。在此圖中選擇???選項卡中的????,,然后單擊??按鈕。此時??????自動為我們創(chuàng)建一個名為?????的獨立單元文件,,并顯示在代碼編輯器中,,我們只需在此加入函數(shù)即可。?
圖3.10 new items對話框
單元創(chuàng)建之后,,就需要實現(xiàn)單元之間的互相引用,。這里有兩種方法:?(1)直接在unit1中寫入uses unit2,代碼如下所示:
var form1: tform1;implementation uses unit2;(2)選擇主菜單的file | use unit命令,,此時delphi彈出use unit對話框,,如圖3.11所示,,在此窗口中列出當(dāng)前文件沒有連接的所有文件,只需選擇需要連接的文件即可,。當(dāng)選擇了某一文件并單擊ok按鈕后,,當(dāng)前文件就包含了對所選文件的引用。
圖3.11 use unit對話框
如果當(dāng)前文件已經(jīng)連接了當(dāng)前項目中所有其他文件,,選擇????????命令后,,就會彈出如圖????所示的信息窗口,告訴程序員當(dāng)前文件已經(jīng)連接了當(dāng)前項目中所有其他文件,。?
圖3.12 information對話框
此時再編譯,,程序就沒有任何錯誤了。?現(xiàn)在我們已經(jīng)創(chuàng)建了?????,,它將用作我們的數(shù)學(xué)函數(shù)定義單元,。在開始定義這個單元之前,需要先了解一下關(guān)于??????的異常處理機制,。?第3章 “速算24”撲克游戲--單元,、異常、邏輯
3.4 異 常 處 理
3.4.1 異常處理的概念 在應(yīng)用程序開發(fā)中如何檢測,、處理程序的運行錯誤是一個很重要的問題,。在 delphi 的ide(集成開發(fā)環(huán)境)中提供了一個完善的內(nèi)置調(diào)試器,可以發(fā)現(xiàn)大部分程序錯誤,。但并不是所有的錯誤都可以被發(fā)現(xiàn),,而且當(dāng)程序涉及到與外設(shè)的數(shù)據(jù)交換或操作外設(shè),如要求用戶輸入,、讀寫磁盤等時,錯誤的發(fā)生是程序無法控制的,,如輸入非法字符,、磁盤不能讀寫等。這些情況不僅會導(dǎo)致應(yīng)用程序異常中止,,而且可能引起系統(tǒng)的崩潰,。針對這些問題,delphi提供了一套強大的異常處理機制,。巧妙地利用它,,可以使程序更為強健,使用更為友好,。
delphi異常處理機制建立在protected blocks(保護(hù)塊)的概念上,。所謂保護(hù)塊是指用保留字try和end封裝的一段代碼。保護(hù)塊的作用是當(dāng)應(yīng)用程序發(fā)生錯誤時自動創(chuàng)建一個相應(yīng)的exception(“異?!鳖悾?。程序可以捕獲并處理這個“異?!鳖悾源_保程序的正常結(jié)束以及資源的釋放和數(shù)據(jù)不受破壞,。如果程序不進(jìn)行處理,,則系統(tǒng)會自動提供一個消息框?!爱惓,!鳖愂莇elphi異常處理機制的核心,也是delphi異常處理的主要特色,。delphi提供的所有“異?!鳖惗际穷恊xception的子類。用戶也可以從類exception派生一個自定義的“異?!鳖?。
3.4.2 資源保護(hù)方式
回收分配的資源是確保程序健壯性的一個關(guān)鍵。但默認(rèn)情況下異常發(fā)生時程序會在出錯點自動退出當(dāng)前模塊,,因此需要一種特殊的機制來確保即使在異常發(fā)生的情況下,,釋放資源的語句仍能被執(zhí)行,而delphi的異常處理正提供了這種機制,。
delphi提供了一個保留字finally,,用于實現(xiàn)資源的保護(hù)。
{分配資源}
try {資源使用情況} finally {釋放資源}
end;try?finally?end就形成了一個資源保護(hù)塊,。finally后面的語句在任何情況下(不論程序是否發(fā)生異常)都會執(zhí)行,。
在異常保護(hù)的情況下,當(dāng)異常發(fā)生時,,系統(tǒng)會自動彈出一個消息框,,在框中顯示異常的消息。退出當(dāng)前模塊后異常類自動清除,。
3.4.3 異常響應(yīng)方式
異常響應(yīng)為開發(fā)者提供了一個按需進(jìn)行異常處理的機制,。try?except?end形成了一個異常響應(yīng)保護(hù)塊。與finally不同的是:正常情況下except 后面的語句并不被執(zhí)行,,而當(dāng)異常發(fā)生時程序自動跳到except處,,進(jìn)入異常響應(yīng)處理模塊。當(dāng)異常被響應(yīng)后異常類自動清除,。
下面是異常響應(yīng)方式的一般代碼:
try {程序正常功能} except on esomething do {響應(yīng)特定異常} else {提供默認(rèn)響應(yīng)} end;保留字on?do用于判斷異常類型,。必須注意的是:except后面的語句必須包含在某一個on?do模塊中,而不能單獨存在,。這是又一個與finally不同的地方,。
3.4.4 提供默認(rèn)響應(yīng)
在異常響應(yīng)模塊中,一般我們只對希望響應(yīng)的特定異常進(jìn)行處理,。如果一個異常發(fā)生而響應(yīng)模塊并沒有包含對它的處理代碼,,則退出當(dāng)前響應(yīng)模塊,,異常類仍被保留。
為了保證任何異常發(fā)生后都能在當(dāng)前響應(yīng)模塊中被清除,,可以定義默認(rèn)響應(yīng):
try {程序正常功能} except on esomething do {響應(yīng)特定異常} else {提供默認(rèn)響應(yīng)} end;由于else可以響應(yīng)任何異常,,包括我們一無所知的異常,因此在默認(rèn)響應(yīng)中最好只包括諸如顯示一個消息框之類的處理,,而不要改變程序的運行狀態(tài)或數(shù)據(jù),。
第3章 “速算24”撲克游戲--單元、異常,、邏輯
3.5 數(shù)學(xué)邏輯單元(1)
此游戲程序最關(guān)鍵的地方是如何將用戶輸入的字符串表達(dá)式解析成數(shù)學(xué)表達(dá)式,。為了使程序結(jié)構(gòu)清晰明了,我們將此解析代碼和程序的主代碼分開,,單獨編寫成一個單元,。
3.5.1 算法設(shè)計
游戲的難點是如何將一字符串形式的表達(dá)式解析成計算機能計算的算術(shù)表達(dá)式。例如對于字符串“3^(4*(9+4))”,,如何讓計算機解析,、計算。
我們的想法是按照數(shù)學(xué)四則運算規(guī)則,,先逐層進(jìn)入最里層的括號,,然后在括號內(nèi)部計算乘方,接著進(jìn)行乘(除)法運算,,最后按順序進(jìn)行加(減)運算,,當(dāng)本層括號內(nèi)部計算完成后,返回結(jié)果,,去掉括號內(nèi)部數(shù)據(jù),,退出到下一級括號(如果有)內(nèi)進(jìn)行計算。
這里面涉及的技術(shù)細(xì)節(jié)主要有下面幾點:
(1)層層剝離括號,,然后從最里層的括號開始計算,。(2)對于每一個運算符號,找到符號兩側(cè)的數(shù)字,,形成一個計算式。
(3)每一個子計算式完成后,,運算結(jié)果返回到原始數(shù)列中,,作為子串的一部分,繼續(xù)進(jìn)行上述計算,。
3.5.2 字符串的相關(guān)函數(shù)
在游戲中,,用戶輸入的都是字符數(shù)據(jù),我們需要從這些字符中分析得到數(shù)字和運算符號,,因此要用到與字符串操作有關(guān)的函數(shù),。
function pos(sub , all:string):integer;這個函數(shù)含有兩個參數(shù):sub表示要查找的字符,,all表示原字符串。函數(shù)在字符串a(chǎn)ll中尋找指定的字符sub的位置,,如果字符串中不存在sub字符,,則函數(shù)結(jié)果為0。
function lastdelimiter(sub,all :string):integer 這個函數(shù)含有兩個參數(shù):sub表示要查找的字符,,all表示原字符串,。函數(shù)返回在字符串a(chǎn)ll中所有查找到的指定字符sub的最后一個的位置,如果字符串中不存在sub字符,,則函數(shù)結(jié)果為0,。
function copy(allstring:string;first,length:integer):string 這個函數(shù)的3個參數(shù)的含義分別是:allstring代表原來的字符串,first表示拷貝開始的位置,,length表示要拷貝的子串長度,。函數(shù)返回拷貝成功的子串。
procedure delete(str:string;ppos,length:integer)這個過程用于刪除字符串中的一段字符,。參數(shù)str代表將要操作的字符串,,ppos代表開始刪除的位置,length表示將要刪除多少個字符,。function length(s): integer;length函數(shù)返回字符串s的長度,。
function trim(const s: string): string;overload;function trim(const s: widestring): widestring;overload;trim函數(shù)返回字符串s去掉前面和后面的空格后的字符串。
下面的例子給出一個綜合利用字符串處理函數(shù)編寫的一個處理特定字符串的函數(shù),,它的功能是:輸入一個字符串后,,可以返回字符串中兩個單括號之間的子字符串,并去掉前面和后面帶著的空格:
function getmystr(const s: string): string;begin result:=trim(copy(s,pos('<',s)+1,pos('>',s)-pos('<',s)-1));end;比如我們在程序中寫到getmystr(‘this is a test < result to output > end of test’);,,會得到字符串“result to output”,。
3.5.3 算法的代碼編寫
基于上述的考慮和知識基礎(chǔ),我們在聲明部分定義下列幾個主要函數(shù):
(1)anylastpos函數(shù)定位最后一個算術(shù)運算符的位置,。
function anylastpos(str:string):integer;(2)anyfirstpos函數(shù)定位最先一個算術(shù)運算符的位置,。
function anyfirstpos(str:string):integer;(3)anyfirstf函數(shù)判斷最先出現(xiàn)的符號是+號、-號,、*號還是/號,。
function anyfirstf(str:string):char;(4)subcompute函數(shù)用于計算不帶()號的加、減,、乘,、除運算。
function subcompute(str:string):integer;(5)totalcompute函數(shù)用于計算表達(dá)式的結(jié)果,。
function totalcompute(str:string):integer;1.尋找最后一個算術(shù)運算符
定義4個整數(shù)變量subpos,,plupos,mulpos,,spanpos,,在給定的字符串中尋找+,-,,*,,/的最后位置,將這些位置存儲在上述的4個變量中,,然后比較4個符號出現(xiàn)的位置,,得到數(shù)值最大的運算符;在返回的結(jié)果中,,返回這個運算符的位置,。
程序代碼如下所示:
function anylastpos(str:string):integer;var subpos:integer;plupos:integer;mulpos:integer;spanpos:integer;pos:integer;begin //定位字符串中最后一個運算符的位置
subpos:=lastdelimiter('-',str);plupos:=lastdelimiter('+',str);mulpos:=lastdelimiter('*',str);spanpos:=lastdelimiter('/',str);pos:=subpos;if(pos
分別在給定的字符串中尋找+,-,,*,,/第一次出現(xiàn)的位置,然后比較4個符號出現(xiàn)的位置,,得到數(shù)值最小的運算符,。在返回的結(jié)果中,傳遞的是這個運算符的位置,。
程序代碼如下所示:
function anyfirstpos(str:string):integer;var subpos:integer;plupos:integer;mulpos:integer;spanpos:integer;forpos:integer;firstpos:integer;begin //定位字符串中最先一個運算符的位置
subpos:=pos('-',str);plupos:=pos('+',str);mulpos:=pos('*',str);spanpos:=pos('/',str);forpos:=pos('^',str);firstpos:=200;if(subpos=0)then //如果沒有-號
subpos:=200;//將subpos設(shè)置成一個不可能的值
if(plupos=0)then //如果沒有+號
plupos:=200;//將plupos設(shè)置成一個不可能的值
if(mulpos=0)then //如果沒有*號
mulpos:=200;//將mulpos設(shè)置成一個不可能的值
if(spanpos=0)then //如果沒有/號
spanpos:=200;//將spanpos設(shè)置成一個不可能的值
if(forpos=0)then //如果沒有^號
forpos:=200;//將forpos設(shè)置成一個不可能的值
if(firstpos>subpos)then firstpos:=subpos;if(firstpos>plupos)then firstpos:=plupos;if(firstpos>mulpos)then firstpos:=mulpos;if(firstpos>spanpos)then firstpos:=spanpos;if(firstpos>forpos)then firstpos:=forpos;
anyfirstpos:=firstpos;//結(jié)束函數(shù),,返回位置
end;第3章 “速算24”撲克游戲--單元、異常,、邏輯
3.5 數(shù)學(xué)邏輯單元(2)
3.得到最先出現(xiàn)的運算符類型
這個函數(shù)的返回結(jié)果是char類型,,代表這是一個字符變量。實際上,,它返回的是+,、-、*,、/ 這4個符號中最早出現(xiàn)的一個,。
程序分別尋找4個符號最早出現(xiàn)的位置,然后判斷最先出現(xiàn)的是哪一種符號,,再根據(jù)符號類型返回代表運算符的字符,。
在具體的實現(xiàn)過程中,因為我們要得到最先出現(xiàn)的運算符,,所以判斷的是每次尋找后各個運算符的位置的最小值,。如果不存在這個運算符,則將代表這個運算符位置的相應(yīng)變量設(shè)置為200,。對于本程序來說,這是一個搜索過程中不可能達(dá)到的值,,這樣就排除了這個位置的繼續(xù)比較的可能,。
程序代碼如下所示:
function anyfirstf(str:string):char;var subpos:integer;plupos:integer;mulpos:integer;spanpos:integer;operator:char;temppos:integer;begin subpos:=pos('-',str);plupos:=pos('+',str);mulpos:=pos('*',str);spanpos:=pos('/',str);
if(subpos=0)then //如果沒有-號
subpos:=200;//將subpos設(shè)置成一個不可能的值
if(plupos=0)then //如果沒有+號
plupos:=200;//將plupos設(shè)置成一個不可能的值
if(mulpos=0)then //如果沒有*號
mulpos:=200;//將mulpos設(shè)置成一個不可能的值
if(spanpos=0)then //如果沒有/號
spanpos:=200;//將spanpos設(shè)置成一個不可能的值
operator:='-';temppos:=subpos;if(temppos>plupos)then begin temppos:=plupos;operator:='+';end;if(temppos>mulpos)then begin temppos:=mulpos;operator:='*';end;if(temppos>spanpos)then begin temppos:=spanpos;operator:='/';end;
anyfirstf:=operator;//結(jié)束函數(shù),,返回位置 end;4.計算不帶括號的運算表達(dá)式
做完上述工作后,我們可以開始進(jìn)行一些實際的運算了,。
包括加,、減、乘,、除,、乘方運算的表達(dá)式的程序算法如下所示:
(1)尋找乘方符號“^”,如果存在,,則計算一次乘方,,去掉計算過的部分,接著循環(huán)查找和計算子串的乘方,。
(2)尋找乘號“*”或者除號“/”,,如果存在,則計算一次乘(除)法,,去掉計算過的部分,,接著循環(huán)計算子串的乘除法。
(3)尋找加號“+”或者減號“-”,,如果存在,,則計算一次加(減)法,去掉計算過的部分,,接著循環(huán)計算子串的加減法,。
上述算法是嚴(yán)格按照順序進(jìn)行的,它體現(xiàn)了數(shù)學(xué)運算中的優(yōu)先關(guān)系,,經(jīng)過上述的計算,,子字符串被分解,計算完畢,。
無論是乘方,、乘除法還是加減法,內(nèi)部實現(xiàn)的邏輯是基本一致的,。下面,,我們設(shè)定有一個運算表達(dá)式:3+2^5/4。
程序代碼如下所示:
function subcompute(str:string):integer;var middle:string;mul2:string;right:string;first:integer;tempstr:string;temp:integer;left:string;mul1:string;mulpos:integer;spanpos:integer;fuhao:char;begin middle:='';mul2:='';right:='';
//定位第一個^號位置,,計算乘方
first:=pos('^',str);while(first<>0)do //循環(huán)計算乘方
begin tempstr:=copy(str,1,first-1);temp:=anylastpos(tempstr);left:=copy(str,1,temp);mul1:=copy(str,temp+1,first-temp-1);tempstr:=copy(str,first+1,length(str)-first);temp:=anyfirstpos(tempstr);if(temp=200)then begin mul2:=tempstr;right:='';end else begin mul2 :=copy(tempstr,1,temp-1);right:=copy(tempstr,temp,length(tempstr)-temp+1);end;middle:=floattostr(intpower(strtoint(mul1),strtoint(mul2)));str:=left+middle+right;first:=pos('^',str);end;
//定位第一個*號或/號的位置
mulpos:=pos('*',str);spanpos:=pos('/',str);first:=mulpos;if(mulpos>spanpos)then first:=spanpos;if((spanpos=0)and(mulpos<>0))then begin first:=mulpos;spanpos:=2000;// 將除號所在位置設(shè)置成一個大于mulpos但又不可能的值
end;if((spanpos<>0)and(mulpos=0))then begin first:=spanpos;mulpos:=2000;// 將乘號所在位置設(shè)置成一個大于spanpos但不可能的值
end;while(first<>0)do //循環(huán)計算乘,、除
begin tempstr:=copy(str,1,first-1);temp:=anylastpos(tempstr);left:=copy(str,1,temp);mul1:=copy(str,temp+1,first-temp-1);tempstr:=copy(str,first+1,length(str)-first);temp:=anyfirstpos(tempstr);if(temp=200)then begin mul2:=tempstr;right:='';end else begin mul2 :=copy(tempstr,1,temp-1);right:=copy(tempstr,temp,length(tempstr)-temp+1);end;if(mulpos>spanpos)then middle:=inttostr(strtoint(mul1)span strtoint(mul2))else middle:=inttostr(strtoint(mul1)*strtoint(mul2));str:=left+middle+right;
mulpos:=pos('*',str);spanpos:=pos('/',str);first:=mulpos;if(mulpos>spanpos)then first:=spanpos;
if((spanpos=0)and(mulpos<>0))then begin first:=mulpos;spanpos:=2000;// 將除號所在位置設(shè)置成一個大于mulpos但又不可能的值
end;if((spanpos<>0)and(mulpos=0))then begin first:=spanpos;mulpos:=2000;// 將乘號所在位置設(shè)置成一個大于spanpos但不可能的值
end;end;//定位+、-號首先出現(xiàn)的位置
first:=anyfirstpos(str);if(first=200)then //如果沒有+,、-號,,則可以直接返回結(jié)果
begin subcompute:=strtoint(str);exit;end;fuhao:=anyfirstf(str);//確定首先出現(xiàn)的符號是+號還是-號
while(first<>0)do begin //如果找到+號或-號
tempstr:=copy(str,1,first-1);temp:=anylastpos(tempstr);left:=copy(str,1,temp);mul1:=copy(str,temp+1,first-temp-1);tempstr:=copy(str,first+1,length(str)-first);temp:=anyfirstpos(tempstr);if(temp=200)then begin mul2:=tempstr;right:='';end else begin mul2 :=copy(tempstr,1,temp-1);right :=copy(tempstr,temp,length(tempstr)-temp+1);end;if(fuhao='+')then middle:=inttostr(strtoint(mul1)+strtoint(mul2))else middle:=inttostr(strtoint(mul1)-strtoint(mul2));str:=left+middle+right;first:=anyfirstpos(str);if(first=200)then break;fuhao:=anyfirstf(str);end;
subcompute:=strtoint(middle);end;程序執(zhí)行過程如下所示:
(1)定位字符串中第一個乘方符號“^”的位置first。這個式子中的first為4。
(2)如果存在乘方符號,,即first不等于0,,則繼續(xù)進(jìn)行計算,否則退出循環(huán),。
(3)進(jìn)入循環(huán)體內(nèi)部,,得到“^”前面的子串tempstr(“3+2”),尋找tempstr中的最后一個運算符temp(這里是“+”),,則temp和first之間的字符就是乘方符號的第一個參數(shù)(“2”),。
(4)同樣的邏輯,得到“^”后面的子串tempstr(“5/4”),,尋找tempstr中的第一個運算符位置temp(“/”),,則temp和first之間的字符就是乘方符號的第二個參數(shù)(“5”)。
(5)去掉乘方符號和兩個參數(shù),,得到左側(cè)子串left(“3+”)和右側(cè)子串right(“/4”),。
(6)利用這兩個參數(shù)和乘方符號,計算乘方,,將結(jié)果返回,,并插入在left和right之間,得到一次計算后的新字符串(“3+32/4”),。
(7)判斷新串內(nèi)部是否包含“^”,,如果包含,則返回到步驟(3),,不包含則進(jìn)入下一種運算,。
第3章 “速算24”撲克游戲--單元、異常,、邏輯
3.5 數(shù)學(xué)邏輯單元(3)5.計算整個表達(dá)式的值
totalcompute函數(shù)利用循環(huán),,找到最內(nèi)層的一對括號,然后調(diào)用subcompute函數(shù)處理這一對括號中的表達(dá)式,。subcompute函數(shù)處理的表達(dá)式中已經(jīng)沒有括號了,,因此subcompute只需處理乘方、加,、減,、乘、除,,返回結(jié)果,,形成新的字符串。
當(dāng)整個字符串縮減至空值時,,整個表達(dá)式計算完成,。
程序代碼如下所示:
function totalcompute(str:string):integer;var first:integer;last:integer;substr:string;leftstr:string;middle:string;right:string;temp:integer;begin first:=lastdelimiter('(',str);//定位最后一個(號位置 while(first<>0)do begin substr:=copy(str,first+1,length(str)-first);last:= pos(')',str);//last:=last+first;//定位最后一個(號以后的最開始的)號位置
leftstr:=copy(str,1,first-1);//(號左邊的字符串
middle:=copy(str,first+1,last-first-1);//()號中間的字符串
right:=copy(str,last+1,length(str)-last);//)號右邊的字符串
temp:=subcompute(middle);//進(jìn)入下面的計算
middle:=inttostr(temp);
str:=leftstr+middle+right;first:=lastdelimiter('(',str);end;
result:=subcompute(str);end;end.在程序中,,“計算”按鈕的onclick事件處理程序中調(diào)用totalcompute函數(shù)。函數(shù)中使用了一些數(shù)學(xué)函數(shù)和定位字符串的函數(shù),,這些函數(shù)delphi已經(jīng)在相應(yīng)的系統(tǒng)單元中進(jìn)行了定義,,我們需要把這些系統(tǒng)單元包括到文件里面:
uses sysutils,math;將前面調(diào)用totalcompute的注釋去掉,把代碼改回:
procedure 2click(sender: tobject);var result:integer;answer:string;begin result:=totalcompute();if(result=24)then ebox('您真行,,我服了您!','對了',mb_ok)else begin