久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

delphi24點游戲

時間:2019-05-12 22:29:44下載本文作者:會員上傳
簡介:寫寫幫文庫小編為你整理了多篇相關的《delphi24點游戲》,但愿對你工作學習有幫助,當然你在寫寫幫文庫還可以找到更多《delphi24點游戲》。

第一篇:delphi24點游戲

第3章 “速算24”撲克游戲--單元、異常、邏輯

3.1 “速算24”撲克游戲效果說明

“速算24”是一個考察心算能力、有助于開發智力的撲克游戲。在給出4張撲克牌之后,要求應用這些撲克牌數字做數學運算,迅速構造出一個數學表達式,得出結果24。這個游戲的關鍵在于迅速判斷用戶輸入的表達式是否正確,并做出相應的反饋,告訴用戶是算對了還是算錯了。游戲的初始界面如圖3.1所示。

圖3.1 游戲的初始界面

當用戶單擊“開始”按鈕時,系統開始發牌,隨機發出4張牌,如圖3.2所示為隨機開始的一局游戲,給出的4張紙牌分別為“9”,“8”,“9”,“2”。在文本框中輸入運算表達式,比如,輸入“8*(2+(9-9))”,單擊“計算”按鈕,系統會出現提示框,顯示“您輸入的表達式的計算結果為16!”,告訴你該表達式的結果不是“24”,如圖3.3所示。單擊“確定”按鈕,再次在文本框中輸入表達式,比如“8*(2+(9/9))”,單擊“計算”按鈕,系統會出現提示框,顯示“您真行,我服了您!”,表明運算正確,如圖3.4所示。

圖3.2 系統隨機發4張紙牌

圖3.3 運算式不正確

圖3.4 運算式正確

這個游戲具體的規則如下:

(1)單擊“開始”按鈕,游戲開始,系統將隨機發牌。

(2)請迅速在文本框中輸入運算表達式,然后單擊“計算”按鈕。

(3)這時系統會提示您的運算是對了還是錯了,在彈出的對話框中單擊“OK”按鈕,再次輸入新的運算表達式,重復上一步,直到您的運算表達式結果正確,這時系統會恭喜您!

(4)如果結果錯了還想繼續或者中途想計算另一局撲克牌,就單擊“重新開始”按鈕,得到新一局撲克牌進行游戲。

下面,我們開始循序漸進地創建這個小游戲。在最開始,游戲的界面和效果都會非常簡單,在后面我們會逐漸地完善它。

第3章 “速算24”撲克游戲--單元、異常、邏輯

3.2 生成和建立程序(1)在程序中用到了Image組件,用于放置圖片。還用到了Timer組件,用于計算用戶操作時間。下面我們來生成游戲的基本框架。

3.2.1 Image組件

Image組件在Additional頁上,用來在窗口中顯示一幅圖片。它擁有如下幾個主要屬性: 1.Picture屬性

可以在picture屬性中調入圖像文件。Delphi支持多種圖像格式,如位圖(.BMP)、圖標(.ICO)、圖元(.WFM)、動畫光標(.ANI)、JPEG圖片(.JPG、.JPEG)等。

2.AutoSize屬性

當AutoSize為True時,Image組件將根據它所包含的圖像的大小來調整自身的大小;當AutoSize為False時,不論圖像有多大,組件將保持設計時的大小。如果組件比圖像小,那么只有一部分圖像是可見的。

3.Stretch屬性

當Stretch為True時,位圖圖像將根據組件的大小調整自身的大小,當組件大小改變時,上述三種文件也做相應變化。Stretch屬性對圖標沒有作用。

上述的AutoSize和Stretch屬性決定了圖像在窗口中的顯示尺寸。

圖3.5演示的3個Image分別為:AutoSize為True,AutoSize為False,Stretch為True的情形。可以看到,Image的原始尺寸比圖片寬,矮,在上面的屬性設置下,就會有不同的顯示效果。

圖3.5 AutoSize和Stretch的設置 3.2.2 Timer組件

在Delphi中,組件分可視組件和非可視組件。可視組件是指那些在運行期間仍然能顯示的組件,例如Label,Button,Image組件等。非可視組件是指那些在程序界面設計期間可見,而在程序運行時不可見的組件,例如在System頁上的Timer組件。

Timer組件能夠有規律地觸發OnTimer事件,發送信息給應用程序,它是編制應用程序時最為重要的組件之一。

1.Timer組件的屬性

Enabled屬性表示Timer是打開還是關閉。用Interval屬性設置兩個OnTimer事件間的間隔,單位是毫秒。將間隔設置為0相當于關閉計時器,Interval是Cardinal類型的,最大值可到4294967295,當然程序中一般不會把Interval設成很大的值。2.Timer組件的使用

Timer是獨立的對象,在啟動與Windows無關的邏輯和應用事件時極其有用。可以模擬時鐘或計時器,可視地顯示經過的時間;可以用作系統延時,Delphi提示信息出現只需在該區域停頓幾秒,就是Timer組件應用的一個例子;可以檢查系統環境、事件,根據結果進行響應;也可以在窗口中閃爍一段正文或圖像,提示某種操作或處理正在進行等等。

盡管Delphi的計時器每秒可以產生1000次激發,在編程中還必須注意程序對Timer觸發的響應。如果程序處理OnTimer事件的時間超過Interval的設定值,就可能錯過事件,因為當下一次觸發到來時,系統正忙于處理上一事件,則這次觸發就會被忽略。同時要注意其他的Windows應用程序是否會影響Timer的觸發。如果后臺正運行著一個占用處理器的程序,就可能會導致Timer的觸發不準確,從而使前臺程序運行出現錯誤。

這里要強調的是Timer組件是一個非可視組件,可以把它放置到窗體或者其他容器組件上的任何位置。3.實現游戲計時功能

在本章的游戲中,我們加入一個Timer組件,實現游戲的計時功能。

在窗體中加入一個Label組件,將此組件的Caption屬性設置為“使用時間”,然后從組件面板上選擇System頁中的Timer組件。

在Unit1中加入Form1的一個私有成員SpendTime,記錄用戶計算所用的時間。代碼如下所示:

private { Private declarations } SpendTime:Integer;在Form1的onCreate事件中加入如下代碼。將SpendTime設置為0,并將Timer1的Enabled屬性設置為False,使Timer1組件不能響應OnTimer事件;并將Timer1的Interval屬性設置為1000,表示當Timer1有效時,每間隔1000ms(即1秒)發生一次OnTimer事件:

procedure TForm1.FormCreate(Sender: TObject);var i:integer;begin //初始化,設置數組RandomData的長度為4 //并將每個數組元素初始化為零

setLength(RandomData,4);for i := 0 to 3 do RandomData[i]:=0;SpendTime:=0;Timer1.Enabled:=False;Timer1.Interval:=1000;end;然后在標題為“開始”的“開始”按鈕的OnClick事件中,加入如下所示的代碼,將Timer1的Enabled屬性設置為True,使Timer1組件有效,即現在Timer1能響應OnTimer事件,計時開始。并將SpendTime重新設置為0:

Timer1.Enabled:=True;Timer1.Interval:=1000;SpendTime:=0;//將SpendTime重新設為0 再在“計算”按鈕的OnClick事件句柄中,增加下面的語句,使Timer1無效:

Timer1.Enabled:=False;最后雙擊Timer1組件,創建Timer1的OnTimer事件句柄,在其中加入如下所示的代碼,將SpendTime加1,并設置Label5的Caption屬性:

procedure TForm1.Timer1Timer(Sender: TObject);begin SpendTime:=SpendTime+1;Label5.Caption:='使用時間:'+IntToStr(SpendTime)+'秒';end;這樣,每隔1秒鐘,程序就刷新一次使用時間。

3.2.3 設計初始界面

按住Shift鍵,然后單擊組件面板中Additional頁中的Image組件,這時該組件邊緣出現藍色的邊框,并且凹陷下去,表示可以在窗體上連續加入幾個Image組件。選擇好Image組件后,在窗體的左上角單擊,加入1個Image組件,然后依次向右單擊鼠標3次,再加入3個Image組件。最后再單擊組件面板中最左邊的箭頭。

為了排列這4個Image組件,先利用Shift鍵將它們同時選上,然后右擊,選擇Align命令,在隨后出現的Alignment對話框中的Horizontal選項組中選擇Space equally,在Vertical選項組中選擇Tops,表示這4個組件頂端對齊,水平方向上間距相等。

按照同樣的方法加入4個Label組件、3個Button組件和1個Edit組件。按照表3.1所示設置各個組件的屬性。

表3.1 各個組件的屬性

組件名 Form1 Label1 屬性名 Caption Caption AutoSize WordWrap Caption

屬性值 速算24

1.單擊“開始”按鈕,游戲開始,系統將發出4張撲克牌

False False

2.要求用戶利用撲克牌顯示的數字,通過加減乘除運算,以最快的速度得出24(可以使用括號),JQKA和“王”算做1。然后在文本框中寫好表達式,接

著單擊“計算”按鈕

Label2

Label3 AutoSize WordWrap Caption

False True

3.這時系統會計算輸入表達式的結果,告訴用戶是對還是錯了。在彈出的對話框中單擊“OK”按鈕,如果錯了可以再次輸入新的表達式,重復上一步。直

到您的表達式正確,這時系統會恭喜算對了!

Label4 AutoSize WordWrap Caption AutoSize Caption Caption Caption Text

False True 在下面輸入數學表達式

False 開始 計算 退出游戲 空

Button1 Button2 Button3 Edit1

現在同時選擇Label1,Label2和Label3,將它們左對齊,垂直方向等距離排列。將Button1,Button2和Button3左對齊,垂直方向等距離排列。

下面放置4個Image組件,用于放置4張紙牌的圖片。

先選擇Image1,然后切換到對象查看器中的屬性編輯器,選擇屬性選項頁中的Picture屬性,然后在Picture屬性值欄中雙擊,或單擊此屬性值旁邊的帶有省略號的按鈕,打開Picture Editor對話框,如圖3.6所示。然后單擊Load按鈕,彈出Load Picture對話框,在此對話框中選擇background.bmp文件。最后單擊OK按鈕,退出Picture Editor對話框。

圖3.6 指定圖片

使用同樣的方法,設定其他3個Image組件的Picture屬性。

保存我們的新項目,運行之后界面如圖3.7所示,與運行時的界面圖3.1稍有不同。這里是設計時界面,只有界面沒有事件響應。是程序創建過程中的一個步驟的檢驗。但是,這個程序還沒有什么具體的功能,為了讓游戲運行起來,必須添加代碼,創建相應的事件處理程序。

第3章 “速算24”撲克游戲--單元、異常、邏輯

????生成和建立程序????

???????

3.2.4 事件處理

需要添加?個事件:第一個用于響應單擊?開始?按鈕,在此事件中完成發牌,即隨機顯示圖片;第二個用于響應單擊?計算?按鈕,解析用戶在文本框中輸入的表達式,計算表達式的結果,并判斷表達式的結果是否等于??;第三個用于響應單擊?退出游戲?按鈕,退出游戲(程

序)。?

1.數據初始化

創建窗體的????????事件處理程序,在這里進行必要的初始化。?第一步先在Unit1中添加Form1的私有成員數組:

private

{ Private declarations }

RandomData:array of Integer;然后,在對象查看器中選中Form1,選中Event選項卡,在OnCreate一欄對應的右邊的空白欄中雙擊,創建OnCreate函數。添加如下代碼。

procedure TForm1.FormCreate(Sender: TObject);

var

i:integer;

begin //初始化,設置數組RandomData的長度為4

//并將每個數組元素初始化為零

setLength(RandomData,4);

for i := 0 to 3 do

RandomData[i]:=0;

end;這里使用一個for循環語句,i是循環變量,格式是:for循環變量:=初值to末值do循環體。你也可以借助Delphi的自動完成功能,在輸入for之后按下Ctrl+J鍵,生成如下代碼:

procedure TForm1.FormCreate(Sender: TObject);

begin

for := to do

begin end;

end;在上述代碼中,程序首先利用setLength函數設定可變數組RandomData的數組長度為4,然后,將數組的每一個單元都設置為0。這樣,就完成了數組的數據初始化工作。

2.“開始”按鈕的Click事件處理

(?)功能?單擊?開始?按鈕時,系統就隨機地發出?張紙牌,顯示在?個?????組件中。?

(?)代碼?首先,我們需要一個循環變量?,一個字符串變量存放隨機選取的圖片的文件名。?創建“開始”按鈕的OnClick事件處理程序,在begin前頭添加需要的變量,然后在此事件

中加入如下所示的代碼。

procedure TForm1.Button1Click(Sender: TObject);

var

i:integer;

filename:String;

begin

Randomize;//初始化隨機數

for i := 0 to 3 do

begin RandomData[i]:=Random(13)+1;//產生一個1到13的隨機數

filename:=IntToStr(RandomData[i])+'.bmp';//根據隨機數,得到文件名

//根據i的不同為不同的Image組件載入圖像文件

case i of 0 : Image1.Picture.LoadFromFile(filename);1 : Image2.Picture.LoadFromFile(filename);2 : Image3.Picture.LoadFromFile(filename);3 : Image4.Picture.LoadFromFile(filename);

end;

edit1.Text:='';

edit1.SetFocus;

end;

end;在Delphi內部,隨機數的產生實際上也是在一套算法的控制之下,Randomize函數用于初始化產生隨機數的種子,保證兩次產生的隨機數不同,而Random(i:integer)則利用初始化過后的隨機數種子產生一個1~i之間的隨機數。這里i設定為13,以配合撲克牌的張數13。

???????????????????用來將一個整數轉換成一個字符串,和上一章中的??????????????????的功能恰好相反。?我們已經預先準備了位圖文件,它們都是???形式,文件名則是利用數字????命名。??????中特殊的字符串運算符???將兩個字符串串聯起來,產生一個新的字符串,我們需要的位圖文件后綴是???,因此,在產生文件名的時候,在數字后面加上??????這個字符串。?????語句在上一章中已經講過,單擊?開始?按鈕后,準備接受用戶的輸入,然后利用????????方法,把焦點設置到?????上。????????是??????提供的方法之一,用于設置輸入

焦點到某個指定的組件。?

3.“計算”按鈕的OnClick事件

雙擊“計算”按鈕,創建此組件的OnClick事件響應句柄,然后在代碼編輯器中加入如下所

示的代碼,用于計算用戶輸入的表達式。

procedure TForm1.Button2Click(Sender: TObject);

var

result:integer;

answer:String;

begin

result:=TotalCompute(Edit1.Text);

if(result=24)then Application.MessageBox('您真行,我服了您!','對了',MB_OK)

else

begin answer:='您輸入的表達式的計算結果為'+IntToStr(Result)+'!';Application.MessageBox(PChar(answer),'錯了',MB_OK);

end;

end;這段程序根據自定義函數的計算結果判斷用戶的輸入正確與否,并且輸出相應的結果以提示

用戶。

在語句“result:=TotalCompute(Edit1.Text)”中用到了一個自定義的函數TotalComp-ute,我們用它來計算用戶輸入的表達式。現在我們還沒編寫這個函數的代碼,所以,目前這段代碼是無法運行的。沒關系,可以先把它用“//”注釋掉,然后隨便給 result賦一個值,測試這個事件處理程序的其他部分是否運行正常,例如:

//result:=TotalCompute(Edit1.Text);

result:=24;這樣,運行后,單擊“計算”按鈕后的顯示如圖3.8所示。

圖3.8 成功的提示信息

我們用一個??????類型的??????變量存放出錯信息,但是???????函數的第一個參數要求是?????(????????????????字符指針)類型,因此,我們用一個強制類型轉換將??????轉換

成?????。?4.“退出游戲”按鈕的OnClick事件

雙擊“退出游戲”按鈕,創建此組件的OnClick事件處理程序,然后在代碼編輯器中加入如

下所示的代碼,用于退出程序。

procedure TForm1.Button3Click(Sender: TObject);

begin

Close;

end;在上一章中我們提到可以用?????????????????????代替?????,但這里使用?????來結束程序的運行。這樣,可以通過????????????事件來指定在什么條件下窗體可以關閉。

第3章 “速算24”撲克游戲--單元、異常、邏輯

????生成和建立程序???????????5.OnCloseQuery事件

當調用?????方法來關閉窗體時,????????????事件發生。利用????????????事件來指定在什么條件下窗體可以關閉。????????????事件包含一布爾型的????????參量,可以用它來決定窗體是否關閉。????????的默認值為????。?可以利用????????????事件來詢問用戶是否真的希望馬上關閉窗體。?我們在這里彈出一個對話框,代碼如下所示:

procedure TForm1.FormCloseQuery(Sender: TObject;var CanClose: Boolean);begin if(MessageDlg('現在要退出游戲嗎?', mtConfirmation, [mbOk, mbCancel], 0)= mrOk)then canClose:=True else canClose:=False;end;MessageDlg是一種提示對話框,第一個參數是對話框詢問的訊息,是一個字符串;第二個參數則代表對話框的類型,mtConfirmation是一個TMsgDlgType的枚舉類型,表示這個對話框是個確認對話框。TMsgDlgType類型如下所示:

type TMsgDlgType =(mtWarning, mtError, mtInformation, mtConfirmation, mtCustom);以上定義的對話框類型分別表示:警告、錯誤、提示、確認和自定義類型。

第三個參數是TMsgDlgBtn類型的集合,這個集合包含了類型為TMsgDlgBtn的按鈕,TMsgDlgBtn的定義如下:

type TMsgDlgBtn =(mbYes, mbNo, mbOK, mbCancel, mbAbort, mbRetry, mbIgnore, mbAll, mnNoToAll, mbYesToAll, mbHelp);在我們的程序中,利用了一個集合[mbOK, mbCancle],表示在對話框中顯示兩個按鈕:OK和Cancel的組合。

最后一個參數是用來描述幫助索引的長整型變量,用來獲取提示用戶的幫助信息,這里我們沒有任何幫助信息,先不管它。??????????函數和用戶交互,返回一個????類型的數字,??????預先定義了一套數字,用來直觀地表示對話框返回信息。如果用戶單擊了??按鈕,這個對話框返回????,效果如圖???所示。?

圖3.9 關閉窗口時詢問用戶

現在,我們已經完成了程序的主體部分。??第3章 “速算24”撲克游戲--單元、異常、邏輯

????單元間的互相引用????????3.3.1 單元引用的概念

在第?章關于單元的知識里,我們已經知道??????可以定義不包含窗體的單元,它集中定義了程序中使用的函數,這一節里,我們就要實現這樣的一個單元,用來實現上面提到的????????????函數。?我們可以在任何單元中編寫自己的函數,當然包括與窗體相連的單元。可是我們常常需要用到一些常用的函數,這時最好是創建一個不與窗體相連的獨立單元,用它來容納自己的函數,這稱為獨立的單元文件。當創建了不與窗體相連的獨立單元文件后,項目中的其他單元就能很容易地共享這些函數,其他項目也可以很容易地調用這些函數了。?對于單元間的引用,要用到????語句。?3.3.2 uses語句

????語句告訴程序在最終的執行代碼中需要用到哪些函數和過程。??????會自動把一些必須的單元包括進來,例如???????,????????,????????等。對于我們自己編寫的單元,如果程序中使用了該單元的函數或代碼,也需要包括在????部分中。?????語句具有兩種類型:公有引用和私有引用。?在?????????部分包含的????語句代表的是本單元的公有引用,就是說,這部分的引用可以被其他引用本單元的單元繼承性地引用。在?????????部分的????語句應包含在?????????部分中的代碼所需要的單元,去掉那些??????可以自動加入到程序中的單元。?在?????????部分包含的????語句代表的是本單元的私有引用,就是說,這部分的引用只能被本單元內部使用。在??????????????部分的????語句應只包含在??????????????部分中的代碼所需的單元的名字。?對于單元間的引用,要避免交叉引用。假設有兩個單元?和?,如果?出現在?的?????????部分的????語句中,那么單元?便不能出現在單元?的?????????的????語句中。因為這樣會產生對單元的循環訪問,編譯時會出現錯誤信息。?3.3.3 創建另一個單元

創建一個不與窗體相連的單元文件的方法是,首先選擇主菜單的????命令,然后選擇???命令,此時??????彈出一個?????????對話框,如圖????所示。在此圖中選擇???選項卡中的????,然后單擊??按鈕。此時??????自動為我們創建一個名為?????的獨立單元文件,并顯示在代碼編輯器中,我們只需在此加入函數即可。?

圖3.10 New Items對話框

單元創建之后,就需要實現單元之間的互相引用。這里有兩種方法:?(1)直接在Unit1中寫入uses Unit2,代碼如下所示:

var Form1: TForm1;implementation uses Unit2;(2)選擇主菜單的File | Use Unit命令,此時Delphi彈出Use Unit對話框,如圖3.11所示,在此窗口中列出當前文件沒有連接的所有文件,只需選擇需要連接的文件即可。當選擇了某一文件并單擊OK按鈕后,當前文件就包含了對所選文件的引用。

圖3.11 Use Unit對話框

如果當前文件已經連接了當前項目中所有其他文件,選擇????????命令后,就會彈出如圖????所示的信息窗口,告訴程序員當前文件已經連接了當前項目中所有其他文件。?

圖3.12 Information對話框

此時再編譯,程序就沒有任何錯誤了。?現在我們已經創建了?????,它將用作我們的數學函數定義單元。在開始定義這個單元之前,需要先了解一下關于??????的異常處理機制。?第3章 “速算24”撲克游戲--單元、異常、邏輯

3.4 異 常 處 理

3.4.1 異常處理的概念 在應用程序開發中如何檢測、處理程序的運行錯誤是一個很重要的問題。在 Delphi 的IDE(集成開發環境)中提供了一個完善的內置調試器,可以發現大部分程序錯誤。但并不是所有的錯誤都可以被發現,而且當程序涉及到與外設的數據交換或操作外設,如要求用戶輸入、讀寫磁盤等時,錯誤的發生是程序無法控制的,如輸入非法字符、磁盤不能讀寫等。這些情況不僅會導致應用程序異常中止,而且可能引起系統的崩潰。針對這些問題,Delphi提供了一套強大的異常處理機制。巧妙地利用它,可以使程序更為強健,使用更為友好。

Delphi異常處理機制建立在Protected Blocks(保護塊)的概念上。所謂保護塊是指用保留字try和end封裝的一段代碼。保護塊的作用是當應用程序發生錯誤時自動創建一個相應的Exception(“異常”類)。程序可以捕獲并處理這個“異常”類,以確保程序的正常結束以及資源的釋放和數據不受破壞。如果程序不進行處理,則系統會自動提供一個消息框。“異常”類是Delphi異常處理機制的核心,也是Delphi異常處理的主要特色。Delphi提供的所有“異常”類都是類Exception的子類。用戶也可以從類Exception派生一個自定義的“異常”類。

3.4.2 資源保護方式

回收分配的資源是確保程序健壯性的一個關鍵。但默認情況下異常發生時程序會在出錯點自動退出當前模塊,因此需要一種特殊的機制來確保即使在異常發生的情況下,釋放資源的語句仍能被執行,而Delphi的異常處理正提供了這種機制。

Delphi提供了一個保留字finally,用于實現資源的保護。

{分配資源}

try {資源使用情況} finally {釋放資源}

end;try?finally?end就形成了一個資源保護塊。finally后面的語句在任何情況下(不論程序是否發生異常)都會執行。

在異常保護的情況下,當異常發生時,系統會自動彈出一個消息框,在框中顯示異常的消息。退出當前模塊后異常類自動清除。

3.4.3 異常響應方式

異常響應為開發者提供了一個按需進行異常處理的機制。try?except?end形成了一個異常響應保護塊。與finally不同的是:正常情況下except 后面的語句并不被執行,而當異常發生時程序自動跳到except處,進入異常響應處理模塊。當異常被響應后異常類自動清除。

下面是異常響應方式的一般代碼:

try {程序正常功能} except on ESomething do {響應特定異常} else {提供默認響應} end;保留字on?do用于判斷異常類型。必須注意的是:except后面的語句必須包含在某一個on?do模塊中,而不能單獨存在。這是又一個與finally不同的地方。

3.4.4 提供默認響應

在異常響應模塊中,一般我們只對希望響應的特定異常進行處理。如果一個異常發生而響應模塊并沒有包含對它的處理代碼,則退出當前響應模塊,異常類仍被保留。

為了保證任何異常發生后都能在當前響應模塊中被清除,可以定義默認響應:

try {程序正常功能} except on ESomething do {響應特定異常} else {提供默認響應} end;由于else可以響應任何異常,包括我們一無所知的異常,因此在默認響應中最好只包括諸如顯示一個消息框之類的處理,而不要改變程序的運行狀態或數據。

第3章 “速算24”撲克游戲--單元、異常、邏輯

3.5 數學邏輯單元(1)

此游戲程序最關鍵的地方是如何將用戶輸入的字符串表達式解析成數學表達式。為了使程序結構清晰明了,我們將此解析代碼和程序的主代碼分開,單獨編寫成一個單元。

3.5.1 算法設計

游戲的難點是如何將一字符串形式的表達式解析成計算機能計算的算術表達式。例如對于字符串“3^(4*(9+4))”,如何讓計算機解析、計算。

我們的想法是按照數學四則運算規則,先逐層進入最里層的括號,然后在括號內部計算乘方,接著進行乘(除)法運算,最后按順序進行加(減)運算,當本層括號內部計算完成后,返回結果,去掉括號內部數據,退出到下一級括號(如果有)內進行計算。

這里面涉及的技術細節主要有下面幾點:

(1)層層剝離括號,然后從最里層的括號開始計算。(2)對于每一個運算符號,找到符號兩側的數字,形成一個計算式。

(3)每一個子計算式完成后,運算結果返回到原始數列中,作為子串的一部分,繼續進行上述計算。

3.5.2 字符串的相關函數

在游戲中,用戶輸入的都是字符數據,我們需要從這些字符中分析得到數字和運算符號,因此要用到與字符串操作有關的函數。

function Pos(sub , all:string):integer;這個函數含有兩個參數:sub表示要查找的字符,all表示原字符串。函數在字符串all中尋找指定的字符sub的位置,如果字符串中不存在sub字符,則函數結果為0。

function LastDelimiter(sub,all :string):integer 這個函數含有兩個參數:sub表示要查找的字符,all表示原字符串。函數返回在字符串all中所有查找到的指定字符sub的最后一個的位置,如果字符串中不存在sub字符,則函數結果為0。

function Copy(allstring:string;first,length:integer):string 這個函數的3個參數的含義分別是:allstring代表原來的字符串,first表示拷貝開始的位置,length表示要拷貝的子串長度。函數返回拷貝成功的子串。

procedure Delete(str:string;ppos,length:integer)這個過程用于刪除字符串中的一段字符。參數str代表將要操作的字符串,ppos代表開始刪除的位置,length表示將要刪除多少個字符。function Length(S): Integer;Length函數返回字符串S的長度。

function Trim(const S: string): string;overload;function Trim(const S: WideString): WideString;overload;Trim函數返回字符串S去掉前面和后面的空格后的字符串。

下面的例子給出一個綜合利用字符串處理函數編寫的一個處理特定字符串的函數,它的功能是:輸入一個字符串后,可以返回字符串中兩個單括號之間的子字符串,并去掉前面和后面帶著的空格:

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 算法的代碼編寫

基于上述的考慮和知識基礎,我們在聲明部分定義下列幾個主要函數:

(1)AnyLastPos函數定位最后一個算術運算符的位置。

function AnyLastPos(Str:String):integer;(2)AnyFirstPos函數定位最先一個算術運算符的位置。

function AnyFirstPos(Str:String):integer;(3)AnyFirstF函數判斷最先出現的符號是+號、-號、*號還是/號。

function AnyFirstF(Str:String):Char;(4)SubCompute函數用于計算不帶()號的加、減、乘、除運算。

function SubCompute(Str:String):integer;(5)TotalCompute函數用于計算表達式的結果。

function TotalCompute(Str:String):integer;1.尋找最后一個算術運算符

定義4個整數變量SubPos,PluPos,MulPos,DivPos,在給定的字符串中尋找+,-,*,/的最后位置,將這些位置存儲在上述的4個變量中,然后比較4個符號出現的位置,得到數值最大的運算符;在返回的結果中,返回這個運算符的位置。

程序代碼如下所示:

function AnyLastPos(Str:String):integer;var SubPos:integer;PluPos:integer;MulPos:integer;DivPos:integer;Pos:Integer;begin //定位字符串中最后一個運算符的位置

SubPos:=LastDelimiter('-',Str);PluPos:=LastDelimiter('+',Str);MulPos:=LastDelimiter('*',Str);DivPos:=LastDelimiter('/',Str);Pos:=SubPos;if(Pos

分別在給定的字符串中尋找+,-,*,/第一次出現的位置,然后比較4個符號出現的位置,得到數值最小的運算符。在返回的結果中,傳遞的是這個運算符的位置。

程序代碼如下所示:

function AnyFirstPos(Str:String):integer;var SubPos:integer;PluPos:integer;MulPos:integer;DivPos:integer;ForPos:integer;FirstPos:integer;begin //定位字符串中最先一個運算符的位置

SubPos:=Pos('-',Str);PluPos:=Pos('+',Str);MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);ForPos:=Pos('^',Str);FirstPos:=200;if(SubPos=0)then //如果沒有-號

SubPos:=200;//將SubPos設置成一個不可能的值

if(PluPos=0)then //如果沒有+號

PluPos:=200;//將PluPos設置成一個不可能的值

if(MulPos=0)then //如果沒有*號

MulPos:=200;//將MulPos設置成一個不可能的值

if(DivPos=0)then //如果沒有/號

DivPos:=200;//將DivPos設置成一個不可能的值

if(ForPos=0)then //如果沒有^號

ForPos:=200;//將ForPos設置成一個不可能的值

if(FirstPos>SubPos)then FirstPos:=SubPos;if(FirstPos>PluPos)then FirstPos:=PluPos;if(FirstPos>MulPos)then FirstPos:=MulPos;if(FirstPos>DivPos)then FirstPos:=DivPos;if(FirstPos>ForPos)then FirstPos:=ForPos;

AnyFirstPos:=FirstPos;//結束函數,返回位置

end;第3章 “速算24”撲克游戲--單元、異常、邏輯

3.5 數學邏輯單元(2)

3.得到最先出現的運算符類型

這個函數的返回結果是Char類型,代表這是一個字符變量。實際上,它返回的是+、-、*、/ 這4個符號中最早出現的一個。

程序分別尋找4個符號最早出現的位置,然后判斷最先出現的是哪一種符號,再根據符號類型返回代表運算符的字符。

在具體的實現過程中,因為我們要得到最先出現的運算符,所以判斷的是每次尋找后各個運算符的位置的最小值。如果不存在這個運算符,則將代表這個運算符位置的相應變量設置為200。對于本程序來說,這是一個搜索過程中不可能達到的值,這樣就排除了這個位置的繼續比較的可能。

程序代碼如下所示:

function AnyFirstF(Str:String):Char;var SubPos:integer;PluPos:integer;MulPos:integer;DivPos:integer;Operator:char;tempPos:integer;begin SubPos:=Pos('-',Str);PluPos:=Pos('+',Str);MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);

if(SubPos=0)then //如果沒有-號

SubPos:=200;//將SubPos設置成一個不可能的值

if(PluPos=0)then //如果沒有+號

PluPos:=200;//將PluPos設置成一個不可能的值

if(MulPos=0)then //如果沒有*號

MulPos:=200;//將MulPos設置成一個不可能的值

if(DivPos=0)then //如果沒有/號

DivPos:=200;//將DivPos設置成一個不可能的值

Operator:='-';tempPos:=SubPos;if(tempPos>PluPos)then begin tempPos:=PluPos;Operator:='+';end;if(tempPos>MulPos)then begin tempPos:=MulPos;Operator:='*';end;if(tempPos>DivPos)then begin tempPos:=DivPos;Operator:='/';end;

AnyFirstF:=Operator;//結束函數,返回位置 end;4.計算不帶括號的運算表達式

做完上述工作后,我們可以開始進行一些實際的運算了。

包括加、減、乘、除、乘方運算的表達式的程序算法如下所示:

(1)尋找乘方符號“^”,如果存在,則計算一次乘方,去掉計算過的部分,接著循環查找和計算子串的乘方。

(2)尋找乘號“*”或者除號“/”,如果存在,則計算一次乘(除)法,去掉計算過的部分,接著循環計算子串的乘除法。

(3)尋找加號“+”或者減號“-”,如果存在,則計算一次加(減)法,去掉計算過的部分,接著循環計算子串的加減法。

上述算法是嚴格按照順序進行的,它體現了數學運算中的優先關系,經過上述的計算,子字符串被分解,計算完畢。

無論是乘方、乘除法還是加減法,內部實現的邏輯是基本一致的。下面,我們設定有一個運算表達式: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;DivPos:Integer;Fuhao:Char;begin Middle:='';Mul2:='';Right:='';

//定位第一個^號位置,計算乘方

First:=Pos('^',Str);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;Middle:=FloatToStr(IntPower(StrToInt(Mul1),StrToInt(Mul2)));Str:=Left+Middle+Right;First:=Pos('^',Str);end;

//定位第一個*號或/號的位置

MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);First:=MulPos;if(MulPos>DivPos)then First:=DivPos;if((DivPos=0)and(MulPos<>0))then begin First:=MulPos;DivPos:=2000;// 將除號所在位置設置成一個大于MulPos但又不可能的值

end;if((DivPos<>0)and(MulPos=0))then begin First:=DivPos;MulPos:=2000;// 將乘號所在位置設置成一個大于DivPos但不可能的值

end;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(MulPos>DivPos)then Middle:=IntToStr(StrToInt(Mul1)div StrToInt(Mul2))else Middle:=IntToStr(StrToInt(Mul1)*StrToInt(Mul2));Str:=Left+Middle+Right;

MulPos:=Pos('*',Str);DivPos:=Pos('/',Str);First:=MulPos;if(MulPos>DivPos)then First:=DivPos;

if((DivPos=0)and(MulPos<>0))then begin First:=MulPos;DivPos:=2000;// 將除號所在位置設置成一個大于MulPos但又不可能的值

end;if((DivPos<>0)and(MulPos=0))then begin First:=DivPos;MulPos:=2000;// 將乘號所在位置設置成一個大于DivPos但不可能的值

end;end;//定位+、-號首先出現的位置

First:=AnyFirstPos(Str);if(First=200)then //如果沒有+、-號,則可以直接返回結果

begin SubCompute:=StrToInt(Str);exit;end;Fuhao:=AnyFirstF(Str);//確定首先出現的符號是+號還是-號

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;程序執行過程如下所示:

(1)定位字符串中第一個乘方符號“^”的位置First。這個式子中的First為4。

(2)如果存在乘方符號,即First不等于0,則繼續進行計算,否則退出循環。

(3)進入循環體內部,得到“^”前面的子串tempStr(“3+2”),尋找tempStr中的最后一個運算符temp(這里是“+”),則Temp和First之間的字符就是乘方符號的第一個參數(“2”)。

(4)同樣的邏輯,得到“^”后面的子串tempStr(“5/4”),尋找tempStr中的第一個運算符位置temp(“/”),則Temp和First之間的字符就是乘方符號的第二個參數(“5”)。

(5)去掉乘方符號和兩個參數,得到左側子串left(“3+”)和右側子串right(“/4”)。

(6)利用這兩個參數和乘方符號,計算乘方,將結果返回,并插入在left和right之間,得到一次計算后的新字符串(“3+32/4”)。

(7)判斷新串內部是否包含“^”,如果包含,則返回到步驟(3),不包含則進入下一種運算。

第3章 “速算24”撲克游戲--單元、異常、邏輯

3.5 數學邏輯單元(3)5.計算整個表達式的值

TotalCompute函數利用循環,找到最內層的一對括號,然后調用SubCompute函數處理這一對括號中的表達式。SubCompute函數處理的表達式中已經沒有括號了,因此SubCompute只需處理乘方、加、減、乘、除,返回結果,形成新的字符串。

當整個字符串縮減至空值時,整個表達式計算完成。

程序代碼如下所示:

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);//進入下面的計算

Middle:=IntToStr(temp);

Str:=LeftStr+Middle+Right;First:=LastDelimiter('(',Str);end;

Result:=SubCompute(Str);end;end.在程序中,“計算”按鈕的OnClick事件處理程序中調用TotalCompute函數。函數中使用了一些數學函數和定位字符串的函數,這些函數Delphi已經在相應的系統單元中進行了定義,我們需要把這些系統單元包括到文件里面:

uses Sysutils,Math;將前面調用TotalCompute的注釋去掉,把代碼改回:

procedure TForm1.Button2Click(Sender: TObject);var result:integer;answer:String;begin result:=TotalCompute(Edit1.Text);if(result=24)then Application.MessageBox('您真行,我服了您!','對了',MB_OK)else begin

第二篇:delphi復習資料

題型:

填空題20×1 簡答題5×6 程序填空題11×2 編程題2×14 資料整理的不是完全完整,結合這些重點可以在書上再仔細復習。希望好好復習,大家都能通過!

第一章Delphi簡介

1.1delphi概念 Delphi的主要特點: Borland公司的Pascal編譯器 Delphi以object Pascal為編程語言 Delphi充分發揮了windows的強大功能 Delphi提供了豐富的32位可視組件庫

Delphi在數據庫和網絡處理功能方面是同類產品中最強的

1.2delphi7集成開發環境

主窗口:包括菜單欄,工具欄及組件欄; 對象游覽器:包括屬性頁和事件頁; 對象樹性列表; 窗體設計器; 代碼編輯器;

1.3delphi程序的基本結構

擴展名為dpr的是項目文件;擴展名為pas的單元文件;擴展名為dfm的是窗體文件

單元文件的格式如下:

單元頭:該單元指定單元的名稱

接口部分:該部分從保留字interfact開始,到保留字implementation之前結束。接口部分可以有uses語句,還可以用來聲明常量,數據類型,變量,過程和函數等。其中uses語句必須緊跟在保留字interfact之后。在整個程序中都可以被訪問

實現部分:這些聲明可以在本單元中被訪問,不可以在其他單元中被訪問,類的方法必須在實現部分實現

初始化部分:從保留字implementation開始,到保留字finalization之前結束。一個單元中可以沒有該部分。

結束部分:一個單元中只有出現了初始化部分,才可以有結束部分

第二章Object Pascal語言基礎 2.1詞法符號 保留字

標識符:1標識符由字母,數字或下劃線組成 2標示符的第一個字符必須是字母或下劃線 3標識符的長度不應超過255個字符 4不能將保留字用作標識符 5標識符不區分大,小寫

標準標識符是可以重新定義的,而保留字卻不允許重新定義

因system單元是自動應用的,不必也不允許在引用部分列出system單元 Absolute指令字用于指示相同類型的另一標識符存放在同一段內存區域中 2.2常量和變量

布爾常量是指false和true這兩個值 用#引導一個整數,整數表示該字符的ASCII碼 用‘’‘’表示單引號字符 2.3簡單數據類型

數據類型分為簡單數據類型,字符串類型,結構類型,指針類型,過程與函數類型和可變類型等是一種常見的分類方法

有序數據類型特點:

1、數據的分布是離散的;

2、除了第一個元素外,其他任何元素都有一個前驅元素;

3、除了最后一個元素外,其他任何元素都有一個后繼元素

關系運算符號:=,<>,>≡,>,<≡,< 整型數的邏輯運算符:not,and,or,xor 左,右移位運算符:shl,shr 基本字型有ansichar和widechar Pascal語言提供的自變量為實型的標準函數由: 1絕對值函數abs(x):函數值為x的絕對值 2平方函數sqr(x):函數值為x的平方

3正弦函數sin(X):函數值為x的正弦,其中x的單位為弧度 4余弦函數cos(x):函數值為x的余弦,其中x的單位為弧度 5反正切函數arctan(x):函數值為x的正反切,函數值的單位為弧度 6指數函數exp(x):函數值為指數e 的x次方 7對數函數in(x):函數值為x的自然對數 8平方根函數sqrt(x):函數值為x的平方根

9舍入函數round(x):對實數x作四舍五入,結果為整數 10截尾取整函數trunc(x):截去實數x的小數部分,結果為整數 object pascal提供了豐富的日期時間處理函數,常用的有: 1date0:函數返回系統當前日期,無參數,返回數據是tdate time型 2time0:函數返回系統當前時間,無參數,返回數據是tdate time型 3now0:函數返回系統當前日期和時間,無參數,返回數據是tdate time型 4strtodte(日期字符串):字符串轉換為日期時間函數,返回數據是tdate time型

2.4結構類型 結構數據: —集合類型(set)—數組類型(arry)—記錄類型(record)—文件類型(file)—類類型(class)

—類引用類型(class reference)—接口類型(interfact)

object pascal中規定了基類型只能是不超過265個有序值的集合,集合元素的敘數值必須介于0~~255之間

集合運算有交(*),并(+),差(—),運算對象是兩個相同類型的集合,運算結果也是集合。例如,若有為[1,3,5],y為[3,4,5],則x*y為[3,5],x+y為[1,3,4,5],x-y為[1] 數組的定義:Type arry [indextype。。,indextypen] of basetype ①對于通用字符串類型string,指定其最大長度(0------255)。此時string型被視為shortstring型

②shortstring型不是以null(空字符#0)作為字符串的結果標志,而是將長度保存在字符串數組下標為0的儲存單元中 ③ansistring以full結束

記錄的定義: Type 記錄類型標識符=record 域1:類型1 域2:類型2。。。。域n:類型n 2.6語句流程 語法形式: 輸入語言

Read([文件變量]變量列表)

Readln([文本文件變量]變量列表)有回車 省略文本變量參數表示從鍵盤輸入中讀取數據 輸出語言

Write([文件變量]輸出項表)

Writeln([文本文件變量]輸出項表)有回車

注釋和編譯指令 //單行注釋內容 {注釋內容}(*注釋內容*)

Case語句的語法格式: Case選擇表達式of 常量1:語句1 常量2:語句2。。。。

常量n-1:語句n-1 [else語句n;] End;

保留字case后的選擇表達式,其值必須是有序類型,如整型,字符型,布爾型,枚舉型或子界型 P45頁程序

While語句的執行過程是:先計算布爾表達式的值,當值為true時,執行循環體中的語句序列,然后重新計算布爾表達式的值,若仍為true則再執行一遍循環體

While語句的特點是先判斷條件,當條件為true才執行。當第一次條件為false時,循環次數為0

Repeat語句的執行過程是:先執行repeat到until之間的語句,然后計算布爾表達式的值,若為false,則再執行repeat到until之間的語句,若為true則推出循環體

Break過程,可使程序的執行流程立即退出該層循環 Continue過程將使程序直接轉入下一次循環 2.7過程與函數

Procedure過程名(參數表)

Function函數名(參數表):返回數據類型 過程由過程首部、局部聲明部分和過程體組成。函數由函數首部、局部聲明部分和函數體組成。

參數的傳遞如下:

1值參數聲明時,形參前面無任何修飾

2變量參數聲明時 變參傳遞的是一個變量的地址,即實參把地址傳遞的是一個變量的地址,即實參把地址傳遞給變參,變參和實參指向的是同一地址空間。在過程和函數中對變參的修改直接影響實參 3常量參數聲明時,形參的前面用保留字const修飾

過程和函數重裁是指定義多個名稱相同,而參數列表不同的過程和函數。編譯器根據調用時實參表中的參數個數和類型,自動匹配一個重裁的過程或函數。重裁過程或函數使用默認參數可能會導致二義性錯誤 2.8程序與單元的結構 單元結構: 1單元首部

2接口部分:定義的這些標識符可以被引用該單元的程序訪問 3實現部分:在實現部分定義的標志符不能被其他單位或程序訪問 4初始部分 5終結部分

2.9標識符的作用域

標識符的作用域是指其在程序中起作用的范圍。

單元中接口部分定義的標識符包括數據類型,類,常數,變量,過程和函數導等 他們在引用該單元的程序(項目文件,其他單元)中都可以被訪問

第三章 Delphi中的面向對象 3.1面向對象程序設計概述

將具有相同屬性和行為的對象抽象為類,每個對象都屬于某個類。通過繼承關系構成類的層次結構,子類可以直接繼承父類的性質和功能。3.2類與對象

類是具有相同或相似屬性和行為的一組對象的共同描述,是對相似對象建立的模板。

對象由屬性和方法構成。屬性是描述對象靜態特征的一組數據想:方法描述了該類對象動態特征的一個操作序列,體現對象的行為特征或功能。定義類:type 類名=class 數據成員

成員函數或過程 End;

注意:在函數或過程名前必須帶有類名。Procedure Circle.Draw; 聲明對象一般形式為:var 對象名:類名; 訪問對象成員:對象名.成員

構造函數和析構函數的定義,作用和特點:

構造函數是專用的創建對象和初始化對象的成員函數。定義時用保留字constructor,函數名通常為create。在定義的構造函數中,不僅可以為類對象分配內存空間,而且可以打開文件或數據庫讀取數據或控制設備復位。析構函數是專用的刪除對象和為對象進行善后處理的成員函數。定義時用保留字destructor,函數名通常為Destroy。在析構函數中,不僅可以釋放相應的內存資源,還可以保存數據信息,關閉文件或者數據庫,控制設備復位并關機。3.3類成員的訪問權限

封裝是把一組數據和與這組數據有關的操作集合組裝在一起,形成一個能動的實體,也就是對象。

訪問權限分為:private:私有數據成員、成員函數、過程。不能被類所在單元以外的程序訪問,但本單元是可見的。

Protected:保護??。被該類及該類的所有派生類訪問,并成為派生類的私有成員。

Public:共有??。被該類以外的類訪問。

Published:公布??。在設計期間的對象觀察器窗口中可見。

Automated:自動??。用于響應對象鏈接與嵌入自動化類型信息的公共接口。3.4繼承

繼承的實質是在既有類的基礎上構造新的類,即新類從一個或者多個已有類中繼承數據和方法,同時增加或重新定義數據和方法,由此構造出一個新的類型,稱為派生類。已有的類稱為基類。繼承的主要目的是實現代碼的重用。派生類的定義:type 派生類=class(基類){派生類新增或改寫部分} End;

派生類的構造和析構函數:在派生類構造函數的開始部分,使用inherited保留字來調用基類的構造函數,首先初始化基類的成員,然后構造派生類的特有成員。在派生類的析構函數的結尾部分,使用inherited保留字來調用基類的析構函數,最后釋放基類的成員部分。

構造函數越上層越早被調用,析構函數越下層越早被調用。3.5多態性

多態性是指同一的操作,在不同的對象中具體實現過程不同。Object Pascal 支持兩種多態性和運行時的多態性。編譯時的多態性通過重載來實現,運行時的多態性用虛方法來實現。

重載函數或者過程用保留字overload來說明。例如:Function max(x:integer):integer;integer; 虛方法的定義如p79 虛方法與動態方法的區別:在運行時才能確定對象方法的調用地址,這種調用方法為動態聯編。虛方法與動態方法在功能上是等價的,不同在于虛方法額調用速度比較快,動態方法的代碼比較少。

抽象類與抽象方法:使用指令字abstract說明,則該方法稱為抽象方法,包含抽象方法的類稱為抽象類。定義:procedure 過程名;virtual;abstract;

第四章

4.1 VCL基礎

四種基本的組件類型:標準組件,自定義組件,圖形組件,非可視組件。圖形組件與標準組件的的區別在于:①標準組件可以獲得輸入焦點,即可用Tab鍵依次獲得焦點;圖形組件不能獲得輸入焦點。②標準組件可以包含其他組件,即可以是其他組件的父類;圖形組件不能包含其他組件。③標準組件具有一個WINDOWS句柄,圖形組件沒有WINDOWS句柄。

4.2窗體設計

窗體組件的屬性值設置為 組件名.屬性:=屬性值。重點看一下caption、visible、hint。

窗體的方法和事件詳見P91.4.3常用VCL組件

對于memo組件的編程填空要注意。列表框組件(listbox)的常用屬性見P104 4.4菜單設計

對菜單項可以指定其加速鍵,方法是在菜單項的Caption屬性中,在要作為加速鍵的字母前添加符號“&”,則運行時該字母帶有下劃線,按下Alt+加速字母鍵就執行此菜單項。

4.6對話框的使用

Showmessage過程:調用Showmessage過程會彈出一個簡單的對話框,對話框上顯示提示信息及“確定”按鈕,單擊該按鈕,就關閉對話框。

Inputbox函數:調用Inputbox函數顯示一個能夠接受喲娜防護輸入數據的對話框,并返回用戶輸入的數據值。

Inputquery函數:與Inputbox函數最大的不同是他的返回值是一個邏輯值。

第五章 5.1程序調試

錯誤的種類及處理方式:

1、語法錯誤:沒有遵守語言的語法規則而產生。

2、運行錯誤:程序在執行過程中發生了錯誤。程序試圖打開一個不存在的文件或試圖修改一個只讀文件,程序運行過程中出現除零錯誤或用戶輸入了非法數據等。

3、邏輯錯誤:運行的結果與設想的結果不同。

解決邏輯錯誤可以從三步驟來解決:猜測出程序可能出錯的地方,并在此設置斷點。讓程序執行到斷點停止運行,觀察所有中間變量及對象內容。讓程序單步運行,同時觀察每一個變量及對象內容的變化。

事件變量和相關數據的值:提示文本,watch list窗口,evaluate 窗口。5.2異常保護和處理

1、異常保護與try?finally?end;語句 Try ? //被保護的代碼塊 Finally ? //處理語句 End;

2、響應異常和try?except?end;語句 Try //以下為保護代碼塊 ?

If <異常條件> raise<異常對象> Except //以下為異常處理快

On <異常類1> do <處理過程1或語句1> On <異常類2> do <處理過程2或語句2> On ?

Else <其他處理過程或語句> End;

通過繼承類exception可以自定義新的異常類。

第6章 Delphi7與數據庫

6.1數據庫簡介 數據庫可以長期存儲、有組織、可共享的數據集合。

數據庫系統(database system,DBS)是指具有數據管理功能的計算機系統。它一般由數據庫、數據庫管理系統和應用系統構成。

數據庫系統根據的組織方式主要分為層次數據庫系統、網狀數據庫系統、關系型數據庫系統很面向對象數據庫系統等幾類

Delphi支持關系型數據庫,關系型數據庫由表組成。標的定義了事物的一組屬性數據,稱為記錄。表的列定義了事物的某種屬性,稱為字段。6.2 Delphi7的數據庫訪問機制

Borland推出了一個數據庫引擎(borland database engine,BDE)BDE管理器(BDE Administrator)是設置和管理BDE的工具,它可以用來管理BDE中的數據庫別名和驅動器。Datebase Desktop的使用:

1、定義數據庫別名

2、設置工作目錄及私有目錄

3、建立數據表結構

4、保存數據表文件

5、建立索引(1)建立主索引(2)建立次索引

6、設置有效性檢查

7、設置口令

8、設置參照完整性

9、輸入部分數據

數據庫游覽器可用于定義數據庫別名、查詢或編輯數據庫中的各類信息,如數據庫的參數設置、各類據表文件的結構及數據,也可以使用SQL語句進行查詢 6.3數據庫組件

使用TTable組件連接并顯示數據表的一般步驟

1、把一個TTable組件放到窗體上

2、TableName屬性指定要訪問的表

3、TDataSource組件放到窗體上,設置DataSet屬性指向該TTable組件

4、把數據控制組放到窗體上,設置TDataSource屬性指向該TDataSource組件

5、把TTable組件的Active屬性設為True Tablel.Fields[0].AsString:=Editl Edit.Text Editl.Text= Tablel Fields [0].AsString Editl.Text:= Tablel.FieldByName(‘Name’).AsString 當表結構改變引起字段索引號改變時,就要修改相應的程序,所以使用第二種方法比較好。

DataSet屬性:表明于當 前數據源組件相聯系的數據集組件對象的名字

Enabled屬性:如果Enabled屬性值為True(默認值),數據控制組件將顯示數據:如果Enabled屬性值為False,則所有與此數據源組件相連的數據控制組件都將不顯示任何數據。

Columna屬性用于指定TDBGrid對象中各欄目的特征 6.4 TField對象的使用

動態字段對象與永久字段對象的概念,區別,使用場合:Delphi會為數據中的每一個字段自動生成一個動態的字段對象。數據集的結構和其他信息改變,當應用程序重新打開這個數據集時,就會基于最近的結構和信息重建所有的字段對象。當數據集關閉時,這些對象也跟著取消。

動態對象的最大特點是適應性強,缺點是要想改變字段的顯示屬性、數據格式就要編寫代碼,不能把某些字段暫時隱去,也不能增加新的字段。

永久字段最大的好處是可以在設計時設置它的屬性。可以選擇部分字段,增加新的字段。再永久字段對象列表中刪除某些需要保護的字段,避免用戶訪問這些字段;在數據庫查詢或特定數據表的字段基礎上定義新的字段,代替現存的字段;改變原有的字段的顯示和編輯屬性。6.5 數據集的操作 數據集的打開與關閉:

1、設置Active屬性 Table.Active:=True;//打開數據集,數據集組件對數據表進行讀寫操作。Table.Active:=False;//關閉數據集,數據集組件不能對數據表進行讀寫操作。

2、調用Open和Close方法 Table1.Opene//打開數據集和 Table1.Close//關閉數據集。移動記錄指針:

1、Bof屬性:如果Bof為True,表明當前記錄指針所處的位置為數據集的第一條記錄;反之,則不是第一條記錄。

2、Eof屬性:如果Eof為True,表明當前記錄指針所處的位置為數據集的最后一天記錄;反之,則不為最后一條記錄。

3、First方法:將記錄指針移至數據集的第一條記錄處,并使之成為當前記錄,同時將Bof屬性值設置為True。

4、Last方法:將記錄指針移至數據集最后一條記錄處,并使之成為當前記錄,同時將Bof屬性設置為True。

5、Next方法:將記錄指針后移一條記錄,并使之成為當前記錄。如果記錄指針指向了數據集的最后一條記錄,將Eof屬性設置為True。

6、Prior方法:將記錄指針前移一條記錄,并使之成為當前記錄。如果記錄指針指向了數據集的第一條記錄,將Bof屬性設置為True。

7、MoveBy方法:將記錄指針從當前記錄開始向后或向前移動若干條記錄。格式如下:function MoveBy(Distance:Integer):Integer;

限制記錄集:

1、SetRangeStart方法和SetRangeEnd方法可以過濾記錄。SetRangeStart方法用來限制記錄集的開始,SetRangeEnd方法用來限制記錄集的結束,調用ApplyRange方法使限制生效,調用CancelRange方法取消為數據表設定的限制范圍。

2、使用數據集的Filter屬性

Filter屬性值是一個用來指明數據表過濾標準的字符串,Filter屬性決定了過濾器是否起作用。

查找記錄:

1、使用FindKey方法。使用Table的FindKey方法或FindNearest方法。

2、搜索特定記錄(Locate)。FindKey或FindNearest方法只能在TTable組件中使用,如果使用的是TQuery或TStoreProc組件,就要使用Locate方法來查找記錄。Locate函數適合于所有數據集組件,也適合于TTable組件。AppendRecord方法與InsertRecord方法:這里兩個方法分別與Append方法與Insert方法相似,都是用于在表中插入一條新紀錄,但AppendRecord方法與InsertRecord方法比Append方法與Inser t方法更簡單、更方便一些,不需要調用Post方法。過程形式如下:Procedure AppendRecord(Const Values:Array of Const);

Procedure InsertRecord(Const Values:Array of Const);

建立數據表的主從關系:設置表之間的主從關系是通過設置從表的MasterSource屬性和MasterField屬性來實現的,且從表必須按MasterField屬性中指定的字段建立了索引。

6.6TQuery組件

TQuery組件和TTable組件的比較:同屬于數據集組件。

不同之處為:TQuery組件主要功能是用來支持SQL語言訪問本地或遠程數據庫;TQuery組件允許用戶同時訪問多個表,而TTable組件一次只能訪問一個表格;TQuery組件訪問的是表格中的特定數據內容,而TTable組件只有在提供過濾或限定檢索范圍時才能訪問表格中的特定數據內容,否則訪問的將是表格中的全部數據。掌握P193 BDE綜合實例。

6.8 ADO技術

通過ADO不僅能夠訪問基于SQL Server的所有數據庫,而且可以通過ODBC訪問所有支持ODBC的數據庫。

ODBC是一種采用開放式結構進行數據庫鏈接的接口標準,是一種開放的獨立于廠商的API應用程序接口。掌握P208 ADO應用實例

第七章 Windows編程基礎

7.1動態鏈接庫(DLL)

Windows允許同時運行的多個程序共享一組函數的單一備份,于是引入了動態鏈接方式,將可共享的程序代碼以及各種數據資源編譯成單獨的模塊。

一般項目的格式如下: Program 程序標識符; Uses 單元列表; Begin 程序體; End.DLL項目文件的格式如下: Library 程序標識符號; Uses 單元列表;

Exports 過程和函數標識符列表; Begin 程序體; End.兩者的區別的原因在于:Delphi編譯器是一句項目文件頭的保留字是Program還是Library來決定編譯生成的是EXE文件還是DLL文件。若DLL 要輸出共其他應用程序調用的函數或過程,則需要在其項目文件的保留字exports之后一一列出,這些DLL函數或過程將被編譯成遠程地址調用。

Window系統自身包含三個DLL,分別是Kernel,User,GD1。DLL調用必須使用標準方式,其一是靜態引用,其二是動態引用。靜態引入:

加載引用的DLL文件是,庫文件的查找順序是:

1、當前路徑;

2、Windows系統的安裝目錄;

3、Windows的系統目錄system和system32;

4、列在環境變量PATH中的路徑。

引入方法:

1、最簡單的是名字引入;

2、使用索引引入;

3、若名字引入會引起標識符沖突,可以使用換名引入。

第三篇:c++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;}

template int Stack::size()const { return count;}

template void 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;}

Stack sign;Stack num;

int set;

// 判斷程序中的異常,以便適時退出?//

void process(char c)

//計算兩個數的 +-* / 運算// { int k=0;double a,b;sign.pop();

if(num.top(b)==success){

num.pop();

if(num.top(a)==success){ num.pop();k=1;} } if(k){ switch(c){

case '+': num.push(a+b);break;case '-': num.push(a-b);break;case '*': num.push(a*b);break;case '/': if(b==0){ set=4;num.push(-1);} else

num.push(a/b);break;} }

else {set=1;num.push(-1);} }

void get_command(string &str){

cout<<“n請輸入要進行運算的表達式,包括” +,-,*,/,=,(,)“和數字,”<

<<“注意: 以數字開頭,等號結尾,中間括號要匹配.”<>str;}

double do_command(const string &str){ string s=“";

double outcome=-1;char c;

for(int i=0;str[i]!='

主站蜘蛛池模板: 日韩人妻无码一区二区三区综合部| 亚洲人成人无码www影院| 国产绳艺sm调教室论坛| 亚洲国产欧美日韩精品一区二区三区| 亚洲日韩国产精品乱-久| 亚洲和欧洲一码二码区别7777| 内射囯产旡码丰满少妇| 欧美巨大黑人极品精男| 青青草原亚洲| 日韩电影一区二区三区| 国产av天堂亚洲国产av天堂| 亚洲国产美国国产综合一区二区| 国产精品无码久久久久| 欧美人与动另类xxxx| 2022国产在线无码精品| 国产精品久久久久久久影院| 永久免费毛片在线播放| 久久久久亚洲av成人网人人网站| 国产内射老熟女aaaa∵| 亚洲综合国产一区二区三区| 中文字幕在线不卡精品视频99| 日本又色又爽又黄的a片18禁| 丰满少妇内射一区| 国产精品成人一区无码| 在线视频精品中文无码| 香蕉av777xxx色综合一区| 日韩午夜理论免费tv影院| 麻豆人妻少妇精品无码专区| 精品国产一区二区三区无码| 成人无码区免费A片在线软件| 亚洲欧美综合区自拍另类| 亚洲精品久久久久中文字幕二区| 在线岛国片免费无码av| 一本色道久久88综合日韩精品| 国产精久久???老狼网站漫画| 国产日韩av免费无码一区二区| 国产精华av午夜在线观看| 777午夜福利理论电影网| 国产精品久久久久久久久久免费看| 人人爽人妻精品a片二区| 久久免费午夜福利院|