第五课 流程语句

  首先,什么是语句?为什么需要语句?语句又是怎么组成的?语句简单的说就是一个分号结尾的句子,我们可以称为这是一条语句。那这条句子就是由一些关键字和操作指令组成。语句通常放在过程和函数中,一个程序通常都是由若干个语句组成,没有语句,当然程序也就无法运行。

语句从大的范围可以分为简单语句和复合语句。

简单语句和复合语句

  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语言中都有,它们包括 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) 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 面板中的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按钮后显示的结果

注意:用 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语句改进后半部分代码,如下:

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的高级内容。

下一页: 过程与函数

时间: 2024-10-16 01:27:58

第五课 流程语句的相关文章

第七课第一节,T语言流程语句( 版本5.0)

流程语句 if语句 用if语句可以构成分支结构.它根据给定的条件进行判断,以决定执行某个分支程序段.TC综合开发工具的if语句有三种基本形式,并且每个语句的结尾都要有一个end (注:关键字,if,else,elseif,end) 执行流程图解: if语句在在开发应用使用的频率很高,一般都是用来做判断使用比如:判断是否符合某中条件等等 语句举例:实现在区域内找某一个点的颜色,支持模糊查找 var 返回的x坐标=0,返回的y坐标=0 findpic(0,0,600,800,"/sdcard/111

【C++探索之旅】第一部分第五课:简易计算器

内容简介 1.第一部分第五课:简易计算器 2.第一部分第六课预告:控制流程,随心所至 简易计算器 上一课<[C++探索之旅]第一部分第四课:内存,变量和引用>中,我们已经学习了挺重要的内存的概念,变量的知识,对引用这个C++中常用的技术也有了初步的了解. 我们在上一课开头处用一个小小计算器的存储技术引出内存的概念.其实我们的电脑兄也是一个计算器,只不过高端大气上档次了很多,不然怎么会被称为 computer呢?英语中compute这个词,正是<计算>的意思,而加上r就构成了名词.c

linux就该这么学第五课

linux就该这么学第五课 vim编辑器 命令模式 复制:yy 剪切删除:dd u:撤销上一步的操作 p:将之前操作的步骤返回 n/N:搜索下一个字符串/搜索上一个字符串 输入模式 直接输入即可,跟记事本一样 末行模式 :w保存 :q退出 q!:强制退出 :命令 直接执行相应命令 :整数 跳转到该行 输入模式无法直接进入末行模式,反之一样,都需要通过命令模式进入输入模式或者末行模式 编辑脚本 固定格式: #! /bin/bash #注释 相应命令 接受用户参数 $0:shell脚本的名称 $#:

第五课 进程管理

unix_c_05.txt================第五课 进程管理================一.基本概念------------1. 进程与程序~~~~~~~~~~~~~1) 进程就是运行中的程序.一个运行着的程序,可能有多个进程.进程在操作系统中执行特定的任务.2) 程序是存储在磁盘上,包含可执行机器指令和数据的静态实体.进程或者任务是处于活动状态的计算机程序.2. 进程的分类~~~~~~~~~~~~~1) 进程一般分为交互进程.批处理进程和守护进程三类.2) 守护进程总是活跃的

BeagleBone Black板第五课:Shell脚本编程实验

BBB板第五课:Shell脚本编程实验 在一上课我们通过简单的echo命令测试并控制GPIO端口的高低电平输出,实现对一个LED指示灯的点亮和关闭控制,本节将通过Shell脚本编程,来完成两个LED指示灯的交替闪亮的实验. 实验器材:准备两个二极管指示灯,面包板等 使用GPIO端口P8.12和P8.11两个引脚 我们暂时不借助其他工具软件,直接远程登陆到BBB板的图形桌面,使用内置的Ledfpad编辑器来完成Shell脚本的编程. 远程登陆BBB板图形桌面还记得吧,不记得话参考前面的课程,这里就

NeHe OpenGL教程 第五课:3D空间

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. 第五课:3D空间 3D空间: 我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体. 在上节课的内容上作些扩展,我们现在开始生成真正的3D对象,而不是象前两节课中那样3D世界中的2D对象.我们给三角形增加一

【C语言探索之旅】 第一部分第五课:运算那点事

内容简介 1.课程大纲 2.第一部分第五课:运算那点事 3.第一部分第六课预告:条件表达式 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算那点事 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量类型 文件读写

04 Java基础 -控制流程语句

/* 控制流程语句: 语句: 使用分号分隔的代码就是一个语句. 顺序语句: 按照代码顺序从上往下执行所有的代码就是顺序语句 ; 也是一个语句 */ class Demo1 {     public static void main(String[] args){     /*     int i = 10;  //声明变量的语句         ;//空语句         System.out.println("Hello World!"); //输出语句             *

【Linux探索之旅】第三部分第五课:延时执行,唯慢不破

内容简介 1.第三部分第五课:延时执行,唯慢不破 2.第三部分测验题 延时执行,唯慢不破 上一课(<[Linux探索之旅]第三部分第四课:后台运行及合并多个终端>)中,我们学习了后台进程以及如何在一个终端里打开多个虚拟终端. 到目前为止,我们所运行的命令都是立即执行,也就是我们按下回车键的那一刻,命令就开始执行了. 其实Linux中命令还可以延时执行.这一课我们就来学习几个命令,可以帮助我们<稍后>执行程序.比如我们即将学习到的crontab命令. 所有这一课新学的命令都涉及到时间