![]() |
|
|
PASCAL 精要 |
第五章 语句 |
如果说数据类型是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语句对if-then型语句, 仅当条件满足时,语句才执行;对if-then-else型,if语句在两条语句中选择一条执行。条件用布尔表达式建立,这里通过一个简单的Delphi 例子来示范如何写条件语句。首先,创建一个应用程序,在form上面放两个复选框(check box)和四个按钮(button),不要改变复选框和按钮的名字,双击按钮为其OnClick 事件添加响应程序。下面是第一个按钮事件代码中一条简单的if语句:
procedure TForm1.Button1Click(Sender: TObject);
begin
// simple if statement
if CheckBox1.Checked then
ShowMessage ('CheckBox1 is checked')
end;
当点击button1,如果第一个复选框中有复选标记,那么这个程序将显示一条消息(见图5.1)。我用了ShowMessage 函数,因为它是Delphi中最简单的短信息显示函数。
图 5.1: 例IfTest显示的信息
如果点击按钮后没有反应,表明复选框未被选中。对于这种情况,最好能交代得更清楚些,为此在第二个按钮的代码中,我用了if-then-else 语句:
procedure TForm1.Button2Click(Sender: TObject);
begin
// if-then-else statement
if CheckBox2.Checked then
ShowMessage ('CheckBox2 is checked')
else
ShowMessage ('CheckBox2 is NOT checked');
end;
要注意的是,不能在第一句之后、else 关键词之前加分号,否则编译器将告知语法错误。实际上,if-then-else 语句是单纯的一条语句,因此不能在语句中间加分号。
if 语句可以很复杂,句子中的条件部分可以是一系列条件(用and、 or 、 not等布尔操作符联接起来),if语句又可以嵌套另一个if语句,见例IfTest中其它两个按钮的示范代码:
procedure TForm1.Button3Click(Sender: TObject);
begin
// statement with a double condition
if CheckBox1.Checked and CheckBox2.Checked then
ShowMessage ('Both check boxes are checked')
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
// compound if statement
if CheckBox1.Checked then
if CheckBox2.Checked then
ShowMessage ('CheckBox1 and 2 are checked')
else
ShowMessage ('Only CheckBox1 is checked')
else
ShowMessage (
'Checkbox1 is not checked, who cares for Checkbox2?')
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;Pascal语言中的循环
其它编程语言中使用的循环语句,Pascal语言中都有,它们包括 for、 while 和 repeat 语句。如果你用过其他编程语言,你会发现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) do begin // 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);
从上可见即使 I 或 J 的初始值大于100,repeat-until循环中的代码也仍会执行一次。
注意:两种循环另一个关键的不同点是,repeat-until 循环的条件是反向的条件,只要不满足这个条件,循环就执行;当条件满足时,循环终止。这正好与while-do 循环相反,while-do 循环当条件是真值时才执行。为此,我不得不在上面代码中用反向条件来获得相同的结果。
一个循环语句例子为了探究循环的细节,让我们看一个Delphi 简例,这个循环例子表现了固定计数器循环和随机计数器循环之间的差别。建一个新的工程,在主窗体上放一个listbox和两个button,通过设置Object Inspector中的name属性分别命名button为BtnFor 和BtnWhile。你还可以把Caption 属性中的Btn 去掉,或甚至加上 & ,让跟在 & 后面的字母成为快捷键。下面是该窗体文本描述:
object Form1: TForm1
Caption = 'Loops'
object ListBox1: TListBox ...
object BtnFor: TButton
Caption = '&For'
OnClick = BtnForClick
end
object BtnWhile: TButton
Caption = '&While'
OnClick = BtnWhileClick
end
end
图 5.2: 单击For按钮后显示的结果
现在,我们分别给两个button 添加OnClick 事件代码。第一个button用一个简单的for循环来显示一列数字,结果如图5.2。这个循环向listbox中的Items 属性添加一系列字符串。在执行循环之前,需要清除listbox 中的内容。程序如下:
procedure TForm1.BtnForClick(Sender: TObject);
var
I: Integer;
begin
ListBox1.Items.Clear;
for I := 1 to 20 do
Listbox1.Items.Add ('String ' + IntToStr (I));
end;
第二个button的事件代码稍微复杂点。本例中让while 循环基于一个随机增长的计数器。为实现它,我调用了Randomize 过程, 用它来重置随机数发生器,还调用了Random 函数, 其取值范围为100, 即函数返回0至99之间的随机数,随机数序列控制while 循环的执行次数。
procedure TForm1.BtnWhileClick(Sender: TObject);
var
I: Integer;
begin
ListBox1.Items.Clear;
Randomize;
I := 0;
while I < 1000 do
begin
I := I + Random (100);
Listbox1.Items.Add ('Random Number: ' + IntToStr (I));
end;
end;
每次点击While按钮,出现的数字都不同,因为这些数字取决于随机数发生器。图5.3显示了两次点击的结果,可看到不仅每次产生的数字不同,而且数据项数也不同。也就是说,这个while循环执行的次数是随机的。
图 5.3: 按While按钮后显示的结果
注意:用 Break 和 Continue 系统过程可以改变循环执行的标准流程。Break 中断循环;Continue直接跳至循环测试句,或使计数器增加一个步长,然后继续循环(除非条件为空或计数器达到最大值)。还有两个系统过程 Exit 和 Halt,让你立即从函数或过程中返回,或者终止程序。
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语句改进后半部分代码,如下:
begin
with BirthDay do
begin
Year := 1995;
Month := 2;
Day := 14;
end;
在Delphi程序中,这种方法能用于访问控件和类变量。现在通过with语句访问列表框的条目,我们重写上面循环例子的最后部分:
procedure TForm1.WhileButtonClick(Sender: TObject);
var
I: Integer;
begin
with ListBox1.Items do
begin
Clear; // shortcut
Randomize;
I := 0;
while I < 1000 do
begin
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 do begin Width := 2; Color := clRed; end;
当编写的代码很复杂时,with语句会很有用,也可省去一些临时变量。但是这样做也有缺点,因为这样将使代码的可读性变差,特别对有相似或相同属性的对象。
更严重的是,使用with语句可能会在代码中融入微妙的逻辑错误,甚至连编译器都难以发现。例如:
with Button1 do begin 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的高级内容。
下一章: 过程与函数
© Copyright Marco Cantù, Wintech Italia Srl 1995-2000

written by 访客, May 17, 2006
if CheckBox1.Checked then
begin
ShowMessage ('CheckBox1 is checked')
ShowMessage ('CheckBox1 is checked')
ShowMessage ('CheckBox1 is checked')
ShowMessage ('CheckBox1 is checked')
end
else
begin
ShowMessage ('CheckBox1 is NOT checked');
ShowMessage ('CheckBox1 is NOT checked');
ShowMessage ('CheckBox1 is NOT checked');
ShowMessage ('CheckBox1 is NOT checked');
end;





procedure TForm1.Button1Click(Sender: TObject);
begin
// simple if statement
if CheckBox1.Checked then
ShowMessage ('CheckBox1 is checked')
end;
如果要在showmessage后面让他调处这个函数