52
1 第第第第 C/C++ 第 C++ Builder 第第第第 C++ Builder 第第第C++ Builder 第 第第第第第第第第第第第第 VCL 第第 第第第第第第第第第第第 第第 ,, 第第第第第第第 第第第第第第第第第第 C/C++ 第第第第第第第第第第 第第第第 第第第第第第第第第第第第第第第第第第 第第第第第 。, C++ Builder 第第第第第 第第第第第 C++ Builder 第第第 第第

第三章從 C/C++ 到 C++ Builder

  • Upload
    flynn

  • View
    175

  • Download
    9

Embed Size (px)

DESCRIPTION

第三章從 C/C++ 到 C++ Builder. 為了強化 C++ Builder 的功能, C++ Builder 透過類別的形式提供了大量的 VCL 元件,不但加速了程式的開發,也方便了程式的維護,但相對的也衍伸出許多 C/C++ 中所沒有的資料型態和處理機制。本章將針對常用的型態與機制進行介紹,讓讀者熟悉 C++ Builder 的特有語法,也充分利用 C++ Builder 的強大功能。. 大綱. 3-1. 基本資料型態 3-2.AnsiString 型態 3-3. 常用類別型態 3-4. 例外處理機制 3-5. 類別轉換機制. 3-1. 基本資料型態. - PowerPoint PPT Presentation

Citation preview

Page 1: 第三章從 C/C++ 到 C++ Builder

1

第三章從 C/C++到 C++ Builder

為了強化 C++ Builder的功能, C++ Builder透過類別的形式提供了大量的 VCL元件,不但加速了程式的開發,也方便了程式的維護,但相對的也衍伸出許多 C/C++中所沒有的資料型態和處理機制。本章將針對常用的型態與機制進行介紹,讓讀者熟悉 C++ Builder的特有語法,也充分利用 C++ Builder的強大功能。

Page 2: 第三章從 C/C++ 到 C++ Builder

2

大綱• 3-1. 基本資料型態• 3-2. AnsiString型態• 3-3. 常用類別型態• 3-4. 例外處理機制• 3-5. 類別轉換機制

Page 3: 第三章從 C/C++ 到 C++ Builder

3

3-1.基本資料型態• C/C++中紀錄基本資料型態所使用的記憶體大小會隨著編譯器的不同而有所不同,進而影響資料型態所能儲存的資料,底下為 C++ Builder中對整數和浮點數基本型態的定義,包括使用的位元空間和所能表示的數值。 型別 位元大小 (Bits)

char 8

unsigned char 8

short int 16

unsigned short 16

int 32

long 32

enum 32

unsigned int 32

Page 4: 第三章從 C/C++ 到 C++ Builder

4

3-1.基本資料型態• 浮點數:

• 此外, C++ Builder和 C/C++最大的差別在於它提供了對字串的支援,而非 C/C++中使用的字元陣列或是字串指標,且在 C++ Builder視窗環境中,使用字串的機會遠比字元陣列或是指標大的多,在 3-2節中我們將有對字串的完整介紹。

型別 位元大小 (Bits) 數值區間float 32 1.18*10^-38<|X|<3.40*10^38double 64 2.23*10^-308<|X|<1.79*10^308long double 80 3.37*10^-4932<|X|<1.18*10^4932

Page 5: 第三章從 C/C++ 到 C++ Builder

5

3-2.AnsiString資料型態• 在 C++ Builder中的字串稱為 AnsiString資料型態,該型態繼承至

Delphi而來,原因在於 C++ Builder共用了 Delphi中的大部分 VCL元件,而 Delphi使用的 Object Pascal語法擁有所謂的字串型態,為了能順利使用 Delphi中的程式資源,所以繼承 Delphi的字串型態(String)以方便對 VCL元件進行設定的動作。

• 3-2-1. 使用 AnsiString– 要建立一個 AnsiString有很多方法,其中最簡單方式就是和基本型態一樣以宣告的方式建立一個 AnsiString型態的變數,除此,亦可透過

Constructor建構子的使用來產生一個 AnsiString變數,底下為幾種宣告的示範:宣告 /建構子 範例AnsiString() 基本宣告 AnsiString Str="Hello World!"AnsiString(const char* src) char *temp="Hello World!";AnsiString Str(temp);

Page 6: 第三章從 C/C++ 到 C++ Builder

6

3-2.AnsiString資料型態宣告 /建構子 範例AnsiString(const AnsiString& src) AnsiString temp="Hello World!";AnsiString Str(temp);AnsiString(const char* src, unsigned char len); chat *temp="Hello World";

AnsiString Str=AnsiString(temp,5);AnsiString(int) int temp=5168;AnsiString Str=AnsiString(temp);AnsiString(double) double temp=123.45;AnsiString Str(temp);AnsiString(char) char temp='A';AnsiString Str=AnsiString(temp);AnsiString(unsigned long) unsigned long temp=1234567;AnsiString Str=AnsiString(temp);

Page 7: 第三章從 C/C++ 到 C++ Builder

7

3-2.AnsiString資料型態• 從上面的表格中可知,基本型態的數值幾乎都可以轉成AnsiString型態,而除了使用建構子達成轉換的目的外,

C++ Builder還提供AnsiString和基本型態的轉換函式,列表如下:

AnsiString型態 函式 範例整數 StrToInt() int a=StrToInt("1234");

浮點數 StrToFloat() float a=StrToFloat("1234.5");

日期 StrToDate() TDate a=StrToDate("2002/2/2");

時間 StrToTime() TTime a=StrToTime("20:20");

日期時間 StrToDateTime() TDateTime a=StrToDateTime("2002/2/2 8:30");

字串指標 c_str()char * a = new char[Edit1->Text.Length() +1];strcpy(a, Edit1->Text.c_str());

幣值 StrToCurr() Currency a=StrToCuur("12.1");

Page 8: 第三章從 C/C++ 到 C++ Builder

8

型態 AnsiString 函式 範例整數 IntToStr() IntToStr(123);

浮點數 FloatToStr()、 FloatToStrF()

FloatToStr(10.123);FloatToStrF(10.123,ffFixed,7,3);

日期 DateToStr() DateToStr(Date());

時間 TimeToStr() DateToStr(Time());

日期時間 DateTimeToStr() DateToStr(Now());

字串指標 AnsiString()char *temp="Hello World!";AnsiString(temp);

幣值 CurrToStr() CurrToStr(10.11);

說明:FloatToStr和 FloatToStrF的差別在於 FloatToStrF可依照指定格式進行轉換,格式為 FloatToStrF(Extended Value, TFloatFormat Format, int Precision, int Digits),其中 Value為浮點數; Format設定轉換格式;Precision指定精確度; Digits設定顯示小數位數。

Page 9: 第三章從 C/C++ 到 C++ Builder

9

3-2.AnsiString資料型態• 除了可以自由轉換成熟悉的基本型態外, AnsiString相較於字串指標最大的優點在於可以使用運算元直接進行運算,使用方式就如同一般的基本型態,而不像字串指標的所有運算都必須靠函式的呼叫來完成

運算元 功能 範例+ 字串相加 "Hello"+" World"

= 指定運算 temp="Hello"+" World"

== 相等條件與否 if (temp=="Hello World")…

!= 不等條件判斷 if (temp!="Hello World")..

< 小於判斷 if (temp<"0")…

> 大於判斷 if (temp>"9")…

<= 小於等於判斷 if (temp<="9")…

>= 大於等於判斷 if (temp>="0")…

[] 字串陣列索引 output=temp[1];

Page 10: 第三章從 C/C++ 到 C++ Builder

10

3-2.AnsiString資料型態– 至此,可發現 AnsiString不但可任意轉換型態,還能進行運算比較,比過去 C/C++中使用的字串指標來的方便,但好戲還不止於此, C++ Builder對 AnsiString型態提供了眾多的字串處理函式,讓基本的字串處理工作變的輕輕鬆鬆,這些函式將在下一小節說明。

• 3-2-2. AnsiString字串處理函式– AnsiString字串處理函式包羅萬象,下面僅就常用的函式進行說明和示範:

AnsiCompare函數宣告: int AnsiCompare(const AnsiString& rhs) const;說明:比較兩字串的內容:兩字串相同傳回 0;小於傳回 -1;大於傳回1範例: if(Edit1->Text.AnsiCompare("Hello")) ShowMessage("字串相等 ");

Page 11: 第三章從 C/C++ 到 C++ Builder

11

3-2.AnsiString資料型態

AnsiPos函數宣告: int AnsiPos(const AnsiString& subStr) const;說明:回傳 subStr在字串中的位置,回傳值為 0表示 subStr不存在於字串中。範例: Edit1->Text.AnsiPos("Hello");//回傳 "Hello"在 Edit1輸入框中的位置

AnsiCompareIC函數宣告: int AnsiCompareIC(const AnsiString& rhs) const;說明:和 AnsiCompare()功能相同,但不考慮字串的大小寫。範例: if(Edit1->Text.AnsiCompareIC("Hello")) ShowMessage("字串相等 ");

Page 12: 第三章從 C/C++ 到 C++ Builder

12

3-2.AnsiString資料型態

Delete函數宣告: AnsiString Delete(int index, int count)說明:從字串的第 index個字元開始刪除 count字元,字串的第一個字元 index為1範例:AnsiString tem="Hello World";tem.Delete(1,6); //tem字串刪除後為 "World"

cat_printf函數宣告: AnsiString cat_sprintf(const char* format, ...);說明:依照格式將字串附加於原有字串之後範例: s.cat_sprintf("Dear %s",Edit1->Text);

Page 13: 第三章從 C/C++ 到 C++ Builder

13

3-2.AnsiString資料型態FloatToStrF函數宣告:AnsiString FloatToStrF(Extended Value, TFloatFormat Format, int Precision, int Digits);

說明:依照 Format設定的輸出格式、 Precision指定的精確度和 Digits限制的小數點後位數對 Value浮點數進行字串轉換的動作。 Format有 ffGeneral(一般 )、ffExponent(科學符號 )、 ffFixed(固定小數點位置 )、 ffNumber(千位分隔號 )和 ffCurrency(錢幣 )五種格式。範例:float tem= 87654.325;AnsiString str=FloatToStrF(tem,ffNumber,7,2);//str="87,654.33",小數第三位四捨五入

Page 14: 第三章從 C/C++ 到 C++ Builder

14

3-2.AnsiString資料型態FormatFloat函數宣告:AnsiString FormatFloat(const AnsiString Format, Extended Value);說明:依照 Format格式轉換 Value浮點數。範例:Format格式 說明 12345 -12345 0.80 整數四捨五入 12345 -12345 10.00 小數兩位 12345.00 -12345.00 0.80#.## 有值才顯示 12345 -12345 .8#,##0.00 千位分隔號 12,345.00 -12,345.00 0.80#,##0.00;(#,##0.00)

正負號格式不同 12,345.00 (-12,345.00) 0.80

0.000E+00 符合格式的科學符號 1.235E+05 -1.235E+05 8.000E-01

Page 15: 第三章從 C/C++ 到 C++ Builder

15

3-2.AnsiString資料型態

IntToHex函數宣告: AnsiString IntToHex(int Value, int Digits);說明:把整數轉成 16進位的 AnsiString。範例: ShowMessage(IntToHex(168,2));//顯示的值為 A8

Insert函數宣告: AnsiString& Insert(const AnsiString& str, int index);說明:從字串的第 index字元開始插入 str字串,而原有 index後的字串會往後挪移。範例: AnsiString temp="Hello";temp.Insert(" World",6);//新增後的字元為 "Hello World"

Page 16: 第三章從 C/C++ 到 C++ Builder

16

3-2.AnsiString資料型態

IsPathDelimiter

函數宣告: bool IsPathDelimiter(int index);

說明:判斷 Index字元是否為反斜線字元 "\",如果是則回傳 True。範例: if (dirStr.IsPathDelimiter(dirStr.Length())) ShowMessage("Match!");

IsDelimiter

函數宣告:bool IsDelimiter(const AnsiString Delimiters, const AnsiString S, int Index);

說明:判斷 S字串中第 Index字元是否存在於 Delimiters字串中,若存在則傳回 true。範例: if (IsDelimiter("\\", dirStr, dirStr.Length())) ShowMessage("Match!");

Page 17: 第三章從 C/C++ 到 C++ Builder

17

3-2.AnsiString資料型態

LastDelimiter函數宣告: int LastDelimiter(const AnsiString& delimiters);說明:傳回字串中最後一個 delimiters字串的位置範例: int pos=dirStr.LastDelimiter("\\");//傳回最後一個 "\\"的位置

IsEmpty函數宣告: bool IsEmpty();說明:判斷字串是否為空字串,是則回傳 True。範例: if(str.IsEmpty()) ShowMessage("String is empty");

Page 18: 第三章從 C/C++ 到 C++ Builder

18

3-2.AnsiString資料型態

Length函數宣告: int Length();說明:傳回字串的長度範例: int len=Edit1->Text.Length(); //Edit1輸入框中輸入字串的長度

LastDelimiter函數宣告: int LastDelimiter(const AnsiString& delimiters);說明:傳回字串中最後一個 delimiters字串的位置範例: int pos=dirStr.LastDelimiter("\\");//傳回最後一個 "\\"的位置

Page 19: 第三章從 C/C++ 到 C++ Builder

19

3-2.AnsiString資料型態

Pos函數宣告: int Pos(const AnsiString& subStr);說明:傳回 subStr字串在此字串中的位置,若不存在則回傳值為 0。範例: AnsiString temp="Hello World";ShowMessage(IntToStr(temp.Pos("World")));

LowerCase函數宣告: AnsiString LowerCase();說明:把字串內容全部變成小寫。範例: dirStr.LowerCase(); //把 dirStr字串內容轉為小寫

Page 20: 第三章從 C/C++ 到 C++ Builder

20

3-2.AnsiString資料型態

SubString函數宣告: AnsiString SubString(int index, int count);說明:回傳從字串第 index個字元開始的 count個字元所形成的子字串。範例: AnsiString temp=dirStr.SubString(2,2);

sprintf函數宣告: AnsiString& sprintf(const char* format, ...);說明:依照指定格式設定字串內容。格式的設定和 C中的 printf相同。範例: AnsiString temp;temp.sprintf("Hello %s :",Edit1->Text);

Page 21: 第三章從 C/C++ 到 C++ Builder

21

3-2.AnsiString資料型態

TrimLeft函數宣告: AnsiString TrimLeft();說明:去除字串中字頭所含的空白。範例: Edit1->Text.TrimLeft();

Trim函數宣告: AnsiString Trim();說明:去除字串的前後空白。範例: Trim(Edit1->Text); 或 Edit1->Text.Trim();

TrimRight函數宣告: AnsiString TrimLeft();說明:去除字串中字尾所含的空白。範例: Edit1->Text.TrimRight();

Page 22: 第三章從 C/C++ 到 C++ Builder

22

3-2.AnsiString資料型態

ToIntDef

函數宣告: int ToIntDef(int defaultValue);

說明:把字串轉成整數型態,轉換失敗則使用 defaultValue作為輸出。範例: int temp=str.ToIntDef(123);

ToInt函數宣告: int ToInt();說明:把字串轉成整數,但字串內容不允許非數字字元的出現。範例: int temp=str.ToInt();

Page 23: 第三章從 C/C++ 到 C++ Builder

23

3-2.AnsiString資料型態

– 習慣了 AnsiString型態和其提供的方法後,會發覺 AnsiString在很多情況下都比過去的字串指標來的方便,尤其是在 VCL元件屬性或方法設定上,但缺點就是所寫的程式碼不能在其他編譯器下進行編譯。

UpperCase函數宣告: AnsiString UpperCase();說明:把字串內的字元轉成大寫形式。範例: AnsiString temp=str.UpperCase();

Page 24: 第三章從 C/C++ 到 C++ Builder

24

3-3.常用類別型態• 除了 AnsiString字串型態外, C++ Builder為了元件的設定方便還提供了許多的類別型態,這些型態最常出現在元件的屬性或是方法指定上,底下我們僅就常用的 TStrings、參數和時間相關類別型態進行介紹。

• 3-3-1. TStrings型態– TStrings為一個以列表方式紀錄 AnsiString型態資料的類別,也就是以陣列方式來儲存大量的 AnsiString資料,所以舉凡能以條列方式顯示文字資料的 VCL元件幾乎都透過 TStrings型態來紀錄所要顯示的內容,包括: TListBox、 TComboBox、 TMemo和 TStringGrid元件,像 TListBox和 TComboBox使用 TStrings類別的 Items屬性完成顯示內容的設定; TMemo使用 Lines屬性; TStringsGrid使用 Rows屬性。此外,由於 TStrings為一個類別而非基本型態,所以也提供了一些屬性和方法來增強 TStrings類別的功能性,以方便程式設計員對它的使用,熟悉 TStrings類別的屬性和方法將有助於後面元件的開發。

Page 25: 第三章從 C/C++ 到 C++ Builder

25

3-3.常用類別型態– 常用屬性:屬性 說明Count 顯示目前 TStrings中紀錄的字串數目。CommaText 以 AnsiString型態顯示 TStrings中的所有字串內容,字串間以逗點分隔。Text 以 AnsiString型態顯示 TStrings中的所有字串內容,但以斷行符號分隔不同字串。Strings 以陣列型態讀取 TStrings內容,如 Strings[0]。Values 當 TStrings內容為 Name=Value時,可以透過

Values["Name"]的方式讀取對應的 Value值。

Page 26: 第三章從 C/C++ 到 C++ Builder

26

3-3.常用類別型態– 常用方法:

• 3-3-2. 參數類別– 參數類別包含 TParam和 TParams兩種,其中 TParam紀錄個別參數的內容,如 Name=Value,而 TParams則為 TParam的集合,儲存了多個的參數內容。在 C++ Builder中,很多資料庫元件都以 TParams類別作為傳遞參數的依據,而 TParams類別再透過其內的 TParam傳遞每個參數和對應的值,如TQuery、 TADOuery和 TSQLQuery元件,底下為 TParam和 TParams常用的屬性與方法:

方法 說明Add(const AnsiString S) 新增字串 S到 TStrings中。Clear(Void) 清掉 TStrings中的所有字串內容。Delete(int Index) 清掉第 Index個字串內容。Equals(TString* Strings) 判斷兩個 TStrings是否相等。

Page 27: 第三章從 C/C++ 到 C++ Builder

27

3-3.常用類別型態– TParam類別

• 常用屬性:屬性 說明AsString 當參數為字串類型時,透過 AsString指定參數值。AsInteger 當參數為整數類型時,透過 AsInteger指定參數值。AsFloat 當參數為浮點數類型時,透過 AsFloat指定參數值。DataType

設定 TParam參數的類型,有 ftString(字串 )、 ftInteger(整數 )、 ftDate(日期 )、 ftFloat(浮點數 )、 ftTime(時間 )等。

Name 設定參數的名稱。Text 把參數的值轉成字串形式呈現。Value

存取參數的值。 (建議使用AsString、 AsInteger、 AsFloat、 AsTime…等方式存取參數值能得到較好的效能 )。

Page 28: 第三章從 C/C++ 到 C++ Builder

28

3-3.常用類別型態– TParams類別

• 常用屬性:

• 常用方法:

屬性 說明Items 透過 Items屬性紀錄參數的值。Count 回傳 TParams中所紀錄的參數個數。ParamValues 透過 ParamValues["Name"]方式傳回對應的參數值。

方法 說明AddParam(TParam* Value) 新增一個 TParam參數到 TParams中。AssignValues(TParams* Value) 以 Value這個 TParams設定目前的參數值。IsEqual(TParams* Value) 判斷兩個 TParams是否相同。

Page 29: 第三章從 C/C++ 到 C++ Builder

29

3-3.常用類別型態• 3-3-3. 時間類別

– 在開發程式的過程中,時間是一個很常使用到的變數,不論是算程式的執行時間或是作為計算效能的依據,除此,日期變數亦常作為計算使用,如每筆交易紀錄的時間、應用程式的有效日期等,所以在本小節中將就 C++ Builder提供的時間類別進行介紹,雖然說 C/C++也有所謂的時間型態,但 C++ Builder的時間類別能和 Timer、 DateTimePicker等 C++ Builder內附元件配合使用,在使用上更為方便。

– C++ Builder提供了三個主要的時間類別: TTime、 TDate和 TDateTime,分別用以表示時間、日期和時間日期,這些類別主要以浮點數的型態來紀錄日期時間的值,以 1899年 12月 30日的上午 12時為浮點數 0所代表的意義,當然我們可以不需要管這些內部處理的細節,而只需透過包裝好的TTime、 TDate和 TDateTime類別來處理所有的時間計算。對於這些時間類別, C++ Builder提供了一些好用的方法或函式來方便你設定時間類別的值或是做些時間上的判斷,如下所示:

Page 30: 第三章從 C/C++ 到 C++ Builder

30

3-3.常用類別型態– 取得日期部分函式 說明Now() 以 TDateTime類別回傳今天的日期和時間。Date() 以 TDateTime類別回傳今天的日期。Time() 以 TDateTime類別回傳今天的時間。Today() 以 TDateTime類別回傳今天的日期。Tomorrow() 以 TDateTime類別回傳明天的日期。Yesterday() 以 TDateTime類別回傳昨天的日期。CurrentYear() 以四位整數回傳目前的西元年份。

Page 31: 第三章從 C/C++ 到 C++ Builder

31

3-3.常用類別型態– 常用日期處理函式 /方法函式 /方法 單元檔說明DateOf(TDateTime Value) DateUtils把 TDateTime變數的時間部分歸零。DayOf(TDateTime AValue) DateUtils回傳 AValue所指定月份的天數。DayOfTheMonth(TDateTime AValue) DateUtils和 DayOf相同。DayOfTheWeek(TDateTime AValue) DateUtils以數字形式回傳 AValue日期為星期幾, 1表示星期天, 7表示星期六。

Page 32: 第三章從 C/C++ 到 C++ Builder

32

3-3.常用類別型態函式 /方法 單元檔說明DayOfTheYear(TDateTime AValue) DateUtils

以數字形式回傳 AValue日期為該年的第幾天。DaysBetween(TDateTime ANow, TDateTime AThen) DateUtils

回傳兩個日期間的天數。以整數型態回傳。DaysInAMonth(Word AYear, Word AMonth) DateUtils

回傳指定年份 (AYear)月份 (AMonth)的天數。 AYear的範圍為 1~9999;AMonth的範圍為 1~12。DaysInAYear(Word AYear) DateUtils

以整數型態回傳指定年份 (AYear)的天數。

Page 33: 第三章從 C/C++ 到 C++ Builder

33

3-3.常用類別型態函式 /方法 單元檔說明DecodeDate(TDateTime DateTime, Word &Year, Word &Month, Word &Day); SysUtils

透過指標方式,以 Year、Month、 Day三個參數回傳指定日期的年、月、日。EncodeDate(Word Year, Word Month, Word Day) SysUtils

輸入 Year、Month、 Day變數值,回傳代表輸入日期的 TDateTime型別。EncodeDateDay(const Word AYear, const Word ADayOfYear) DateUtils

輸入年份和該年的第幾天,回傳一個代表輸入日期的 TDateTime型別。EncodeDateMonthWeek(Word AYear, Word AMonth, Word AWeekOfMonth, Word ADayOfWeek) DateUtils

輸入年份、月份、該月的第幾個禮拜和該禮拜的第幾天,回傳代表該日期的TDateTime型別。

Page 34: 第三章從 C/C++ 到 C++ Builder

34

3-3.常用類別型態函式 /方法 單元檔說明EncodeDateWeek(Word AYear, Word AWeekOfYear, Word ADayOfWeek) DateUtils

輸入年份、該年的第幾個禮拜和該禮拜的第幾天,回傳 TDateTime型別表示該日期,其中, ADayOfWeek以星期一為 1、星期二為 2,依此類推。IncAMonth(Word &Year, Word &Month, Word &Day, int NumberOfMonths) SysUtils

對指定日期加上指定的月份,並透過傳址變數回傳新的日期。IncMonth(TDateTime Date, int NumberOfMonths = 1) SysUtils對指定日期加上指定的月份,預設值為加上 1個月。IncDay(TDateTime AValue, int ANumberOfDays) DateUtils指定日期加上指定的天數,回傳值為 TDateTime型態。

Page 35: 第三章從 C/C++ 到 C++ Builder

35

3-3.常用類別型態函式 /方法 單元檔說明IsInLeapYear(TDateTime AValue) DateUtils

判斷指定的日期是否為閏年,回傳值為 True表示為閏年。IsToday(TDateTime AValue) SysUtils判斷指定日期是否為目前日期,如果是則回傳 True。MonthOf(TDateTime AValue) SysUtils回傳指定日期的月份,範圍值 1~12。RecodeDate(TDateTime AValue, Word AYear, Word AMonth, Word ADay) DateUtils

依照指定的年月日對原有的日期進行修改,回傳值為新的日期,型別為TDateTime。

Page 36: 第三章從 C/C++ 到 C++ Builder

36

3-3.常用類別型態函式 /方法 單元檔說明RecodeDay(TDateTime AValue, Word ADay) DateUtils

依照 ADay的輸入修改 AValue的日期,回傳值為 TDateTime型別的新日期。RecodeMonth(TDateTime AValue, Word AMonth) SysUtils依照 AMonth的輸入修改 AValue的日期,回傳值為 TDateTime型別的新日期。RecodeYear(TDateTime AValue, Word AYear) SysUtils依照 AYear的輸入修改 AValue的日期,回傳值為 TDateTime型別的新日期。WeekOf(TDateTime AValue) DateUtils回傳指定日期在該年中的第幾個星期,為一整數型態的回傳值。

Page 37: 第三章從 C/C++ 到 C++ Builder

37

3-3.常用類別型態函式 /方法 單元檔說明WeekOfTheMonth(TDateTime AValue) DateUtils

回傳指定日期在該月的第幾個禮拜,為一整數型態的回傳值。WeekOfTheYear(TDateTime AValue) SysUtils回傳指定日期在該年的第幾個禮拜,為一整數型態的回傳值。WeeksBetween(TDateTime ANow, TDateTime AThen) SysUtils

回傳 ANow和 AThen兩日期的星期間格,為一整數的回傳值。YearOf(TDateTime AValue) DateUtils

回傳指定日期的年份,回一整數的回傳值。

Page 38: 第三章從 C/C++ 到 C++ Builder

38

3-3.常用類別型態– 常用時間處理函式 /方法函式 /方法 單元檔說明HoursBetween(TDateTime ANow, AThen) DateUtils回傳兩個指定時間的時差,不包含小數部分。HourSpan(TDateTime ANow, TDateTime AThen) DateUtils回傳兩指定時間間的時差,包含小數部分。HourOf(TDateTime AValue) DateUtils回傳時間的小時部分,範圍值為 0~23。HourOfTheWeek(TDateTime AValue); DateUtils回傳指定日期為該週的第幾個小時,計算基準為星期一的 AM12:00。

Page 39: 第三章從 C/C++ 到 C++ Builder

39

3-3.常用類別型態函式 /方法 單元檔說明IncHour(TDateTime AValue, __int64 ANumberOfHours) DateUtils

從 AValue日期加上指定的小時數, __int64為 64bits的長整數。IncMinute(TDateTime AValue, __int64 ANumberOfMinutes) SysUtils從 AValue日期加上指定的分鐘數, __int64為 64bits的長整數。IncSecond(TDateTime AValue, __int64 ANumberOfSeconds) SysUtils從 AValue日期加上指定的秒數, __int64為 64bits的長整數。MinutesBetween(TDateTime ANow, TDateTime AThen) DateUtils回傳兩 TDateTime變數間的分鐘數差,回傳值為 __int64型態的長整數。

Page 40: 第三章從 C/C++ 到 C++ Builder

40

3-3.常用類別型態函式 /方法 單元檔說明MinutesSpan(TDateTime ANow, TDateTime AThen) DateUtils

回傳兩 TDateTime變數間的分鐘數差,包含小數部分,以浮點數回傳。MinuteOf(TDateTime AValue) DateUtils以整數型態回傳 TDateTime變數的分鐘數,該值介於 0~59。MinuteOfTheDay(TDateTime AValue) DateUtils回傳從同一天 AM12:00算起到 TDateTime變數的分鐘數。MilliSecondsBetween(TDateTime ANow, TDateTime AThen) DateUtils回傳兩 TDateTime變數間的毫秒數差,以 __int64長整數回傳。

Page 41: 第三章從 C/C++ 到 C++ Builder

41

3-3.常用類別型態函式 /方法 單元檔說明SecondsBetween(TDateTime ANow, TDateTime AThen) DateUtils

回傳兩 TDateTime變數間的秒數差,以 __int64長整數回傳。SecondSpan(TDateTime ANow, TDateTime AThen) SysUtils回傳兩 TDateTime變數間的秒數差,包含小數部分,以浮點數型態回傳。SecondOf(TDateTime AValue) SysUtils

以整數型態回傳 TDateTime變數的秒數,該值介於 0~59。

Page 42: 第三章從 C/C++ 到 C++ Builder

42

3-4.例外處理機制• 在寫程式時,難免因為考慮不周而產生一些特殊情形才會發生的錯誤,造成電腦的不穩定,為了避免這樣的情形發生, C++ Builder提供了例外處理機制來確保程式的穩定執行。所謂的例外處理機制在於程式執行時攔截所有可能發生的錯誤,並產生對應的例外錯誤事件,這事件中紀錄了錯誤的類型與說明,而由於錯誤已經被攔截,所以可以在不影響系統的穩定和資源下跳過錯誤指令繼續執行程式,至於攔截到的訊息則可以提供原設計師做為改正程式的參考,底下為基本的例外處理範例:

Page 43: 第三章從 C/C++ 到 C++ Builder

43

3-4.例外處理機制void __fastcall TForm1::Button1Click(TObject *Sender){ try { int i=Edit1->Text.ToInt(); ShowMessage(10/i); } catch (EDivByZero &E) //例外處理 { MessageDlg(E.Message, mtError,TMsgDlgButtons() << mbYes << mbNo, 0); }}

Page 44: 第三章從 C/C++ 到 C++ Builder

44

3-4.例外處理機制– 在 try{}中的程式碼即為被例外處理機制所監督的程式區塊,而 catch{}中的程式碼則為例外發生時所要執行的程式內容– 以上面的例子來說,當 Edit1->Text為 0時會發生除數為 0的錯誤

• 而為了避免除數為 0錯誤對程式執行可能造成的影響,我們使用 catch來監督 EDivByZero(除數為 0)錯誤類別的發生,其中 EDivByZero為專門監督除數為 0錯誤的例外處理類別,當除數為 0的錯誤發生後就會自動進入 catch區塊中執行程式,並跳過 try{}區塊中程式執行錯誤後面的程式碼,下面為 Exception錯誤發生的訊息方塊。

Page 45: 第三章從 C/C++ 到 C++ Builder

45

3-4.例外處理機制– 上面程式片段中使用了 EDivByZero例外處理類別解決了除數為 0的錯誤,而 C++ Builder還提供了其他的例外處理類別來解決不同的例外事件,下面為常見的例外處理類別。例外處理類別 例外說明EAccessViolation 錯誤的記憶體存取。EComponentError 不正當的修改元件名稱。EConvertError String或 object的轉換錯誤。EDatabaseError 資料庫存取錯誤。EDBEditError 資料庫資料編輯錯誤。EDivByZero 除數為 0的錯誤。EInOutError 檔案 I/O錯誤。

Page 46: 第三章從 C/C++ 到 C++ Builder

46

3-4.例外處理機制例外處理類別 例外說明EIntOverflow 整數 Overflow的錯誤EInvalidCast 不當的類別轉換錯誤。EInvalidGraphic 使用未知圖檔類型的錯誤。EInvalidOperation 在元件上不當的操作錯誤。EInvalidPointer 指標操作不當所造成的錯誤。EPrinterError 列印錯誤。EPropertyError 設定錯誤的元件屬性值所產生的錯誤。

Page 47: 第三章從 C/C++ 到 C++ Builder

47

3-4.例外處理機制– 倘若一個程式區塊內可能發生兩種不同類型的錯誤,而對於這兩種錯誤希望能分別處理,則可以透過多次的 catch使用來撰寫不同的處理內容void __fastcall TForm1::Button1Click(TObject *Sender){ try { int i=Edit1->Text.ToInt(); Edit1->Text=AnsiString(10/i); } catch (EDivByZero &E) { //除數為 0的例外處理 MessageDlg(E.Message, mtError,TMsgDlgButtons() << mbYes << mbNo, 0); } catch (EConvertError &E) { //Edit1->Text轉換成整數的例外處理 MessageDlg(E.Message, mtError,TMsgDlgButtons() << mbYes << mbNo, 0); Edit1->Text=AnsiString(10/1); }}

Page 48: 第三章從 C/C++ 到 C++ Builder

48

3-4.例外處理機制– 上面的程式碼利用兩個 catch{}區塊處理了兩種不同的錯誤,在每個例外處理中加入對應的程式碼,這種將不同例外處理交由不同 catch{}區塊來處理的好處就是可以針對錯誤類型進行特別處理,如加入對應的中文錯誤訊息說明或錯誤的自動校正功能,至於不針對特定類別的例外處理可使用下面的範例來監督所有可能的例外發生。

void __fastcall TForm1::Button1Click(TObject *Sender){ try { int i=Edit1->Text.ToInt(); Edit1->Text=AnsiString(10/i); } catch (Exception &E) { //不特別指定例外處理的類別 MessageDlg(E.Message, mtError,TMsgDlgButtons() << mbYes << mbNo, 0); }}

Page 49: 第三章從 C/C++ 到 C++ Builder

49

3-4.例外處理機制• 或

void __fastcall TForm1::Button1Click(TObject *Sender){ try { int i=Edit1->Text.ToInt(); Edit1->Text=AnsiString(10/i); } catch (...) //不特別指定例外處理的類別 { ShowMessage("Error"); }}

Page 50: 第三章從 C/C++ 到 C++ Builder

50

3-4.例外處理機制– 除了程式執行過程因為錯誤發生而進入例外處理機制外,對於一些特殊的應用,我們亦可透過 throw方法的呼叫來強迫例外處理類別的產生,進而引發對應的例外處理機制,底下為 throw使用的範例。

try{ throw EDivByZero("Division Error");}catch(Exception &E){ ShowMessage(E.Message);}

Page 51: 第三章從 C/C++ 到 C++ Builder

51

3-5.類別轉換機制• C++ Builder對於不同類別提供了一個轉換的機制

– 也就是 dynamic_cast的使用,透過 dynamic_cast可以把某種物件的類別強制轉換成另一種類別,但兩類別間的轉換不保證能確實完成• 為此, dynamic_cast提供了安全保護機制來確保縱使轉換失敗也不影響系統的運作,也就是說若轉換不成功只是無法達成轉換的目的,但不致造成系統的當機。 dynamic_cast的語法:• 其中參數 T為所欲轉換的型態,必須為指標、 void*或是定義過的類別才行,而 ptr參數則為原來的型態,必須為指標或是參考 (reference),至於轉換錯誤則回傳一個值為 0的指標,下面為 dynamic_cast的範例。

• 透過轉換機制把 TForm類別的 ActiveMDIChild轉成了 TImageForm類別,並指到 ptrImageForm。

dynamic_cast <T> (ptr)

TImageForm *ptrImageForm = dynamic_cast<TImageForm *>(ActiveMDIChild);

Page 52: 第三章從 C/C++ 到 C++ Builder

52

本章習題• 習題

1. 如何從整數型態變數所佔的記憶體大小來推算該型態所允許的數值。2. __int64使用 64bits來紀錄數值的大小,試問它最大允許多大的數值輸入。3. 簡述 AnsiString和字串指標的不同。4. 試問 TDate、 TTime和 TDateTime如何儲存日期和時間的資料。5. 簡述例外處理機制的優點。