shl,shr:为双目运算符,参加运算的数为整数,结果也为整数,分别将运算数表示成8位二进制数后左移或右移指定的位数。如9,表示成二进制数为00001001,9Shl1左移1位,结果为00010010,9Shr2,右移2位,结果为00000010。
2.关系运算符
关系运算符用来比较两个数值、字符串(字符可以看做字符串的特例)大小,运算的结果为布尔类型,多用于条件判断。
ObjectPascal的关系运算符有:=(等于)、>(大于)、>=(大于或等于)、(小于)、=(小于或等于)、(不等于)这几种。
关系运算符的运算规则如下。
1)关系运算符比较两个数值、字符或字符串的大小,若比较成立,则结果为True(布尔“真”);若不成立,则结果为False(布尔“假”)。如7>5,显然成立,则结果为True;再如12=6,显然不成立,则结果为False。
2)两个数值类型的数据可以直接比较。
3)两个字符类型的数据是比较其ASCII码的大小。
4)比较两个字符串,先比较第一个字符,若不同,此比较结果作为两字符串比较的结果;若相同,则比较第二个字符,…,若前几个字符都相同,则短的字符串为小。按此规则,‘A’‘B’,‘abcd’>‘abc’。
3.布尔运算符
布尔运算符也称逻辑运算符,是进行布尔运算(也称逻辑运算)的运算符,运算数为布尔类型,运算结果也为布尔类型。
布尔运算符有not(逻辑“非”)、and(逻辑“与”)、or(逻辑“或”)和xor(逻辑“异或”)等几个,其中not为单目运算符,其他为双目运算符。
4.字符串运算符
字符串运算符只有一个字符串的“+”操作,是把两个字符串连接起来,如‘ABCD’+‘cef’,结果为‘ABCDcef’。
4.4.2表达式
用运算符将运算数连接起来组成的式子称表达式。
表达式的运算规则如下。
1)一个表达式中可以有几个运算符。
2)运算按运算符的优先级从高到低顺序进行。运算符的优先级由高到低依次排列如下,同一行优先级相同。
其中,为单目运算符,返回运算数的地址。
3)同级运算符从左到右顺序进行。
4)表达式中有括号时,先运算括号内,再运算括号外。
4.5语句
Delphi应用程序代码是由一个个的ObjectPascal语句组成,语句是程序代码的基本组成单元。
Objectpascal语句以“;”作为语句的结尾。
4.5.1语句的分类
ObjectPascal的语句可分为两大类。
1.声明语句
声明语句放在程序的说明部分,并不完成某种运算和操作,只是说明标号、常量、类型、变量、过程或函数的语句。如前面讲的定义常量的const语句,定义变量的var语句,声明类型的type语句都是。后面还要讲到声明过程和函数的声明语句。
2.可执行语句
可执行语句放在程序的执行部分,用于实现某种运算和操作的语句。
根据语句的结构,可执行语句又分为简单语句和复合语句。
1)简单语句
单个语句行是简单语句。
2)复合语句
用关键字“begin/end”包围起来的若干语句行组成的语句,是复合语句。
在Objectpascal中,复合语句被看做一条语句。
复合语句可以嵌套,即一个复合语句中,可以包含另一个复合语句,如下所示:
另外,ObjectPascal中的语句,有一类专门用来控制程序执行流程的,被称为程序流程控制语句。
下面将分别介绍这些语句。
4.5.2赋值语句
赋值语句是最基本、最常用的语句,用于为变量赋值。在程序中定义了变量之后,必须给它赋值,这个变量才能参加运算或操作。
赋值语句的一般格式为:
变量名:=表达式;
赋值语句的功能是:计算表达式的值,然后把结果赋给“:=”左边的变量。
如a:=5;直接将常数5赋给变量a
b:=a+7;计算a+7,即5+7=12赋给变量b
使用赋值语句,必须遵从如下原则。
1)被赋值的变量必须在程序的声明部分声明过。
2)“:=”两边的数据类型必须一致。
3)对Delphi来说,赋值语句也常用来为对象设置属性。如第3章的程序简例中,Label1.Caption:=‘欢迎进入Delphi6.0的世界!’就是用赋值语句为变量设置属性的。
4.5.3if语句
从程序执行流程看,程序可分为顺序结构、分支结构和循环结构。而分支结构和循环结构的程序需要用程序流程控制语句。下面几个小节介绍的if语句和Case语句用来实现分支结构程序,for语句、while语句和repeat语句用来实现循环结构程序。
if语句,也称条件语句,是实现分支结构的流程控制语句之一。
if语句的语法格式为:
if条件表达式then
语句1
else
语句2;
其中条件表达式可以是布尔表达式,也可以是关系表达式;语句1和语句2可以是简单语句,也可以是复合语句;关键字else前面的语句不能有“;”。
执行if语句,首先计算条件表达式的值,若结果为True,则执行语句1;若结果为False,则执行语句2;执行完语句1或语句2之后,继续执行if语句后面的语句。
若我们只关心一种情况,则if语句变为如下格式:
if条件表达式then
语句1;
由此看出,if语句可以实现程序执行的分支结构,但也只能产生两个分支。若要产生多个分支,可以用if语句嵌套。所谓if语句嵌套是指if语句中的子句,如语句1或语句2中又包含if语句。
if条件表达式Then
if条件表达式Then
设计或阅读带if语句嵌套的程序时应注意,else总是与离它最近的if配对,如需要,应使用begin/end加以界定。如下例:
这里,else应与第二行的if配对。若程序设计需要else和第一个if配对,则要用begin/end界定为:
4.5.4Case语句
if语句嵌套虽然可以实现多分支程序结构,但若需要分支较多,嵌套层次过多,容易引起混乱,使程序可读性下降,这时更多使用另一种分支结构流程控制的Case语句。
Case语句的语法格式为:
Case表达式of
常量1:语句1;
常量2:语句2;
…
常量n:语句n;
else
语句;
end;
执行Case语句,先计算表达式的值,若其值等于常量1则执行语句1,若其值等于常量2则执行语句2,…若都不等,则执行else后面的语句。
如下例:
CaseIof
1..5:Caption:=‘Low’;
6..9:Caption:=‘High’;
0,10..99:Vaption:=‘Outofrange’;
else
Caption:=‘’;
End;
执行该语句,先计算表达式I,若其值在1到5之间,则变量Caption赋值为字符串Low;若其值在6到9之间,则变量Caption赋值为字符串High;若其值为0或10到99之间,则变量Caption赋值为字符串Outofrange;若其值都不为以上情况,则变量Caption赋值为空字符串。
4.5.5for语句
for语句是最常用的循环结构流程控制语句。
for语句的语法格式为:
for循环变量:=初值to(或downto)终值do
语句;
其中do后面的语句可以是简单语句,也可以是复合语句,被称为循环体。
执行该语句,首先将初值赋给循环变量,然后循环执行do后面的语句,每执行一次,循环变量加1(对初值后为to时)或减1(对初值后为downto时),直到循环变量等于终值为止。
如下例:
fori:=1to10do
sum:=sum+i;
该语句执行的结果是1+2+…+10。
由此看出,for语句循环的次数是确定的,由初值和终值决定。因此,若用to时终值小于初值,若用downto时终值大于初值,则for语句一次也不循环。
For语句也可以嵌套,如下例:
执行该语句是给一个100个元素的二维数组赋值,各元素的值分别为11,12,…,110,
21,22,…,101,102,…,1010。
4.5.6while语句
for语句可以实现循环次数确定的循环。但有时循环次数不能确定,要根据程序执行情况决定循环什么时候结束。while语句就是这样的循环语句之一。
while语句的语法格式为:
while条件表达式do
语句;
其中条件表达式为布尔表达式或关系表达式,do后面的语句(称为循环体)可为简单语句,也可为复合语句。
执行该语句,先计算表达式的值,若为True,则执行一次循环体,直到表达式的值为False为止。
如:
whilei=10do
i:=i+1;
因为while语句是在执行循环体之前计算表达式的值,当开始表达式的值即为False,则while语句一次也不循环。
4.5.7repeat语句
repeat语句是另一种不能事先确定循环次数的循环语句。
repeat语句的语法格式为:
repeat
语句1;
语句2;
…
until条件表达式;
其中repeat与until之间的语句序列为循环体。
执行该语句,首先执行循环体,然后计算until后面条件表达式的值,若为False,则返回再执行循环体,直到条件表达式的值为True为止。
可以看出,repeat语句和while语句的不同之处在于repeat语句至少执行一次循环体。
4.5.8goto语句
goto语句也称为无条件转移语句。
goto语句的语法格式为:
goto标号;
其中标号要在程序的说明部分加以说明,格式为:
Lable标号;
执行goto语句,程序无条件地转移到标号指示的语句执行。
例如:
需要指出的是,Pascal是结构化程序设计语言,而使用goto语句会破坏程序的结构化,所以建议用户尽量不要使用goto语句。
4.6过程与函数
过程和函数是ObjectPascal中的两种子程序。
子程序是程序设计中的重要技术。在程序设计中,往往需要重复使用一些相同的代码段。
为了避免重复输入这些相同的代码段,减少程序设计的工作量,也使程序更便于阅读和维护,通常的做法是将这些相同的代码段独立出来,设计成实现特定功能的程序模块,被称为子程序。子程序不能独立运行,而由主程序在需要它们的时候调用,而且可以被不同的主程序调用,从而实现代码段的公用和重复使用,如图4-1所示。
子程序有两种不同的类型,一种调用时没有返回值,一种调用时有返回值。在ObjectPascal中,把没有返回值的子程序称为过程,而把有返回值的子程序称为函数。在Delphi应用程序中,对事件的响应处理都是由过程完成的。
4.6.1过程和函数的定义
过程和函数在使用前必须先进行定义。
1.过程的定义
定义过程的语法格式为:
procedure过程名(参数列表);
说明部分
begin
语句1;
语句2;
…
语句n;
end;
其中:
1)procedure为定义过程的关键字。
2)过程名由用户定义。
3)圆括号中的参数列表列出了过程中使用的参数(被称为形式参数,简称形参),格式为(参数1:类型;参数2:类型;…),有的过程没有参数(称无参过程),则这部分可省略。
4)说明部分说明过程使用的标号和变量等,如前所述,说明标号用“Label标号;”格式,说明变量用“var变量名:类型;”格式。
5)begin与end之间的语句序列为过程体,即过程要实现的功能。
2.函数的定义
函数的定义与过程的定义类似,其语法格式为:
function函数名(参数列表):返回值类型;
说明部分
begin
语句1;
语句2;
…
语句n;
end;
其中不同的是:
1)function为定义函数的关键字;
2)圆括号后要说明函数返回值的类型。
4.6.2过程和函数的调用
过程和函数定义之后,就可以在需要的时候进行调用了。
1.过程的调用
因为过程没有返回值,所以调用过程是以单个语句的形式出现。
对无参过程,调用的语法格式为:
过程名;
对有参过程,调用的语法格式为:
过程名(参数1,参数2,…);
这里过程名为定义过程时使用的过程名,参数被称为实在参数,简称实参。
例如,一个过程的定义如下所示:
procedureplus(i:integer;j:integer);
var
value:integer;
begin
value:=i+j;
end;
参数列表中,i,j类型相同,也可以写成(i,j:integer)的形式。
这个过程的调用如下所示:
proc1(20,30);
2.函数的调用
因为函数有返回值,所以调用的函数名只能出现在表达式中,不能像过程名那样以单个语句的形式出现。
函数的返回值有两种赋值方式,一是将返回值赋给变量名,二是将返回值赋给内置变量Result。
对无参函数,只在表达式需要的位置写上调用的函数名;而对有参函数,则应在表达式需要的位置写上调用的函数名(参数1,参数2,…)。
例如,一个函数的定义如下所示:
functionplus(i:integer;j:integer):integer;
begin
参数列表中,类型相同,也可以写成(i,j:integer)的形式。
这个函数的调用如下所示:
4.6.3过程和函数调用时的参数传递
调用有参过程和函数时,要用实参代替形参,实现调用程序与被调用过程或函数间的数据传递。根据其传递数据的方式不同,参数可分为数值参数、变量参数和常数参数3种。
1.数值参数
数值参数是过程和函数的缺省参数,因此定义过程和函数时形式参数名的前面不加任何关键字加以说明。
数值参数传递的是实在参数的值,就是说调用过程或函数时,是将实在参数的值传递给形式参数,因此调用后,若形式参数的值改变时,实在参数的值也不会改变。
例如:
过程定义如下:
projectsum(i:integer);注意这里i前面没加任何关键字,因此i是数值参数begin
i:=i+10;
end;
过程调用如下:
var
int:integer;
begin
int:=20;
sum(int);
end;
因为i是数值参数,所以过程调用后,形式参数的值虽已改变(由20变为20+10=30),但实在参数的值不变(仍为20)。
2.变量参数
在定义过程或函数时,变量参数的形参名前要加关键字var。
变量参数传递的是实在参数的地址,就是说调用过程或函数时,是将实在参数的地址传递给形式参数,即形参和实参指向同一地址,因此调用后,若形式参数的值改变时,实在参数的值也会随之改变。
如上例:
过程定义如下:
projectsum(vari:integer);注意这里i前面加关键字var,因此i是变量参数begin
i:=i+10;
end;