C51的基本程序结构有3种,即顺序结构、选择结构和循环结构。
顺序结构是一种最基本、最简单的编程结构。在这种结构中,程序由低地址向高地址顺序执行指令代码。如图3-2所示,程序要先执行A,然后再执行B,二者是顺序执行的关系。顺序结构的特点如下:
● 执行过程是按顺序从第1条语句执行到最后1条语句;
● 在程序执行过程中,顺序结构程序中的任何一个可执行语句都要运行一次,而且只能运行一次。
选择结构是对给定的条件进行判断,再根据判断的结果决定执行哪一个分支。如图4-3所示,图中P代表一个条件,当P条件成立(或称为“真”)时,执行A,否则执行B。注意,只能执行A或B之一,两条路径汇合在一起,然后从一个出口退出。
图3-2 顺序结构
图3-3 选择结构
选择结构的语句有if条件语句和switch开关语句等。
1)if条件语句 if语句有以下3种结构形式。
【形式1】
在这种结构形式中,如果括号中的表达式成立,则程序执行“{}”中的语句;否则程序将跳过“{}”中的语句部分,顺序执行其他语句。例如:
【形式2】
在这种结构形式中,如果小括号中的表达式成立,则程序执行“{语句1;}”中的语句;否则执行程序“{语句2;}”中的语句。在项目二中的P_test.c源程序就采用了此种形式进行条件判断。
【形式3】
在这种结构形式中,如果括号中的表达式1成立,则程序执行“{语句1;}”中的语句,然后退出if选择语句,不执行下面的语句;否则,如果表达式2成立,则程序执行“{语句2;}”中的语句,然后退出if选择语句,不执行下面的语句;否则,如果表达式3成立,则程序执行“{语句3;}”中的语句,然后退出if选择语句,不执行下面的语句;……;否则,如果表达式m成立,则程序执行“{语句m;}”中的语句,然后退出if选择语句,不执行下面的语句;否则,上述表达式均不成立,则程序执行“{语句n;}”中的语句。
如果if语句中又包含一个或多个if语句时,这种情况称为if语句的嵌套。if语句的嵌套基本形式如下:
2)switch开关语句 在实际使用中,通常会碰到多分支选择问题,此时可以使用if嵌套语句来实现。但是,如果分支很多的话,if语句的层数太多,程序冗长,可读性降低,而且很容易出错。在C语言中,使用switch语句可以很好地解决多重if嵌套容易出现的问题。switch语句是另一种多分支选择语句,是用于实现多方向条件分支的语句。
(1)switch语句格式。
(2)switch语句使用说明。
● switch后面括号内的表达式可以是整数型表达式或字符型表达式,也可以是枚举型数据。
● 当switch后面表达式的值与某一“case”后面的常量表达式相等时,就执行该“case”后面的语句,然后遇到break语句而退出switch语句。若所有“case”中常量表达式的值都没有与表达式的值相匹配,就执行default后面的语句。
● 每一个case的常量表达式的值必须互不相同,否则就会出现互相矛盾的现象(对同一个值,有两种或多种解决方案提供)。
● 每个case和default的出现次序不影响执行结果,可先出现“default”再出现其他的“case”。
● 假如在case语句的最后没有“break;”,则流程控制转移到下一个case继续执行。所以,在执行一个case分支后,使流程跳出switch结构,即终止switch语句的执行,可用一个break语句完成。
循环结构是在给定条件成立时,反复执行某段程序。在C语言中,用于实现循环的语句有goto语句、while语句、do-while语句和for语句等。
1)goto语句 goto语句为无条件转向语句,该语句可以实现循环。goto语句的一般形式如下:
其中,语句标号不必特殊加以定义,它是一个任意合法的标识符,其命名规则与变量名相同,由字母、数字和下划线组成,并且第一个字符必须为字母或下划线,不能用整数作为标号。这个标识符加上一个“:”一起出现在函数内某处时,执行goto语句后,程序将跳转到该标号处并执行其后的语句。标号必须与goto语句同处于一个函数中,但可以不在一个循环层中。
结构化程序设计主张限制使用goto语句,主要是因为它将使程序层次不清,且不易读,但也并不是绝对禁止使用goto语句,在多层嵌套退出时,用goto语句则比较合理。一般来说,使用goto语句可以有以下两种用途:与if语句一起构成循环结构,从循环体中跳转到循环体外。
(1)与if语句一起构成循环结构。
【例3-2】用if语句和goto语句构成循环结构,求 ,编写的程序如下:
(2)从循环体中跳转到循环体外。在C语言中,如果要跳出本层循环和结束本次循环,可以使用break语句和continue语句。goto语句的使用机会已大大减少,只是需从多层循环的内层跳到多层循环体外时才用到goto语句。但是,这种用法不符合结构化原则,一般不宜采用,只有在特殊情况(如需要大大提高生成代码的效率)时才使用。
2)while语句 while语句很早就出现在C语言编程的描述中,它是最基本的控制元素之一,用于实现“当型”循环结构。while语句的一般格式如下:
若程序的执行进入while循环的顶部时,将对表达式求值。如果该表达式为“真”(非零),则执行while循环内的语句。当执行到循环底端时,马上返回到while循环的顶部,再次对表达式进行求值。如果值仍为“真”,则继续循环,否则完全绕过该循环,而继续执行紧跟在while循环后的语句,其流程图如图3-4所示。
图3-4 while语句的流程图
【例3-3】用while语句,求 ,编写的程序如下:
3)do-while语句 do-while循环与while循环十分相似,而区别在于do-while语句是先执行循环后判断,即循环内的语句至少执行一次,然后再判断是否继续循环,其流程图如图3-5所示。do-while语句的一般格式如下:
图3-5 do-while语句流程图
【例3-4】用do-while语句,求 ,编写的程序如下:
4)for语句 在C语言中,for语句使用最为灵活,完全可以取代while语句或do-while语句。它不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环结束条件的情况。for语句的一般格式如下:
for语句流程图如图3-6所示,其执行过程如下:
图3-6 for语句流程图
①先对表达式1赋初值,进行初始化。
②判断表达式2是否满足给定的循环条件,若满足循环条件,则执行循环体内语句,然后执行第③步;若不满足循环条件,则结束循环,转到第⑤步。
③若表达式2为“真”,则在执行指定的循环语句后,求解表达式3。
④回到第②步继续执行。
⑤退出for循环,执行后面的下一条语句。
for语句最简单的应用形式也就是最易理解的形式如下:
【例3-5】用for语句,求 ,编写的程序如下:
显然,用for语句简单、方便。对于以上for语句的一般形式也可以用相应的while循环形式来表示:
同样,for语句的一般形式还可以用相应的do-while循环形式来表示:
5)break和continue语句
(1)break语句:break语句通常可以用在switch语句或循环语句中。当break语句用于switch语句中时,可使程序跳出switch而执行switch后的语句;当break语句用于while语句、do-while语句或for语句中时,可使程序提前终止循环而执行循环后面的语句。通常break语句总是与if语句连在一起的,即满足条件时便跳出循环。break语句的一般格式如下:
注意:(1)break语句不能用于循环语句和switch语句外的任何其他语句中。
(2)break语句只能跳出它所处的那一层循环,而不像goto语句那样可以直接从最内层循环中跳出来。因此,要退出多重循环时,采用goto语句比较方便。
(2)continue语句:continue语句一般用在while语句、do-while语句或for语句中,其功能是跳过循环体中剩余的语句而强行执行下一次循环。通常continue语句总是与if语句连在一起的,用于加速循环。continue语句的一般格式如下:
continue语句和break语句的区别:break语句结束循环,不再进行条件判断;continue语句只能结束本次循环,不终止整个循环。