delphi基础01-delphi表达式、delphi运算符、delphi函数调用、delphi集合构造函数、delphi索引、(值或变量)delphi类型转换

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、算术运算符

采用实数或整数操作数的算术运算符包括+-*/divmod

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当且仅当xy

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);
//<summary>基础-表达式与运算符:  
var
  LStrA,LStrB,LStrZ:string; LLengthStrBitwise:Integer;
begin
  LStrA:='001101';
  LStrB:='100001';

  LStrZ:='';  LLengthStrBitwise:=0;
  for LLengthStrBitwise:=1 to length(LStrB) do
    LStrZ:=LStrZ+
      IntToStr( StrToInt(LStrA[LLengthStrBitwise]) or StrToInt(LStrB[LLengthStrBitwise]) );
  Memo1.Lines.Add(
     StringOfChar(#32,6)+'二进制数:'+sLineBreak
    +StringOfChar(#32,6)+'LStrA="001101"'+sLineBreak
    +StringOfChar(#32,6)+'LStrB="100001"'+sLineBreak
    +StringOfChar(#32,6)+'LStrA和LStrB按位or运算:'+sLineBreak
    +StringOfChar(#32,6)+'(LStrA[i] or [i]),结果:'+sLineBreak
    +StringOfChar(#32,6)+'LStrZ="'+LStrZ+'"'+sLineBreak
  );
  LStrZ:='';
  for LLengthStrBitwise:=1 to length(LStrB) do
    LStrZ:=LStrZ+
      IntToStr( StrToInt(LStrA[LLengthStrBitwise]) and StrToInt(LStrB[LLengthStrBitwise]) );
  Memo1.Lines.Add(
     StringOfChar(#32,6)+'LStrA和LStrB按位and运算:'+sLineBreak
    +StringOfChar(#32,6)+'(LStrA[i] and [i]),结果:'+sLineBreak
    +StringOfChar(#32,6)+'LStrZ="'+LStrZ+'"'+sLineBreak
  );
  LStrZ:='';
  for LLengthStrBitwise:=1 to length(LStrB) do
    LStrZ:=LStrZ+
      IntToStr( StrToInt(LStrA[LLengthStrBitwise]) xor StrToInt(LStrB[LLengthStrBitwise]) );
  Memo1.Lines.Add(
     StringOfChar(#32,6)+'LStrA和LStrB按位xor异或运算:'+sLineBreak
    +StringOfChar(#32,6)+'(LStrA[i] xor [i]),结果:'+sLineBreak
    +StringOfChar(#32,6)+'LStrZ="'+LStrZ+'"'+sLineBreak
  );

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,则另一个操作数必须为长字符串(UnicodeStringAnsiStringWideString)。
  • +操作的结果:与任何字符串类型兼容。但是,如果操作数都是短字符串或字符,并且它们的组合长度大于255,则结果将被截断为前255个字符。

2.4、指针运算符

字符指针运算符:

操作(运算符) 运作方式 操作数类型 结果类型

+

指针加法

字符指针,整数

字符指针

P + I

-

指针减法

字符指针,整数

字符指针,整数

P - Q

右^

指针取消引用

指针

指针的基本类型

P^

=

相等

指针

布尔型

P = Q

<>

不等式

指针

布尔型

P <> Q

右^运算符解除引用指针。它的操作数可以是除通用Pointer之外的任何类型的指针通用指针必须在取消引用之前进行类型转换。

P = Q :P和Q必须都指向相同的地址,结果才为;否则 P <> QTrue

您可以使用+-运算符来增加和减少字符指针的偏移量。您也可以使用-计算两个字符指针的偏移量之差。适用以下规则:

  • 如果I是一个整数,并且P是一个字符指针:1、对于PAnsiChar指针:则P + I添加IP; 给定的地址中。也就是说,它返回指向I后面的地址的字符指针P。(该表达式I + P等于P + I。)。P - I从给定的地址中减去I;也就是说,它返回指向之前的地址的字符指针。2、如果是PWideChar指针P + I =  P + I * SizeOf(WideChar)
  • 如果PQ都是字符指针,则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 YO 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 YZ >= W is equivalent to W <= ZU = 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 SO in S is True just in case O is a member of S.

2.6、关系运算符:

    关系运算符用于比较两个操作数。运算符=<><=> =也适用于集合。


  • 仅当两个指针指向同一字符数组时,才使用运算符<><=> =比较PAnsiChar(和PWideChar)操作数。
  • 运算符=<>可以采用类和类引用类型的操作数。类类型的操作数=<>是评估根据适用于指针的规则:C = DCD必须指向相同的实例对象,否则C <> D为类引用类型的操作数C = D:表示CD相同的类,否则C <> D这种运算不会比较存储在类中的数据。有关类的更多信息,请参见类和对象(Delphi)

2.7、类和接口运算符:

    操作符asis将类和实例对象作为操作数;以及在接口上的操作。有关更多信息,请参见类和对象(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)是一个整数表达式。如果IJ是整数变量,则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访问长整数的低位和高位字。你可以调用预先定义的功能LoHi为了同样的目的,但一个变量的类型转换具有可以在赋值语句的左侧使用的优势。 结果: 

      变量转换及赋值:

      4660

      52

      0

      19088743

      17767

      69

      97
 

        有关类型转换指针的信息,请参见指针和指针类型(Delphi)。有关强制转换类和接口类型的信息,请参见类参考接口参考(Delphi)中的 “ as运算符” 。

 

也可以看看

发布了61 篇原创文章 · 获赞 6 · 访问量 5547

猜你喜欢

转载自blog.csdn.net/pulledup/article/details/104859485