第6章 程序设计的基本结构
从程序流程的角度来看,程序可以分为三种基本结构:顺序结构、分支结构和循环结构。这三种基本结构可以组成所有的各种复杂程序。程序设计的基本组成部分是语句,不同语句组成不同的程序结构。例如,for语句、while语句组成循环结构程序。本章将介绍程序设计的三种基本结构及其语句。
6.1 顺序结构程序设计
顺序结构程序是指程序中的语句由表达式语句、函数调用语句、控制语句、复合语句、空语句或赋值语句构成。顺序结构是程序中最基本的结构之一,最大的特点是程序是以从上至下的顺序执行。
6.1.1 表达式语句
表达式语句是最基本的语句,由表达式加上分号“;”组成。其一般形式为:
表达式;
以下代码都是表达式语句。
x=y+z; //赋值语句; y+z; //加法运算语句,但计算结果不能保留,无实际意义; i++; //自增1语句,i值增1。
6.1.2 函数调用语句
由函数名、实际参数加上分号“;”组成。其一般形式为:
函数名(实际参数表);
执行函数语句就是调用函数体并把实际参数赋予函数定义中的形式参数,然后执行被调函数体中的语句,求取函数值(在后面函数中再详细介绍)。以下代码调用trace函数输出数据。
trace("C Program"); //在控制台下输出字符串。
6.1.3 复合语句
把多个语句用括号{}括起来组成的一个语句称复合语句。在程序中应把复合语句看成是单条语句,而不是多条语句。以下代码是一条复合语句。
{ x=y+z; a=b+c; trace("x.toString()+a.toString()); }
复合语句内的各条语句都必须以分号“;”结尾,在括号“}”外不能加分号。
6.1.4 空语句
只有分号“;”组成的语句称为空语句。空语句是什么也不执行的语句。在程序中空语句可用来作空循环体。以下代码是一空循环。
while(s!="\n") ;
本代码的功能是只要字符不是回车符就一直等待。
6.1.5 赋值语句
赋值语句是由赋值表达式再加上分号“;”构成。其一般形式为:
变量=表达式;
赋值语句的功能和特点都与赋值表达式相同。它是程序中使用最多的语句之一。在赋值语句的使用中需要注意以下几点:
1.表达式嵌套
赋值符“=”右边的表达式也可以是一个赋值表达式。示例如下。
变量=(变量=表达式);
该表达式是成立的。其展开之后的一般形式为:
变量=变量=…=表达式;
以下代码是一条赋值语句。
a=b=c=d=e=5;
按照赋值运算符的右接合性,代码相当于:
e=5; d=e; c=d; b=c; a=b;
2.变量赋初值与赋值语句的区别
给变量赋初值是变量说明的一部分,赋初值后的变量与其后的其他变量之间必须用逗号间隔。而赋值语句必须用分号结尾。以下代码说明变量赋初值和赋值语句的区别。
var a:int=5,b:int,c:int;
3.赋值表达式与赋值语句的区别
赋值表达式是一种表达式,它可以出现在任何允许表达式出现的地方,而赋值语句则不能。
以下代码是合法的。
if((x=y+5)>0) z=x;
此代码的功能是:若表达式x=y+5大于0,则z=x。以下代码是非法的:
if((x=y+5;)>0) z=x;
因为x=y+5;是语句,不能出现在表达式中。
6.2 分支结构程序设计
分支结构程序是指程序中存在分支的逻辑,需要分别处理各分支的逻辑。分支结构程序常用的语句有:if语句、if…else语句、if…else…if语句、switch语句。分支结构是程序中最基本的结构之一,最大的特点是程序是分支处理。
6.2.1 if语句
if语句的语法形式如下所示。
if(表达式) 语句
其语义是:如果表达式的值为真,则执行其后的语句。否则不执行该语句。if语句逻辑如图6-1所示。
图6-1 if语句逻辑图
以下代码使用if语句实现取最大值。
var a:int=2,b:int=5,max:int; max=a; if (max<b) max=b; trace(max.toString());
本例程序中两个数a,b。把a先赋予变量max,再用if语句判别max和b的大小。如max小于b,则把b赋予max。因此max中总是大数,最后输出max的值。
6.2.2 if…else语句
if…else语句的语法形式如下所示。
if(表达式) 语句1; else 语句2;
其语义是:如果表达式的值为真,则执行语句1,否则执行语句2。If…else语句逻辑如图6-2所示。
图6-2 if…else语句逻辑图
以下代码使用if…else语句判断大小。
var a:int=5,b:int=10; if(a>b) trace("max= "+a.toString()); else printf("max="+b.toString());
此代码中用if…else语句判别a,b的大小。若a大,则输出a,否则输出b。
6.2.3 if…else…if语句
if语句和if…else语句一般用于两个选择分支的情况。当有两个以上选择分支时,可采用if…else…if语句,其一般形式为:
if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; … else if(表达式m) 语句m; else 语句n;
其语义是:依次判断表达式的值,当出现某个值为真时,则执行其对应的语句。然后跳到整个if语句之外继续执行程序。如果所有的表达式均为假,则执行语句n。然后继续执行后续程序。if…else…if语句的逻辑如图6-3所示。
图6-3 if…else…if语句逻辑图
以下代码使用if…else…if语句判断字符类型。
var c:String="m"; //定义变量c var t:int=c.charCodeAt(0); //获取变量c的ASCII码 if(t<32) trace("是控制字符。\n"); else if(t>="0".charCodeAt(0)&&t<="9".charCodeAt(0)) trace("是数字。\n"); else if(t>="A".charCodeAt(0)&&t<="Z".charCodeAt(0)) trace("是大写字母。\n"); else if(t>="a".charCodeAt(0)&&t<="z".charCodeAt(0)) trace("是小写字母。\n"); else trace("是其他字符。\n");
· charCodeAt方法是String类中的方法,用于获取某一位上的ASCII码。在ActionScript 3.0语言中无单字符变量,所有单字符或字符串都以String类型存储。
· 小于32的ASCII码为控制字符。0的ASCII码为32。大写字母A的ASCII码为65。小写字母a的ASCII码为97。
在使用if语句中还应注意以下问题。
1.表达式形式的多样性
在三种形式的if语句中,在if关键字之后均为表达式。该表达式通常是逻辑表达式或关系表达式,但也可以是其他表达式,如赋值表达式等,甚至也可以是一个变量。以下代码中判断条件分别为赋值表达式和变量。
if(a=5) 语句; if(b) 语句;
a=5表达式的值永远为非0,所以其后的语句总是要执行的。这种情况在程序中不一定会出现,但在语法上是合法的。以下代码中使用赋值表达式。
if(a=b) trace(a); else trace("0");
此代码中把b值赋予a,如为非0则输出该值,否则输出“a=0”字符串。
2.if语句格式
在if语句中,条件判断表达式必须用括号括起来,在语句之后必须加分号。
3.if语句中使用复合语句
在if语句的三种形式中,所有的语句应为单个语句。如果要想在满足条件时执行一组(多个)语句,则必须把这一组语句用“{}”括起来组成一个复合语句。注意的是在“}”之后不能再加分号。
以下代码中使用了复合语句。
if(a>b) { a++; b++; } else { a=0; b=10; }
6.2.4 if语句的嵌套
当if语句中的执行语句又是if语句时,就构成了if语句嵌套的情形。
其一般形式如下所示。
if(表达式) if语句;
或者为:
if(表达式) if语句; else if语句;
在嵌套内的if语句可能又是if…else语句,这将会出现多个if关键字和多个else关键字的情况,这时要特别注意if和else的配对问题。
以下代码中有多个if和else关键字。
if(表达式1) if(表达式2) 语句1; else 语句2;
ActionScript 3.0语言规定,else总是与它前面最近的if配对。
以下代码说明了if和else关键字的配对规则。
var a:int=4,b:int=5; if(a!=b) if(a>b) trace("A>B\n"); else trace("A<B\n"); else trace("A=B\n");
本例中用了if语句的嵌套结构。采用嵌套结构实质上是为了进行多分支选择,实际上有三种选择即A>B、A<B或A=B。这种问题用if…else…if语句也可以完成,而且程序更加清晰。因此,在一般情况下较少使用if语句的嵌套结构。以使程序更便于阅读理解。
上述代码可改写为:
var a:int=4,b:int=5; if(a==b) trace("A=B\n"); else if(a>b) trace("A>B\n"); else trace("A<B\n");
6.2.5 switch语句
ActionScript 3.0语言还提供了另一种用于多分支选择的语句:switch语句,其一般形式为:
switch(表达式) { case常量表达式1: 语句1; case常量表达式2: 语句2; … case常量表达式n: 语句n; default : 语句n+1; }
switch语句的意思是:计算表达式的值,并逐个与其后的常量表达式值相比较。当表达式的值与某个常量表达式的值相等时,即执行其后的语句。然后不再进行判断,继续执行后面所有case后的语句。若表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
以下代码使用switch语句判断是星期几。
var a:int=3; switch (a) { case 1:trace("Monday\n"); case 2:trace("Tuesday\n"); case 3:trace("Wednesday\n"); case 4:trace("Thursday\n"); case 5:trace("Friday\n"); case 6:trace("Saturday\n"); case 7:trace("Sunday\n"); default:trace("error\n"); }
本程序根据数字输出是星期几。但当满足case 3条件之后,却执行了case 3以及以后的所有语句,输出了Wednesday及以后的所有单词。这是因为在switch语句中,“case常量表达式”只相当于一个语句标号。当表达式的值和某标号相等则转向该标号执行。在执行完该标号的语句后不会自动跳出整个switch语句。这与if语句完全不同。为了避免上述情况,ActionScript 3.0语言中提供了一种break语句,用于跳出switch语句。break语句没有参数,这在后面还将详细介绍。
上述代码应作如下修改。
var a:int=3; switch (a) { case 1:trace("Monday\n");break; case 2:trace("Tuesday\n"); break; case 3:trace("Wednesday\n"); break; case 4:trace("Thursday\n"); break; case 5:trace("Friday\n"); break; case 6:trace("Saturday\n"); break; case 7:trace("Sunday\n"); break; default:trace("error\n"); break; }
在使用switch语句时还应注意以下几点:
(1)在case后的各常量表达式的值不能相同,否则会出现错误。
(2)在case后允许有多个语句,可以不用“{}”括起来。
(3)各case和default子句的先后顺序可以变动,不会影响程序执行结果。
(4)default子句可以省略。
6.3 循环结构程序设计
循环结构是程序中一种很重要的结构。其特点是:在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。ActionScript 3.0语言提供的循环语句如下所示。
· 用goto语句和if语句构成循环
· while语句
· do-while语句
· for语句
6.3.1 goto语句
goto语句是一种无条件转移语句。goto语句的一般形式如下所示。
goto 语句标号;
其中标号是一个有效的标识符,这个标识符后紧接一个冒号“:”。执行goto语句后,程序将跳转至该标号处,执行其后的语句。另外,标号必须与goto语句同处于一个函数中,但可以不在一个循环层中。使用goto语句与if条件语句可以实现程序循环。
以下代码使用goto语句和if语句构成循环,计算从1加至100的总和。
public From1To100():void { var i:int=1,sum:int=0; loop: if(i<=100) { sum=sum+i; i++; goto loop; } trace(sum.toString()); }
goto语句一般不用,因为它将使程序层次不清,且程序不易读。但在多层嵌套退出时,用goto语句则比较合理。
6.3.2 while语句
while语句的一般形式如下所示。
while(表达式) 语句
其中表达式是循环条件,语句为循环体。while语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句。while语句的逻辑如图6-4所示。
图6-4 while语句逻辑图
以下代码中使用while语句计算 。
public From1To100():void { var i:int=1,sum:int=0; while(i<=100) { sum=sum+i; i++; } trace(sum.toString()); }
6.3.3 do-while语句
do-while语句的一般形式如下所示。
do 语句 while(表达式);
do-while语句与while语句的不同在于:do-while语句先执行循环中的语句,然后再判断表达式。如果表达式为真则继续循环,如果为假,则终止循环。因此do-while语句至少要执行一次循环体。其逻辑如图6-5所示。
图6-5 do-while语句逻辑图
以下代码用do-while语句求 。
public From1To100():void { var i:int=1,sum:int=0; do { sum=sum+i; i++; } while(i<=100); trace(sum.toString()); }
需注意的是:do-while语句后面的分号“;”不能省略。
以下代码说明了while语句和do-while语句的区别。
//使用while语句 var sum:int=0,i:int=11; while(i<=10) {sum=sum+i; i++; } trace("sum="+sum.toString()); //使用do-while语句 var sum:int=0,i:int=11; do {sum=sum+i; i++; } while(i<=10); trace("sum="+sum.toString());
使用while语句的代码结果为:sum=0,i=11。使用do-while语句的代码结果为:sum=11,i=12。这是因为while语句先进行条件判断。当i=11时,不满足i<=10的条件,所以不会执行循环体中的代码。但do-while语句会先执行一次循环体中的代码,然后根据条件判断是否退出循环体。
6.3.4 for语句
在ActionScript 3.0语言中,for语句使用最为灵活。它完全可以取代while语句,其一般形式如下所示。
for(表达式1;表达式2;表达式3) 语句
for语句的执行过程如下所示。
(1)求解表达式1。
(2)求解表达式2。若其值为真(非0),则执行for语句中指定的内嵌语句,然后执行下面第3步。若其值为假(0),则结束循环,转到第5步。
(3)求解表达式3。
(4)转回上面第2步继续执行。
(5)循环结束,执行for语句下面的一个语句。
for语句的逻辑如图6-6所示。
图6-6 for语句逻辑图
for语句最简单的应用形式也是最容易理解的形式如下所示。
for(循环变量赋初值;循环条件;循环变量增量) 语句
循环变量赋初值是一个赋值语句,用以给循环控制变量赋初值。循环条件是一个关系表达式,决定什么时候退出循环。循环变量增量定义了循环控制变量在每次循环后的变化方式。这三个部分之间用分号间隔。
以下代码中使用了for语句。
for(i=1; i<=100; i++) sum=sum+i;
此代码先给i赋初值为1,判断i是否小于等于100。若是,则执行语句。语句执行后i增加1。重新判断,直到条件为假,即i>100时结束循环。
上述代码可用while语句来表示。
i=1; while(i<=100) { sum=sum+i; i++; }
for语句的一般形式,可用while语句表示。
表达式1; while(表达式2) { 语句 表达式3; }
for语句需注意的地方包括:
1.表达式省略
for语句中的表达式1、表达式2和表达式3都是选择项,可以缺省,但“;”不能缺省。
省略了表达式1表示不对循环控制变量赋初值。
省略了表达式2表示没有循环条件,这样就进入了死循环。应避免这种情况。
以下代码省略了表达式2。
for(i=1;;i++)sum=sum+i;
省略了表达式3 表示不对循环控制变量进行操作。这时可在循环体中加入修改循环控制变量的语句。
以下代码省略了表达式3。
for(i=1;i<=100;) { sum=sum+i; i++; }
省略了表达式1和表达式3表示不对变量赋初值,且不修改循环控制变量。
以下代码省略了表达式1和表达式3。
for(;i<=100;) { sum=sum+i; i++; }
3个表达式可以都省略,表示无条件循环。
以下代码省略了表达式1、表达式2和表达式3。
for(;;) 语句
2.表达式1的多样性
表达式1可以是设置循环变量的初值的赋值表达式,也可以是其他表达式。以下代码中表达式1设置了其他值。
for(sum=0;i<=100;i++)sum=sum+i;
3.使用逗号表达式
表达式1和表达式3可以是一个简单表达式,也可以是逗号表达式。
以下代码中表达式1或表达式3是逗号表达式。
for(sum=0,i=1;i<=100;i++)sum=sum+i; for(i=0,j=100;i<=100;i++,j--)k=i+j;
6.3.5 循环的嵌套
循环体语句中可以又是循环语句,这样就形成了循环的嵌套。例如,for语句的循环体语句中又包括for语句。层层嵌套的循环在程序中经常见到,但一般嵌套的次数不宜超过5次。因为这样会使程序的可读性和执行效率变差。
以下代码是for语句的层层嵌套。
var i:int,j:int,k:int; for (i=0; i<2; i++) for(j=0; j<2; j++) for(k=0; k<2; k++) trace(i.toString()+","+j.toString()+","+k.toString());
6.3.6 几种循环语句的比较
· 四种循环语句都可以用来处理同一个问题,一般可以互相代替。其中for语句功能最强大,goto语句尽量少使用。
· while语句和do-while语句的循环体语句中应包括使循环趋于结束的语句,从而避免死循环。
· 用while语句和do-while语句时,循环变量初始化的操作应在while和do-while语句之前完成。而for语句可以在表达式1中实现循环变量的初始化。
6.3.7 break语句
break语句通常用在循环语句和开关语句中。当break语句用于do-while语句、for语句或while语句中时,可使程序终止循环而执行循环后面的语句。break语句一般总是与if语句联合使用,即满足条件时便跳出循环。break语句的逻辑如图6-7所示。
图6-7 break语句逻辑图
以下代码中使用break语句跳出循环。
var i:int=0; var c:String="\0"; while(1) { if(c=="\0") break; }
使用break语句应注意的地方包括:
· break语句对if…else的条件语句不起作用。
· 在多层循环中,一个break语句只向外跳一层。
6.3.8 continue语句
continue语句的作用是跳过循环体中剩余的语句而强行执行下一次循环。continue语句只用在for语句、while语句或do-while语句中,常与if语句一起使用,用以加速循环。continue语句的逻辑如图6-8所示。
图6-8 continue语句逻辑图
以下代码使用continue语句加速循环执行。
var i:int=0; var c:String="ok"; while(1) { if(c=="ok") { continue; i--; } else { i++; } }
此代码中,当满足c==“ok”条件时,程序执行下一次循环,而不执行i--这条语句。
6.4 小结
与其他大部分程序一样,ActionScript 3.0语言中的基本结构也包括顺序结构、分支结构、循环结构。顺序结构程序由表达式语句、函数调用语句、复合语句、空语句、赋值语句组成,其特点是程序按顺序执行。分支结构程序中有不同的逻辑分支,需要分别处理。分支结构程序可使用if语句、if…else语句、if…else…if语句、switch语句来实现分支处理。循环结构程序中当循环条件成立时,程序执行循环体中的语句,直至循环条件不成立。循环结构程序可使用while语句、do-while语句、for语句来实现循环。其中for语句功能最为强大。break语句和continue语句可分别用于退出循环和加速循环。