XML與ASP ch3

Download Report

Transcript XML與ASP ch3

综合基础 从C/C++到C++ Builder
为了强化C++ Builder的功能,C++ Builder通
过类别的形式提供了大量的VCL组件,不但加
速了程序的开发,也方便了程序的维护,但相
对的也衍生出许多C/C++中所没有的数据型态
和处理机制。本章将针对常用的型态与机制进
行介绍,让读者熟悉C++ Builder的特有语法,
也充分利用C++ Builder的强大功能。
1
大纲
•
•
•
•
•
1-1.
1-2.
1-3.
1-4.
1-5.
基本数据型态
AnsiString型态
常用类别型态
例外处理机制
类别转换机制
2
1-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
3
1-1.
基本数据型态
• 浮点数:
型别
位大小(Bits)
数值区间
float
32
1.18*10^-38<|X|<3.40*10^38
double
64
2.23*10^-308<|X|<1.79*10^308
long double
80
3.37*10^-4932<|X|<1.18*10^4932
• 此外,C++ Builder和C/C++最大的差别在于它提供了对字符串的支持,
而非C/C++中使用的字符数组或是字符串指针,且在C++ Builder窗口环
境中,使用字符串的机会远比字符数组或指针大的多,在1-2节中我们
将有对字符串的完整介绍。
4
1-2.AnsiString数据型态
• 在C++ Builder中的字符串称为AnsiString数据型态,该型态继承至
Delphi而来,原因在于C++ Builder共享了Delphi中的大部分VCL组件,
而Delphi使用的Object Pascal语法拥有所谓的字符串型态,为了能顺
利使用Delphi中的程序资源,所以继承Delphi的字符串型态(String)
以方便对VCL组件进行设定的动作。
• 1-2-1. 使用AnsiString
– 要建立一个AnsiString有很多方法,其中最简单方式就是和基本型态一样
以宣告的方式建立一个AnsiString型态的变量,除此,亦可透过
Constructor建构子的使用来产生一个AnsiString变量,底下为几种宣告的
示范:
宣告/建构子
范例
AnsiString() 基本宣告
AnsiString Str="Hello World!"
AnsiString(const char*
src)
char *temp="Hello World!";
AnsiString Str(temp);
5
1-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)
6
AnsiString Str=AnsiString(temp);
unsigned long temp=1234567;
1-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");
7
型态
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设定转换格式;
8
Precision指定精确度;Digits设定显示小数字数。
1-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];
9
1-2.
AnsiString数据型态
– 至此,可发现AnsiString不但可任意转换型态,还能进行运算比较,
比过去C/C++中使用的字符串指针来的方便,但好戏还不止于此,
C++ Builder对AnsiString型态提供了众多的字符串处理函式,让基
本的字符串处理工作变的轻轻松松,这些函式将在下一小节说明。
• 1-2-2. AnsiString字符串处理函式
– AnsiString字符串处理函式包罗万象,下面仅就常用的函式进行说
明和示范:
AnsiCompare
函数宣告:int AnsiCompare(const AnsiString& rhs) const;
说明:比较两字符串的内容:两字符串相同传回0;小于传回-1;大于传
回1
范例:if(Edit1->Text.AnsiCompare("Hello")) ShowMessage("字符串
相等");
10
1-2.
AnsiString数据型态
AnsiCompareIC
函数宣告:int AnsiCompareIC(const AnsiString& rhs) const;
说明:和AnsiCompare()功能相同,但不考虑字符串的大小写。
范例:if(Edit1->Text.AnsiCompareIC("Hello")) ShowMessage("字符串相
等");
AnsiPos
函数宣告:int AnsiPos(const AnsiString& subStr) const;
说明:回传subStr在字符串中的位置,回传值为0表示subStr不存在于字符串
中。
范例:Edit1->Text.AnsiPos("Hello");//回传"Hello"在Edit1输入框中的位
置
11
1-2.
AnsiString数据型态
cat_printf
函数宣告:AnsiString cat_sprintf(const char* format, ...);
说明:依照格式将字符串附加于原有字符串之后
范例:s.cat_sprintf("Dear %s",Edit1->Text);
Delete
函数宣告:AnsiString Delete(int index, int count)
说明:
从字符串的第index个字符开始删除count字符,字符串的第一个字符index
为1
范例:
AnsiString tem="Hello World";
tem.Delete(1,6); //tem字符串删除后为"World"
12
1-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",小数第三位四舍五入
13
1-2.
AnsiString数据型态
FormatFloat
函数宣告:
AnsiString FormatFloat(const AnsiString Format, Extended Value);
说明:依照Format格式转换Value浮点数。
范例:
Format格式
说明
12345
-12345
0.8
0
整数四舍五入
12345
-12345
1
0.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
14
8.000E-01
1-2.
AnsiString数据型态
Insert
函数宣告:AnsiString& Insert(const AnsiString& str, int index);
说明:从字符串的第index字符开始插入str字符串,而原有index后的
字符串会往后挪移。
范例:AnsiString temp="Hello";
temp.Insert(" World",6);//新增后的字符为"Hello World"
IntToHex
函数宣告:AnsiString IntToHex(int Value, int Digits);
说明:把整数转成16进位的AnsiString。
范例:ShowMessage(IntToHex(168,2));//显示的值为A8
15
1-2.
AnsiString数据型态
IsDelimiter
函数宣告:
bool IsDelimiter(const AnsiString Delimiters, const AnsiString S, int
Index);
说明:
判断S字符串中第Index字符是否存在于Delimiters字符串中,若存在则传回
true。
范例:if (IsDelimiter("\\", dirStr, dirStr.Length()))
ShowMessage("Match!");
IsPathDelimiter
函数宣告:bool IsPathDelimiter(int index);
说明:判断Index字符是否为反斜线字符"\",如果是则回传True。
范例:if (dirStr.IsPathDelimiter(dirStr.Length()))
ShowMessage("Match!");
16
1-2.
AnsiString数据型态
IsEmpty
函数宣告:bool IsEmpty();
说明:判断字符串是否为空字符串,是则回传True。
范例:if(str.IsEmpty()) ShowMessage("String is empty");
LastDelimiter
函数宣告:int LastDelimiter(const AnsiString& delimiters);
说明:传回字符串中最后一个delimiters字符串的位置
范例:int pos=dirStr.LastDelimiter("\\");//传回最后一个"\\"的
位置
17
1-2.
AnsiString数据型态
LastDelimiter
函数宣告:int LastDelimiter(const AnsiString& delimiters);
说明:传回字符串中最后一个delimiters字符串的位置
范例:int pos=dirStr.LastDelimiter("\\");//传回最后一个"\\"的
位置
Length
函数宣告:int Length();
说明:传回字符串的长度
范例:int len=Edit1->Text.Length(); //Edit1输入框中输入字符串
的长度
18
1-2.
AnsiString数据型态
LowerCase
函数宣告:AnsiString LowerCase();
说明:把字符串内容全部变成小写。
范例:dirStr.LowerCase(); //把dirStr字符串内容转为小写
Pos
函数宣告:int Pos(const AnsiString& subStr);
说明:传回subStr字符串在此字符串中的位置,若不存在则回传值为0。
范例:AnsiString temp="Hello World";
ShowMessage(IntToStr(temp.Pos("World")));
19
1-2.
AnsiString数据型态
sprintf
函数宣告:AnsiString& sprintf(const char* format, ...);
说明:依照指定格式设定字符串内容。格式的设定和C中的printf相同。
范例:AnsiString temp;
temp.sprintf("Hello %s :",Edit1->Text);
SubString
函数宣告:AnsiString SubString(int index, int count);
说明:回传从字符串第index个字符开始的count个字符所形成的子字符
串。
范例:AnsiString temp=dirStr.SubString(2,2);
20
1-2.
AnsiString数据型态
Trim
函数宣告:AnsiString Trim();
说明:去除字符串的前后空白。
范例:Trim(Edit1->Text); 或Edit1->Text.Trim();
TrimLeft
TrimRight
函数宣告:AnsiString
TrimLeft();
函数宣告:AnsiString TrimLeft();
说明:
去除字符串中字尾所含的空白。
说明:
去除字符串中字头所含的空白。
范例:Edit1->Text.TrimRight();
范例:Edit1->Text.TrimLeft();
21
1-2.
AnsiString数据型态
ToInt
函数宣告:int ToInt();
说明:把字符串转成整数,但字符串内容不允许非数字字符的出现。
范例:int temp=str.ToInt();
ToIntDef
函数宣告:int ToIntDef(int defaultValue);
说明:把字符串转成整数型态,转换失败则使用defaultValue作为输出。
范例:int temp=str.ToIntDef(123);
22
1-2.
AnsiString数据型态
UpperCase
函数宣告:AnsiString UpperCase();
说明:把字符串内的字符转成大写形式。
范例:AnsiString temp=str.UpperCase();
– 习惯了AnsiString型态和其提供的方法后,会发觉AnsiString在很
多情况下都比过去的字符串指针来的方便,尤其是在VCL组件属性或
方法设定上,但缺点就是所写的程序代码不能在其它编译器下进行
编译。
23
1-3.
常用类别型态
• 除了AnsiString字符串型态外,C++ Builder为了组件的设定
方便还提供了许多的类别型态,这些型态最常出现在组件的
属性或是方法指定上,底下我们仅就常用的TStrings、参数
和时间相关类别型态进行介绍。
• 1-3-1. TStrings型态
– TStrings为一个以列表方式纪录AnsiString型态数据的类别,也就是
以数组方式来储存大量的AnsiString数据,所以举凡能以条列方式显
示文字数据的VCL组件几乎都透过TStrings型态来纪录所要显示的内容,
包括:TListBox、TComboBox、TMemo和TStringGrid组件,像TListBox
和TComboBox使用TStrings类别的Items属性完成显示内容的设定;
TMemo使用Lines属性;TStringsGrid使用Rows属性。此外,由于
TStrings为一个类别???
24
1-3.
常用类别型态
– 常用属性:
属性
说明
Count
显示目前TStrings中纪录的字符串数目。
CommaText
以AnsiString型态显示TStrings中的所有字符串内容,
字符串间以逗点分隔。
Text
以AnsiString型态显示TStrings中的所有字符串内容,
但以断行符号分隔不同字符串。
Strings
以数组型态读取TStrings内容,如Strings[0]。
Values
当TStrings内容为Name=Value时,可以透过
Values["Name"]的方式读取对应的Value值。
25
1-3.
常用类别型态
– 常用方法:
• 1-3-2.
方法
说明
Add(const AnsiString S)
新增字符串S到TStrings中。
Clear(Void)
清掉TStrings中的所有字符串内容。
Delete(int Index)
清掉第Index个字符串内容。
Equals(TString* Strings)
判断两个TStrings是否相等。
参数类别
– 参数类别包含TParam和TParams两种,其中TParam纪录个别参数的内容,如
Name=Value,而TParams则为TParam的集合,储存了多个的参数内容。在C++
Builder中,很多数据库组件都以TParams类别作为传递参数的依据,而
TParams类别再透过其内的TParam传递每个参数和对应的值,如TQuery、
TADOuery和TSQLQuery组件,底下为TParam和TParams常用的属性与方法:
26
1-3.
常用类别型态
– TParam类别
• 常用属性:
属性
说明
AsString
当参数为字符串类型时,透过AsString指定参数值。
AsInteger
当参数为整数类型时,透过AsInteger指定参数值。
AsFloat
当参数为浮点数类型时,透过AsFloat指定参数值。
DataType
设定TParam参数的类型,有ftString(字符串)、ftInteger(整
数)、ftDate(日期)、ftFloat(浮点数)、ftTime(时间)等。
Name
设定参数的名称。
Text
把参数的值转成字符串形式呈现。
Value
存取参数的值。(建议使用AsString、AsInteger、AsFloat、
AsTime…等方式存取参数值能得到较好的效能)。
27
1-3.
– TParams类别
• 常用属性:
常用类别型态
属性
说明
Items
透过Items属性纪录参数的值。
Count
回传TParams中所纪录的参
数个数。
ParamValues
透过ParamValues["Name"]方
式传回对应的参数值。
• 常用方法:
方法
说明
AddParam(TParam* Value)
新增一个TParam参数到TParams中。
AssignValues(TParams* Value)
以Value这个TParams设定目前的参数值。
IsEqual(TParams* Value)
判断两个TParams是否相同。
28
1-3.
常用类别型态
• 1-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提
供了一些好用的方法或函式来方便你设定时间类别的值或是做些时间上的判
断,如下所示:
29
1-3.
常用类别型态
– 取得日期部分
函式
说明
Now()
以TDateTime类别回传今天的日期和时间。
Date()
以TDateTime类别回传今天的日期。
Time()
以TDateTime类别回传今天的时间。
Today()
以TDateTime类别回传今天的日期。
Tomorrow()
以TDateTime类别回传明天的日期。
Yesterday()
以TDateTime类别回传昨天的日期。
CurrentYear()
以四位整数回传目前的公元年份。
30
1-3.
常用类别型态
– 常用日期处理函式/方法
函式/方法
单元文件
说明
DateOf(TDateTime Value)
DateUtils
把TDateTime变量的时间部分归零。
DayOf(TDateTime AValue)
DateUtils
回传AValue所指定月份的天数。
DayOfTheMonth(TDateTime AValue)
DateUtils
和DayOf相同。
DayOfTheWeek(TDateTime AValue)
DateUtils
以数字形式回传AValue日期为星期几,1表示星期天,7表示星期六。
31
1-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)的天数。
32
1-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型别。
33
1-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)
指定日期加上指定的天数,回传值为TDateTime型态。
34
DateUtils
1-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。
35
1-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
回传指定日期在该年中的第几个星期,为一整数型态的回传值。
36
1-3.
常用类别型态
函式/方法
单元文件
说明
WeekOfTheMonth(TDateTime AValue)
DateUtils
回传指定日期在该月的第几个礼拜,为一整数型态的回传值。
WeekOfTheYear(TDateTime AValue)
SysUtils
回传指定日期在该年的第几个礼拜,为一整数型态的回传值。
WeeksBetween(TDateTime ANow, TDateTime AThen)
SysUtils
回传ANow和AThen两日期的星期间格,为一整数的回传值。
YearOf(TDateTime AValue)
DateUtils
回传指定日期的年份,回一整数的回传值。
37
1-3.
常用类别型态
– 常用时间处理函式/方法
函式/方法
单元文件
说明
HoursBetween(TDateTime ANow, AThen)
DateUtils
回传两个指定时间的时差,不包含小数部分。
HourSpan(TDateTime ANow, TDateTime AThen)
DateUtils
回传两指定时间间的时差,包含小数部分。
HourOf(TDateTime AValue)
DateUtils
回传时间的小时部分,范围值为0~23。
HourOfTheWeek(TDateTime AValue);
DateUtils
回传指定日期为该周的第几个小时,计算基准为星期一的AM12:00。
38
1-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型态的长整数。
39
1-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)
回传两TDateTime变数间的毫秒数差,以__int64长整数回传。
40
DateUtils
1-3.
常用类别型态
函式/方法
单元文件
说明
SecondsBetween(TDateTime ANow, TDateTime AThen)
DateUtils
回传两TDateTime变数间的秒数差,以__int64长整数回传。
SecondSpan(TDateTime ANow, TDateTime AThen)
SysUtils
回传两TDateTime变量间的秒数差,包含小数部分,以浮点数型态回传。
SecondOf(TDateTime AValue)
SysUtils
以整数型态回传TDateTime变量的秒数,该值介于0~59。
41
1-4.
例外处理机制
• 在写程序时,难免因为考虑不周而产生一些特殊情形才会发
生的错误,造成计算机的不稳定,为了避免这样的情形发生,
C++ Builder提供了例外处理机制来确保程序的稳定执行。所
谓的例外处理机制在于程序执行时拦截所有可能发生的错误,
并产生对应的例外错误事件,这事件中纪录了错误的类型与
说明,而由于错误已经被拦截,所以可以在不影响系统的稳
定和资源下跳过错误指令继续执行程序,至于拦截到的讯息
则可以提供原设计师做为改正程序的参考,底下为基本的例
外处理范例:
42
1-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);
}
}
43
1-4.
例外处理机制
– 在try{}中的程序代码即为被例外处理机制所监督的程序区块,而catch{}中
的程序代码则为例外发生时所要执行的程序内容
– 以上面的例子来说,当Edit1->Text为0时会发生除数为0的错误
• 而为了避免除数为0错误对程序执行可能造成的影响,我们使用catch来
监督EDivByZero(除数为0)错误类别的发生,其中EDivByZero为专门监
督除数为0错误的例外处理类别,当除数为0的错误发生后就会自动进入
catch区块中执行程序,并跳过try{}区块中程序执行错误后面的程序代
码,下面为Exception错误发生的消息框。
44
1-4.
例外处理机制
– 上面程序片段中使用了EDivByZero例外处理类别解决了除数为0的错误,而
C++ Builder还提供了其它的例外处理类别来解决不同的例外事件,下面为
常见的例外处理类别。
例外处理类别
例外说明
EAccessViolation
错误的内存存取。
EComponentError 不正当的修改组件名称。
EConvertError
String或object的转换错误。
EDatabaseError
数据库存取错误。
EDBEditError
数据库数据编辑错误。
EDivByZero
除数为0的错误。
EInOutError
档案I/O错误。
45
1-4.
例外处理机制
例外处理类别
例外说明
EIntOverflow
整数Overflow的错误
EInvalidCast
不当的类别转换错误。
EInvalidGraphic
使用未知图档类型的错误。
EInvalidOperation
在组件上不当的操作错误。
EInvalidPointer
指标操作不当所造成的错误。
EPrinterError
打印错误。
EPropertyError
设定错误的组件属性值所产生的错误。
46
1-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);
}
}
47
1-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);
}
}
48
1-4.
例外处理机制
• 或
void __fastcall TForm1::Button1Click(TObject *Sender)
{
try
{
int i=Edit1->Text.ToInt();
Edit1->Text=AnsiString(10/i);
}
catch (...) //不特别指定例外处理的类别
{
ShowMessage("Error");
}
}
49
1-4.
例外处理机制
– 除了程序执行过程因为错误发生而进入例外处理机制外,对于一些特殊的应
用,我们亦可透过throw方法的呼叫来强迫例外处理类别的产生,进而引发
对应的例外处理机制,底下为throw使用的范例。
try{
throw EDivByZero("Division Error");
}
catch(Exception &E){
ShowMessage(E.Message);
}
50
1-5.
类别转换机制
• C++ Builder对于不同类别提供了一个转换的机制
– 也就是dynamic_cast的使用,透过dynamic_cast可以把某种对象的类别强制
转换成另一种类别,但两类别间的转换不保证能确实完成
• 为此,dynamic_cast提供了安全保护机制来确保纵使转换失败也不影响系
统的运作,也就是说若转换不成功只是无法达成转换的目的,但不致造成
系统的当机。dynamic_cast的语法: dynamic_cast <T> (ptr)
• 其中参数T为所欲转换的型态,必须为指针、void*或是定义过的类别才行,
而ptr参数则为原来的型态,必须为指针或是参考(reference),至于转换
错误则回传一个值为0的指标,下面为dynamic_cast的范例。
TImageForm *ptrImageForm = dynamic_cast<TImageForm *>(ActiveMDIChild);
• 透过转换机制把TForm类别的ActiveMDIChild转成了TImageForm类别,并
指到ptrImageForm。
51
本章习题
• 习题
1. 如何从整数型态变量所占的内存大小来推算该型态所允
许的数值。
2. __int64使用64bits来纪录数值的大小,试问它最大允许
多大的数值输入。
3. 简述AnsiString和字符串指针的不同。
4. 试问TDate、TTime和TDateTime如何储存日期和时间的数
据。
5. 简述例外处理机制的优点。
52