delphi基础01-表达式、运算符、函数调用、集合构造函数、索引、(值或变量)类型转换
整理出来,供大家学习使用:
http://docwiki.embarcadero.com/RADStudio/Rio/en/Expressions_(Delphi)#Typecasts
1、表达式:
表达式是一种返回值的构造。下表为Delphi表达式示例:
X
变量
@X
变量X的地址
15
整数常数
InterestRate
变量
Calc(X, Y)
函数调用
X * Y
X和Y的乘积
Z / (1 - Z)
Z和(1-Z)的商
X = 1.5
布尔型
C in Range1
布尔型
not Done
布尔取反
['a', 'b', 'c']
组
Char(48)
值类型转换
最简单的表达式是变量和常量(在关于数据类型(Delphi)中描述)。使用运算符,函数调用,集合构造函数,索引和类型转换,从较简单的表达式构建更复杂的表达式。
2、运算符
2.1、算术运算符
采用实数或整数操作数的算术运算符包括+,-,*,/,div和mod。
10进制算术运算符:
操作(运算符)运作方式操作数类型结果类型例 +
加
整数,实数real即double
整数,实数
X + Y
--
减
整数,实数
整数,实数
Result -1
*
乘
整数,实数
整数,实数
P * InterestRate
/
实数除法
整数,实数
实数 X / 2
div
整数除法
整数
整数
Total div UnitSize
mod
求余
整数
整数
Y mod 6
2.2、布尔运算符
布尔操作符不,和,或,并且异或采取任何的操作数的布尔类型并返回类型的值布尔。
布尔运算符:
操作(运算符)运作方式操作数类型结果类型例 不 not
否定
布尔型
布尔型
not (C in MySet)
和(并且) and
连词
布尔型
布尔型
Done and (Total >0)
要么(或) or
析取
布尔型
布尔型
A表达式 or B表达式
异或 xor
异或
布尔型
布尔型
A表达式 xor B表达式
这些操作由布尔逻辑的标准规则控制。例如,形式的表达式x and y是真当且仅当x是真并y是真。
xor(异或):这个比较难理解,一句口诀:自己总结的,两个表达式比较:假真>真, 真假>真,真真>假,真值表: (假) xor (真)=真 (真) xor (假)=真 (真) xor (真)=假
2.3、逻辑(按位)运算符
逻辑(按位)运算符:
操作(运算符)运作方式操作数类型结果类型例 不 not
按位取反
整数
整数
not X
和(并且) and
按位和
整数
整数
X and Y
要么
按位或
整数
整数
X or Y
异或(或) or
按位异或
整数
整数
X xor Y
shl(按位左移)
左移:X乘以2的N层方
整数
整数
X shl N
shr(按位右移)
右移:
1、正整数Y除以2的N层方:求沿零方向四舍五入到最接近的整数的值
2、负整数Y:符号位的值替换为0 (所有负数都将符号位设置为1)
整数
整数
+Y shr N
-Y shr N
案例: D:\delphiXEDev\JSon\UseSuperObject.dproj
procedure TfmxMain.ListBoxItem_OperatorsClick(Sender: TObject); //
end;
二进制数: LStrA="001101" LStrB="100001" LStrA和LStrB按位or运算: (LStrA[i] or [i]),结果: LStrZ="101101"
LStrA和LStrB按位and运算: (LStrA[i] and [i]),结果: LStrZ="000001"
LStrA和LStrB按位xor异或运算: (LStrA[i] xor [i]),结果: LStrZ="101100"
shl(按位左移) shr(按位右移) :
LIntA:=80; LIntB:=3; LStrZ:=''; Memo1.Lines.Add( StringOfChar(#32,6)+'LIntA:=80; LIntB:=3;'+sLineBreak +StringOfChar(#32,6)+'LIntA和LIntB 按位左移shl 运算=LIntA*(2^LIntB):乘以2的N层方:'+sLineBreak +StringOfChar(#32,6)+'( LIntA shl LIntB ),结果:'+sLineBreak +StringOfChar(#32,6)+'LStrZ="'+IntToStr( LIntA shl LIntB )+'"'+sLineBreak ); Memo1.Lines.Add( StringOfChar(#32,6)+'LIntA:=80; LIntB:=3;'+sLineBreak +StringOfChar(#32,6)+'LIntA和LIntB 按位右移shr 运算=LIntA div (2^LIntB):除以2的N层方求商:'+sLineBreak +StringOfChar(#32,6)+'( LIntA shr LIntB ),结果:'+sLineBreak +StringOfChar(#32,6)+'LStrZ="'+IntToStr( LIntA shr LIntB )+'"'+sLineBreak ); LIntA:=-20; LIntB:=1; LStrZ:=''; LIntA:=LIntA shr LIntB; LStrZ:=IntToHex(LIntA,8); Memo1.Lines.Add( StringOfChar(#32,6)+'LIntA:=-20; LIntB:=1;'+sLineBreak +StringOfChar(#32,6)+'LIntA负数和LIntB 按位右移shr 运算=负整数Y:符号位的值替换为0(所有负数都将符号位设置为1):'+sLineBreak +StringOfChar(#32,6)+'( LIntA:=LIntA shr LIntB ),结果:'+sLineBreak +StringOfChar(#32,6)+'LIntA="'+IntToStr( LIntA shr LIntB )+'"'+sLineBreak +StringOfChar(#32,6)+'16进制LStrZ:=IntToHex(LIntZ,8)="'+LStrZ+'"'+sLineBreak );
LIntA:=80; LIntB:=3; LIntA和LIntB 按位左移shl 运算=LIntA*(2^LIntB):乘以2的N层方: ( LIntA shl LIntB ),结果: LStrZ="640"
LIntA:=80; LIntB:=3; LIntA和LIntB 按位右移shr 运算=LIntA div (2^LIntB):除以2的N层方:求沿零方向四舍五入到最接近的整数的值: ( LIntA shr LIntB ),结果: LStrZ="10"
LIntA:=-20; LIntB:=1; LIntA负数和LIntB 按位右移shr 运算=负整数Y:符号位的值替换为0(所有负数都将符号位设置为1): ( LIntA:=LIntA shr LIntB ),结果: LIntA="1073741819" 16进制LStrZ :=IntToHex(LIntA,8)="7FFFFFF6" //LIntA初值为 negative负数, LIntA:=LIntA shr LIntB 为 positive正数. //LStrZ的10进制数: 2147483638 = ( -LIntA shl LIntB ) =(-20 shl 1 )= 1073741819 * (2^1) //LStrZ的16进制数: 7FFFFFF6 //LStrZ的2进制数: : 0111 1111 1111 1111 1111 1111 1111 0110
2.4、字符串运算符
关系运算符=,<>,<,>,<=和> =都采用字符串操作数(请参阅本节后面的关系运算符)。在+运算符连接两个字符串。
字符串运算符:
操作(运算符)运作方式操作数类型结果类型例 +
级联
字符串String,打包字符串packed string,字符Character
字符串
S + '.'
以下规则适用于字符串连接:
+的操作数:可以是字符串,打包字符串(Char类型的打包数组)或字符。但是,如果一个操作数的类型为WideChar,则另一个操作数必须为长字符串(UnicodeString,AnsiString或WideString)。+操作的结果:与任何字符串类型兼容。但是,如果操作数都是短字符串或字符,并且它们的组合长度大于255,则结果将被截断为前255个字符。
2.4、指针运算符
关系运算符 <,>,<= 和 > =可以采用PAnsiChar和PWideChar类型的操作数(请参阅关系运算符)。以下运算符也将指针用作操作数。有关指针的更多信息,请参见指针和指针类型(delphi)在有关数据类型(delphi)。
字符指针运算符:
操作(运算符)运作方式操作数类型结果类型例 +
指针加法
字符指针,整数
字符指针
P + I
-
指针减法
字符指针,整数
字符指针,整数
P - Q
右^
指针取消引用
指针
指针的基本类型
P^
=
相等
指针
布尔型
P = Q
<>
不等式
指针
布尔型
P <> Q
右^运算符:解除引用指针。它的操作数可以是除通用Pointer之外的任何类型的指针,通用指针必须在取消引用之前进行类型转换。
P = Q :P和Q必须都指向相同的地址,结果才为真;否则 P <> Q为True。
您可以使用+和-运算符来增加和减少字符指针的偏移量。您也可以使用-计算两个字符指针的偏移量之差。适用以下规则:
如果I是一个整数,并且P是一个字符指针:1、对于PAnsiChar指针:则P + I添加I到P; 给定的地址中。也就是说,它返回指向I后面的地址的字符指针P。(该表达式I + P等于P + I。)。P - I从给定的地址中减去I;也就是说,它返回指向之前的地址的字符指针。2、如果是PWideChar指针:P + I = P + I * SizeOf(WideChar)如果P和Q都是字符指针,则P - Q = I = P(高位地址)- Q(低位地址);也就是说,它返回一个整数I,表示P和Q之间的字符数。
P + Q 没有定义。
2.5、集合运算符:
操作(运算符)运作方式操作数类型结果类型例 +
并集
集合
集合 Set1 + Set2
-
两个集合不同的部分
集合集合 S - T
*
两个集合交叉的部分
集合集合 S * T
<=
子集
集合 布尔型
Q <= MySet
> =
超集(包含它的那个父集)
集合 布尔型
S1 >= S2
=
相等
集合 布尔型
S2 = MySet
<>
不等
集合 布尔型
MySet <> S1
in 包含在其中(是那个集合的成员)
序数,集合
布尔型
A in Set1
以下规则适用于集合的 +,- ,* 运算 :
An ordinal O is in X + Y if and only if O is in X or Y (or both). O is in X - Y if and only if O is in X but not in Y. O is in X * Y if and only if O is in both X and Y.The result of a +, -, or * operation is of the type set of A..B, where A is the smallest ordinal value in the result set and B is the largest.
以下规则适用于集合的 <=, >=, =, <>, in运算 :
X <= Y is True just in case every member of X is a member of Y; Z >= W is equivalent to W <= Z. U = V is True just in case U and V contain exactly the same members; otherwise, U <> V is True.For an ordinal O and a set S, O in S is True just in case O is a member of S.
2.6、关系运算符:
关系运算符用于比较两个操作数。运算符=,<>,<=和> =也适用于集合。
仅当两个指针指向同一字符数组时,才使用运算符<,>,<=和> =比较PAnsiChar(和PWideChar)操作数。运算符=和<>可以采用类和类引用类型的操作数。类类型的操作数,=和<>是评估根据适用于指针的规则:C = D是真:C和D必须指向相同的实例对象,否则C <> D为真。类引用类型的操作数,C = D是真:表示C和D是相同的类,否则C <> D为真。这种运算不会比较存储在类中的数据。有关类的更多信息,请参见类和对象(Delphi)。
2.7、类和接口运算符:
操作符as和is将类和实例对象作为操作数;以及在接口上的操作。有关更多信息,请参见类和对象(Delphi),对象接口(Delphi)和接口引用(Delphi)。
关系运算符=和<>也可对类进行运算。
2.8、@运算符:
@操作符:返回一个变量的地址,或一个函数方法,过程方法的地址; 也就是说,@构造一个指向其操作数的指针。有关指针的更多信息,请参见关于数据类型(Delphi)中的 “指针和指针类型” 。以下规则适用于@。
如果X是变量,则@X返回的地址X。(当X是过程变量时,将应用特殊规则;请参阅关于数据类型(Delphi)中的 “语句和表达式中的过程类型” 。)如果默认的编译器指令有效,@X则类型为Pointer{$T}。在{$T+}状态下,@X类型为^T,其中T类型为X(此区别对于分配兼容性很重要,请参阅分配兼容性)。如果F是例程(函数或过程),则@F返回F的入口点(即:地址)。@F的类型始终是Pointer。当@应用于类中定义的方法时(即:类方法),该方法标识符必须使用类名限定。例如,@ TMyClass.DoSomething
注意:使用@运算符时,无法获取接口方法的地址,因为该地址在编译时未知,并且无法在运行时提取(接口:是需要去单独为它写实现的代码的)。
2.9、运算符优先级:
在复杂的表达式中,优先级规则确定执行操作的顺序。
运算符的优先级
操作(运算符)优先顺序 @ not
第一(最高)
* / div mod 和shl shr as
第二
+ - 或xor
第三
= <> < > <=> = in 是
第四(最低)
2.10、函数调用:
因为函数返回值,所以函数调用是表达式。例如,如果您定义了一个函数Calc,该函数带有两个整数参数并返回一个整数,则该函数调用Calc(24,47)是一个整数表达式。如果I和J是整数变量,则I + Calc(J,8)也是整数表达式。函数调用的示例包括:
Sum(A, 63)
Maximum(147, J)
Sin(X + Y)
Eof(F)
Volume(Radius, Height)
GetValue
TSomeObject.SomeMethod(I,J);
有关函数的更多信息,请参见过程和函数(Delphi)。
2.11、集合构造函数:
集合构造函数表示集合类型值。例如:
[5,6,7,8]
表示成员为5、6、7和8的集合。也可以这样表达集合构造函数:
[5..8]
可以表达与第1种相同的集合。
集合构造函数的语法为:
[ item1,..,itemN ]
其中每个项目要么是表示集合的基本类型的序数的表达式,要么是一对这样的表达式,它们之间有两个点(..)。当一个项目具有形式时x..y,它是从x到的所有序号的简写y,包括y;但是如果x大于y,则x..yset [x..y]表示什么也不是空集。set构造函数[ ]表示空集,而[x]表示其唯一成员为的值的集x。
集合构造函数的示例:
[ red, green, MyColor ]
[ 1,5,10..(K mod 12),23,(I div 9) ]
[ 'A'..'Z','a'..'z',Chr( Digit + 48) ]
有关集合的详细信息,请参阅结构化类型(delphi)在有关数据类型(delphi)。
2.12、索引:
可为字符串,数组,数组属性以及指向字符串或数组的指针建立索引。例如,如果FileName是字符串变量,则表达式FileName[3]返回字符串FileName中的第三个字符,而FileName[I + 1]返回字符串FileName中的第I + 1个字符。有关字符串的信息,请参见数据类型,变量和常量。有关阵列和阵列属性的信息,请参见阵列中的数据类型,变量和常量和“ 阵列属性在” 属性(DELPHI)页。
2.13、类型转换:
有时将表达式视为属于不同类型很有用。实际上,通过类型转换,您可以通过临时更改表达式的类型来执行此操作。例如,Integer('A')将字符强制转换A为整数。
类型转换的语法为:
类型标识符(强制转化的表达式)
如果表达式是变量,则结果称为变量类型转换;否则,结果为值类型转换。虽然它们的语法相同,但是对于两种类型转换都适用不同的规则。
2.13.1、值类型转换:
在值类型转换中,类型标识符和强制转换表达式都必须是序数或指针类型。值类型转换的示例:
Integer('A') //ord('A') = 65 //:ASCII码值
Char(48)
Boolean(0)
Color(2)
Longint(@Buffer)
通过将括号中的表达式进行类型转换来获得结果值。如果指定类型的字节大小范围与表达式的大小不同,则可能涉及截断或扩展。表达式的符号始终被保留。
语句 :
I := Integer('A');
将Integer('A')的值65 赋值给变量I。
值类型转换不能带有限定符(如 ':String'),也不能出现在赋值语句的左侧。
2.13.2、变量类型转换:
您可以将任何变量强制转换为其它任何类型,只要它们的大小相同并且您不将整数与实数混合即可。(要转换数字类型,请依赖诸如Int和的标准函数Trunc。)变量类型转换的示例:
Char(I); Boolean(Count); TDefinedType(MyVariable);
1、变量类型转换可以出现在赋值语句的两侧 :
var MyChar:char;
//...
ShortInt(MyChar):= 122;
: 将字符 'z'(ASCII 122)分配给MyChar。
2、可以将变量转换为匿名函数类型。例如:
type Func = function(X: Integer): Integer;
var
F: Func;
P: Pointer;
N: Integer;
:您可以这样进行赋值:
F := Func(P); { Assign procedural value in P to F }
Func(P) := F; { Assign procedural value in F to P }
@F := P; { Assign pointer value in P to F }
P := @F; { Assign pointer value in F to P }
N := F(N); { Call function via F }
N := Func(P)(N); { Call function via P }
3、变量类型转换后还可以带有限定符,示例:
type
TByteRec = record
Lo, Hi: Byte;
end;
TWordRec = record
Low, High: Word;
end;
PByte = ^Byte;
var
B: Byte;
W: Word;
L: Longint;
P: Pointer;
begin
Memo1.Lines.Add(StringOfChar(#32,6)+'变量转换及赋值:'+sLineBreak );
W := $1234;
Memo1.Lines.Add(StringOfChar(#32,6)+W.ToString+sLineBreak );
B := TByteRec(W).Lo;
Memo1.Lines.Add(StringOfChar(#32,6)+B.ToString+sLineBreak );
TByteRec(W).Hi := 0;
Memo1.Lines.Add(StringOfChar(#32,6)+TByteRec(W).Hi.ToString+sLineBreak );
L := $1234567;
Memo1.Lines.Add(StringOfChar(#32,6)+L.ToString+sLineBreak );
W := TWordRec(L).Low;
Memo1.Lines.Add(StringOfChar(#32,6)+W.ToString+sLineBreak );
B := TByteRec(TWordRec(L).Low).Hi;
Memo1.Lines.Add(StringOfChar(#32,6)+B.ToString+sLineBreak );
B := PByte(L)^;
Memo1.Lines.Add(StringOfChar(#32,6)+B.ToString+sLineBreak );
end;
在此示例中,TByteRec用于访问单词的低位和高位字节,并TWordRec访问长整数的低位和高位字。你可以调用预先定义的功能Lo和Hi为了同样的目的,但一个变量的类型转换具有可以在赋值语句的左侧使用的优势。 结果:
变量转换及赋值:
4660
52
0
19088743
17767
69
97
有关类型转换指针的信息,请参见指针和指针类型(Delphi)。有关强制转换类和接口类型的信息,请参见类参考和接口参考(Delphi)中的 “ as运算符” 。
也可以看看
基本句法元素(Delphi)声明和声明(Delphi)布尔编译指令调整(Delphi编译器指令)运算符重载(Delphi)指针和指针类型(Delphi)