我学Delphi心得及笔记----语句,第四讲

如果说数据类型是Pascal 编程的一个基础,那么另一个则是语句。编程语言的语句主要由关键字和操作指令组成。语句常放在过程或函数中,就象我们将在下一部分中看到的那样。现在,我们集中讲解最基本的编程语句。

简单语句和复合语句

Pascal 简单语句中不包含任何别的语句,赋值语句和过程调用即是简单语句的例子。简单语句用分号隔开,如下所示:

X := Y + Z;  // assignment Randomize;   // procedure call

用begin 和end 将简单语句括起来即组成复合语句,复合语句用法与普通的Pascal 语句相同,见下例:

begin   A := B;   C := A * 2; end; 

end之前的最后一条语句末尾分号不是必需的,你可以写成:

begin   A := B;   C := A * 2 end; 

这两种写法都是正确的。第一种多了一个无用(但也无害)的分号。分号实际上是一个空语句,也就是说,是一个没有代码的语句。有时,空语句可用在循环体或其他特殊情况中。

注意:虽然最后一条语句末尾的分号没有用,我却总是加上它,并且建议你也这样做。因为有时你可能需要在末尾添加语句,如果最后没有加分号,你就必须记着加上它,与其如此不如一开始就加上它。

赋值语句

在Pascal 语言中赋值语句用冒号-等号操作符“:=”,对使用其他语言的编程人员来说这是一个奇怪的符号。在其他语言中用作赋值符号的“=”在Pascal 中用作关系运算符,用于判断是否相等。

注意:赋值和相等判断使用不同的符号,使Pascal 编译器(象C编译器一样)能更快解译源代码,因为这样就不需要通过检查上下文来判断符号的意义,此外使用不同操作符也使代码更易读。

条件语句

条件语句通过条件检测,判断是否执行该条件语句中包含的语句。条件语句可有两种基本形式:if语句和case语句。

If语句

procedure TForm1.ButTestIf(Sender: TObject);

var

i,j:Integer;

begin

i:=10;

j:=17;

if i>j then

showmessage('i>j');

end;

If the else语句

procedure TForm1.ButTestIf(Sender: TObject);

var

i,j:Integer;

begin

i:=10;

j:=17;

if i>j then

showmessage('i>j')(注意此处不要加';'号)

else

  showmessage('i<j') ;

else

end;

Case语句

如果你的if语句变得非常复杂,有时可以用case语句代替它。case语句包括用来选值的表达式、可能值序列或一个取值范围。这些值应该是常量, 并且它们必须唯一,而且应属于有序类型。Case语句最后可以带一个else 语句,当没有一个标签与选择器的值一致时,执行else语句。下面是两个简单的例子:

case Number of   1: Text := 'One';   2: Text := 'Two';   3: Text := 'Three'; end;  case MyChar of   '+' : Text := 'Plus sign';   '-' : Text := 'Minus sign';   '*', '/': Text := 'Multiplication or division';   '0'..'9': Text := 'Number';   'a'..'z': Text := 'Lowercase character';   'A'..'Z': Text := 'Uppercase character'; else   Text := 'Unknown character'; end; Delphi语言中的循环

其它编程语言中使用的循环语句,Pascal语言中都有,它们包括 forwhilerepeat 语句。如果你用过其他编程语言,你会发现Pascal中的循环语句没什么特别的,因此这里我只作简要的说明。

For循环 

Pascal 中的for循环严格地建立在计数器基础上,循环每执行一次,计数器不是增加一个值就是减小一个值。下面是一个for语句的简例,用来将前十个数加起来:

var   K, I: Integer; begin   K := 0;   for I := 1 to 10 do     K := K + I; 

同样的for语句可以用正好相反的计数器来写:

var   K, I: Integer; begin   K := 0;   for I := 10 downto 1 do     K := K + I; 

Pascal 中的for循环语句其灵活性比其他语言小(它不能指定1之外的步长),不过简单也容易理解。如果需判断的条件比较复杂,或想自定义计数器,你可以用while语句 或 repeat 语句,而不是for循环语句。

注意:for循环计数器不必非是数字,它可以是任何有序类型的值,例如一个字符或一个枚举类型值。

while语句和repeat语句

while-do 循环语句和 repeat-until 语句的不同点在于repeat 循环语句的代码至少要执行一次。从下面的简例很容易理解这一点:

while (I <= 100) and (J <= 100) dobegin// use I and J to compute something...   I := I + 1;   J := J + 1; end;  repeat// use I and J to compute something...   I := I + 1;   J := J + 1; until (I > 100) or (J > 100); 

从上可见即使 IJ 的初始值大于100,repeat-until循环中的代码也仍会执行一次。

注意:两种循环另一个关键的不同点是,repeat-until 循环的条件是反向的条件,只要不满足这个条件,循环就执行;当条件满足时,循环终止。这正好与while-do 循环相反,while-do 循环当条件是真值时才执行。为此,我不得不在上面代码中用反向条件来获得相同的结果。

注意:用 BreakContinue 系统过程可以改变循环执行的标准流程。Break 中断循环;Continue直接跳至循环测试句,或使计数器增加一个步长,然后继续循环(除非条件为空或计数器达到最大值)。还有两个系统过程 ExitHalt,让你立即从函数或过程中返回,或者终止程序。

With语句

我要讲的最后一种Pascal 语句是With语句,With语句是Pascal编程语言独有的语句,不过最近JavaScript 和Visual Basic也添加了这种语句,它在Delphi程序设计中很有用。

With语句是一种用于简化代码的语句。 如你要访问一个记录类型变量(或一个对象),用With语句就不必每次重复变量的名字。例如对于以下的记录类型代码:

type   Date = record     Year: Integer;     Month: Byte;     Day: Byte;   end;  var   BirthDay: Date;  begin   BirthDay.Year := 1997;   BirthDay.Month := 2;   BirthDay.Day := 14; 

可以用with语句改进后半部分代码,如下:

beginwith BirthDay dobegin     Year := 1995;     Month := 2;     Day := 14;   end; 

在Delphi程序中,这种方法能用于访问控件和类变量。现在通过with语句访问列表框的条目,我们重写上面循环例子的最后部分:

procedure TForm1.WhileButtonClick(Sender: TObject); var   I: Integer; beginwith ListBox1.Items dobegin     Clear; // shortcut     Randomize;     I := 0;     while I < 1000 dobegin       I := I + Random (100);       // shortcut:       Add ('Random Number: ' + IntToStr (I));     end;   end; end; 

当你使用控件或类时,with语句通常能简化你的代码,尤其对嵌套域。例如,你要改变窗体画笔的宽度和颜色,你可以写代码如下:

Form1.Canvas.Pen.Width := 2; Form1.Canvas.Pen.Color := clRed; 

但如果用With语句代码会更简单:

with Form1.Canvas.Pen dobegin   Width := 2;   Color := clRed; end; 

当编写的代码很复杂时,with语句会很有用,也可省去一些临时变量。但是这样做也有缺点,因为这样将使代码的可读性变差,特别对有相似或相同属性的对象。

更严重的是,使用with语句可能会在代码中融入微妙的逻辑错误,甚至连编译器都难以发现。例如:

with Button1 dobegin   Width := 200;   Caption := 'New Caption';   Color := clRed; end; 

这段代码改变了按钮的Caption 和 Width属性,但也改变了窗体的Color属性,而不是按钮的颜色!其原因是 TButton 控件没有Color属性, 又由于执行的代码是针对窗体对象的(我们正在写窗体的方法),所以窗体对象即成为默认的访问对象。如果这样写:

Button1.Width := 200; Button1.Caption := 'New Caption'; Button1.Color := clRed; // error!

编译器会给出一个错误。通常,由于with语句在当前的块中定义了新的标识符,省略了原有的标识符,可能引起在同一块内错误地访问另一个标识符(就 象上面的这段代码)。即使存在种种缺陷,我还是建议你习惯于使用with语句,因为with语句确实是非常便利,并且有时也会使代码更容易读懂。

然而,你应该避免使用多个with语句,如:

with ListBox1, Button1 do... 

这样会使后面的代码非常难读,因为,对该块中定义的每个属性,你都要根据相应的属性以及控件的次序,才能推出所访问的控件。

注意:说到可读性,要知道Pascal 没有endif 或endcase 语句。如果if语句有一个begin-end 块,那么end标志语句结束;另外,case语句也总是以一个end结束。所有这些end语句,常常是一个接一个,使代码难以理解, 只有通过缩排跟踪,才能追出一个end所对应的语句。解决这个问题的一个通用办法, 也是使代码更可读的办法,是在end后面加注释,如下例:

  if ... then    ...   end; // if

如果说数据类型是Pascal 编程的一个基础,那么另一个则是语句。编程语言的语句主要由关键字和操作指令组成。语句常放在过程或函数中,就象我们将在下一部分中看到的那样。现在,我们集中讲解最基本的编程语句。

简单语句和复合语句

Pascal 简单语句中不包含任何别的语句,赋值语句和过程调用即是简单语句的例子。简单语句用分号隔开,如下所示:

X := Y + Z;  // assignment Randomize;   // procedure call

用begin 和end 将简单语句括起来即组成复合语句,复合语句用法与普通的Pascal 语句相同,见下例:

begin   A := B;   C := A * 2; end; 

end之前的最后一条语句末尾分号不是必需的,你可以写成:

begin   A := B;   C := A * 2 end; 

这两种写法都是正确的。第一种多了一个无用(但也无害)的分号。分号实际上是一个空语句,也就是说,是一个没有代码的语句。有时,空语句可用在循环体或其他特殊情况中。

注意:虽然最后一条语句末尾的分号没有用,我却总是加上它,并且建议你也这样做。因为有时你可能需要在末尾添加语句,如果最后没有加分号,你就必须记着加上它,与其如此不如一开始就加上它。

赋值语句

在Pascal 语言中赋值语句用冒号-等号操作符“:=”,对使用其他语言的编程人员来说这是一个奇怪的符号。在其他语言中用作赋值符号的“=”在Pascal 中用作关系运算符,用于判断是否相等。

注意:赋值和相等判断使用不同的符号,使Pascal 编译器(象C编译器一样)能更快解译源代码,因为这样就不需要通过检查上下文来判断符号的意义,此外使用不同操作符也使代码更易读。

条件语句

条件语句通过条件检测,判断是否执行该条件语句中包含的语句。条件语句可有两种基本形式:if语句和case语句。

If语句

procedure TForm1.ButTestIf(Sender: TObject);

var

i,j:Integer;

begin

i:=10;

j:=17;

if i>j then

showmessage('i>j');

end;

If the else语句

procedure TForm1.ButTestIf(Sender: TObject);

var

i,j:Integer;

begin

i:=10;

j:=17;

if i>j then

showmessage('i>j')(注意此处不要加';'号)

else

  showmessage('i<j') ;

else

end;

Case语句

如果你的if语句变得非常复杂,有时可以用case语句代替它。case语句包括用来选值的表达式、可能值序列或一个取值范围。这些值应该是常量, 并且它们必须唯一,而且应属于有序类型。Case语句最后可以带一个else 语句,当没有一个标签与选择器的值一致时,执行else语句。下面是两个简单的例子:

case Number of   1: Text := 'One';   2: Text := 'Two';   3: Text := 'Three'; end;  case MyChar of   '+' : Text := 'Plus sign';   '-' : Text := 'Minus sign';   '*', '/': Text := 'Multiplication or division';   '0'..'9': Text := 'Number';   'a'..'z': Text := 'Lowercase character';   'A'..'Z': Text := 'Uppercase character'; else   Text := 'Unknown character'; end; Delphi语言中的循环

其它编程语言中使用的循环语句,Pascal语言中都有,它们包括 forwhilerepeat 语句。如果你用过其他编程语言,你会发现Pascal中的循环语句没什么特别的,因此这里我只作简要的说明。

For循环 

Pascal 中的for循环严格地建立在计数器基础上,循环每执行一次,计数器不是增加一个值就是减小一个值。下面是一个for语句的简例,用来将前十个数加起来:

var   K, I: Integer; begin   K := 0;   for I := 1 to 10 do     K := K + I; 

同样的for语句可以用正好相反的计数器来写:

var   K, I: Integer; begin   K := 0;   for I := 10 downto 1 do     K := K + I; 

Pascal 中的for循环语句其灵活性比其他语言小(它不能指定1之外的步长),不过简单也容易理解。如果需判断的条件比较复杂,或想自定义计数器,你可以用while语句 或 repeat 语句,而不是for循环语句。

注意:for循环计数器不必非是数字,它可以是任何有序类型的值,例如一个字符或一个枚举类型值。

while语句和repeat语句

while-do 循环语句和 repeat-until 语句的不同点在于repeat 循环语句的代码至少要执行一次。从下面的简例很容易理解这一点:

while (I <= 100) and (J <= 100) dobegin// use I and J to compute something...   I := I + 1;   J := J + 1; end;  repeat// use I and J to compute something...   I := I + 1;   J := J + 1; until (I > 100) or (J > 100); 

从上可见即使 IJ 的初始值大于100,repeat-until循环中的代码也仍会执行一次。

注意:两种循环另一个关键的不同点是,repeat-until 循环的条件是反向的条件,只要不满足这个条件,循环就执行;当条件满足时,循环终止。这正好与while-do 循环相反,while-do 循环当条件是真值时才执行。为此,我不得不在上面代码中用反向条件来获得相同的结果。

注意:用 BreakContinue 系统过程可以改变循环执行的标准流程。Break 中断循环;Continue直接跳至循环测试句,或使计数器增加一个步长,然后继续循环(除非条件为空或计数器达到最大值)。还有两个系统过程 ExitHalt,让你立即从函数或过程中返回,或者终止程序。

With语句

我要讲的最后一种Pascal 语句是With语句,With语句是Pascal编程语言独有的语句,不过最近JavaScript 和Visual Basic也添加了这种语句,它在Delphi程序设计中很有用。

With语句是一种用于简化代码的语句。 如你要访问一个记录类型变量(或一个对象),用With语句就不必每次重复变量的名字。例如对于以下的记录类型代码:

type   Date = record     Year: Integer;     Month: Byte;     Day: Byte;   end;  var   BirthDay: Date;  begin   BirthDay.Year := 1997;   BirthDay.Month := 2;   BirthDay.Day := 14; 

可以用with语句改进后半部分代码,如下:

beginwith BirthDay dobegin     Year := 1995;     Month := 2;     Day := 14;   end; 

在Delphi程序中,这种方法能用于访问控件和类变量。现在通过with语句访问列表框的条目,我们重写上面循环例子的最后部分:

procedure TForm1.WhileButtonClick(Sender: TObject); var   I: Integer; beginwith ListBox1.Items dobegin     Clear; // shortcut     Randomize;     I := 0;     while I < 1000 dobegin       I := I + Random (100);       // shortcut:       Add ('Random Number: ' + IntToStr (I));     end;   end; end; 

当你使用控件或类时,with语句通常能简化你的代码,尤其对嵌套域。例如,你要改变窗体画笔的宽度和颜色,你可以写代码如下:

Form1.Canvas.Pen.Width := 2; Form1.Canvas.Pen.Color := clRed; 

但如果用With语句代码会更简单:

with Form1.Canvas.Pen dobegin   Width := 2;   Color := clRed; end; 

当编写的代码很复杂时,with语句会很有用,也可省去一些临时变量。但是这样做也有缺点,因为这样将使代码的可读性变差,特别对有相似或相同属性的对象。

更严重的是,使用with语句可能会在代码中融入微妙的逻辑错误,甚至连编译器都难以发现。例如:

with Button1 dobegin   Width := 200;   Caption := 'New Caption';   Color := clRed; end; 

这段代码改变了按钮的Caption 和 Width属性,但也改变了窗体的Color属性,而不是按钮的颜色!其原因是 TButton 控件没有Color属性, 又由于执行的代码是针对窗体对象的(我们正在写窗体的方法),所以窗体对象即成为默认的访问对象。如果这样写:

Button1.Width := 200; Button1.Caption := 'New Caption'; Button1.Color := clRed; // error!

编译器会给出一个错误。通常,由于with语句在当前的块中定义了新的标识符,省略了原有的标识符,可能引起在同一块内错误地访问另一个标识符(就 象上面的这段代码)。即使存在种种缺陷,我还是建议你习惯于使用with语句,因为with语句确实是非常便利,并且有时也会使代码更容易读懂。

然而,你应该避免使用多个with语句,如:

with ListBox1, Button1 do... 

这样会使后面的代码非常难读,因为,对该块中定义的每个属性,你都要根据相应的属性以及控件的次序,才能推出所访问的控件。

注意:说到可读性,要知道Pascal 没有endif 或endcase 语句。如果if语句有一个begin-end 块,那么end标志语句结束;另外,case语句也总是以一个end结束。所有这些end语句,常常是一个接一个,使代码难以理解, 只有通过缩排跟踪,才能追出一个end所对应的语句。解决这个问题的一个通用办法, 也是使代码更可读的办法,是在end后面加注释,如下例:

  if ... then    ...   end; // if