目录
本章博客是对程序控制结构和语句剩余的知识点进行补充,废话不多说,gogo!
1、循环结构与语句
当我们遇到的问题需要做重复的、有规律的运算时,这个时候我们就可以使用循环结构来实现。循环结构是程序中一种很重要的结构,其特点是:在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。C语言提供的有三种循环语句,它们可以组成各种不同的循环结构。
分别是以下三种:
(1)for 语句
(2)while 语句
(3)do-while 语句
1.1 循环结构
循环结构是指在满足循环条件时反复执行循环代码块,直到循环条件不满足为止。C语言中有以上三种循环语句,都可用来实现循环结构。这些语句都各有特点,而且常常还可以相互替代,根据想要实现的功能选择最合适的循环语句。下面我们看一个具有循环结构程序的例子,分别使用三种循环语句代码的编写。
例:计算100以内的数之和。
(1)for 语句实现
/* for 语句实现100内的数之和 */
#include<stdio.h>
int main()
{
int i = 0;
int sum = 0;
for (i = 1; i <= 100; i++)
{
sum += i;
}
printf("100以内的数之和: %d\n", sum);
return 0;
}
(2)while 语句实现。
/* while 语句实现100内的数之和 */
#include<stdio.h>
int main()
{
int i = 1;
int sum = 0;
while (100>=i)
{
sum += i;
i++;
}
printf("100以内的数之和: %d\n", sum);
return 0;
}
(3)do-while 语句实现。
/* do-while 语句实现100内的数之和 */
#include<stdio.h>
int main()
{
int i = 1;
int sum = 0;
do
{
sum += i;
i++;
} while (100>=i);
printf("100以内的数之和: %d\n", sum);
return 0;
}
上面三个程序都是是循环结构的程序,在执行过程中会根据循环条件反复执行循环体里面的语句直到条件不能满足为止。不满足 100>=i 这个循环条件则终止循环。通过上面的例子,将对我们进一步理解这三个循环语句奠定了一定的基础。
注意:如果我们要想更直观地查看循环体的运行过程,建议在VS(因为目前我使用的编程环境是VS)上面的运行环境里按[F11]键单步执行每条语句查看。同样,对前面的顺序和选择结构也可以单步执行来查看语句的执行情况。
1.2 当型循环语句----- for 语句
for 语句是C语言最为灵活的一种循环语句,不但可以用于循环次数确定的情况,也可以用于循环次数不确定(只给出循环结束条件)的情况。其一般语法格式为:
for(表达式1;表达式2;表达式3)
{
循环体语句;
}
执行步骤:
①计算表达式 1 的值;
②判断表达式2,如果其值为非 0(真),则执行循环体语句,然后执行第③步;如果其值为0(假),则结束循环,执行第⑤步;
③计算表达式 3 的值;
④返回,继续执行第②步;
⑤循坏结束,执行 for 语句的后续语句。
为了进一步加深理解,将 for 语句的形式改写成:
for(循环变量赋初值;循环条件;循环变量增值)
{
循环体语句;
}
for 循环流程图:
注意:①在 for 语句中,重复执行的部分是循环体语句和表达式 3 ,可见表达式3也是循环体的一部分;表达式 1在进入循环之前求解,只做一次,相当于给循环变量赋初值。②不要在for后面加分号,例如:for(i=100;i<1000;i++);上述 for 语句相当于满足条件执行空语句,真正的循环语句则没有被执行。这是初学者容易犯的错误,又很难察觉出来。
for 循环的扩展形式:
(1)表达式1和表达式3 可以是一个简单的表达式,也可以是逗号表达式(即包含了一个以上的简单表达式),例如:
for(i=0,j=100;i<j;i++,j--)
{
k=i+j;
}
这里的循环控制变量可以不止一个。而且表达式1也可以是与循环变量无关的其他表达式。
(2)循环条件可由一个较复杂表达式的值来确定,例如:
for(i=0;s[i]!=c && s[i]!='\0';++i);
(3)表达式2一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值不等于0就执行循环体。如:
for(i=1;i-4;i++)
{
s+=k;
}
仅当 i 的值等于4 时终止循环。i-4 是数值表达式。
for 循环省略形式
for 循环语句中的3个表达式都是可以省略的。
(1) 省略 “ 表达式1 ”,此时应在 for 语之前给循环变量赋初值。如:
i=0;
for(;i<=100;i++)
{
sum+=i;
}
(2)省略 “ 表达式2 ”,表示不判断循环条件,循环无终止地进行下去,也可以认为表达式 2始终为真。如:
for(i=0;;i++)
{
sum+=i;
}
这样写的话,代码将无休止地执行循环体,一直做累加和。为了终止循环,就要在循环体中加入break 语句和goto 语句等,将在下面讲到。
(3)省略 “ 表达式 3 ”,此时应在循环体内部实现循环变量的增量,以保证循环能够正常结束。如:
for(i=0;i<=10;)
{
sum+=i;
i++;
}
相当于把表达式3写在了循环体内部,作为循环体的一部分。
(4)省略 “ 表达式 1 ” 和 “ 表达式 3 ”,只给出了循环条件。如:
i=0;
for(;i<=100;)
{
sum+=i;
i++;
}
相当于把表达式1放在了循环的外面,表达式3作为循环体的一部分。这种情况与下面将要介绍的while语句完全相同。
(5)3个表达式都省略,既不设初值,也不判断条件,循环变量不增值。无终止地执行循环体。如:
for(;;)
{
循环体语句;
}
注意:表达式可以省,但中间的两个分号不能省略。在省略某个表达式时,应在适当的位置进行循环控制的必要操作,以保证循环的正确执行。
1.3 当型循环语句----- while 语句
while 语句用来实现当型循环,即先判断循环条件,再执行循环体。其一般语法格式为:
while(表达式)
{
循环体语句;
}
执行过程:当表达式为非0(真)时,执行循环体语句,然后重复上述过程,一直到表达式为0(假)时,while 语句结束。
while 流程图。
例如:
i=0;
while(i<=100)
{
sum+=i;
i++;
}
解释:
(1))循环体包含一条以上语句时,应用 “ { } ” 括起来,以复合语句的形式出现,否则它只认
为 while 后面的第1条语句是循环体;
(2)循环前,必须给循环控制变量赋初值,如上例中的( i=0;);
(3)循环体中,必须有改变循环控制变量值的语句(使循环趋向结束的语句),如上例中的 ( i++;),否则循环永远不结束。
for 与 while 区别:
while 与 for 不同的是,while 必须在循环之前设置循环变的初值,在循环中有改变循环变量的语句存在;for 语句是在 “ 表达式1 ” 处设置循环变的初值,在 “ 表达式3 ” 处进行循环变量的增值。
注意:while后面不能直接加 “;”,如果直接在 while 语句后面加了分号,系统会认为循环体是空体,什么也不做。后面用 “ { } ” 括起来的部分只认为是 while 语句后面的下一条语句。
1.4 直到型循环语句----- do-while 语句
do-while 语句实现的是直到型循环,即先执行语句,后判断表达式。其一般的语法格式为:
do
{
循环体语句;
}while(表达式);
执行过程:先执行一次循环体语句,然后判断表达式是否为非 0(真),如果为真,则再次执行循环体语句,如此反复,一直到表达式的值等于 0(假)时,循环结束。
注意:
(1) do-while 语句是先执行循环体 “ 语句 ”,后判别循环终止条件。与 while 语句不同,二者的区别在于:当 while 后面的表达式一开始的值为0(假)时,while 语句的循环体一次也不执行,而 do-while 语句的循环体至少要执行一次。
(2)在书写格式上,循环体部分要用花括号括起来,即使只有一条语句也如此;do-while 语句最后以分号结束。
(3)通常情况下,do-while 语句是从后面控制表达式退出循环。但它也可以构成无限循环,此时要利用 break 语句或 return 语句直接从循环体内跳出循环。
1.5 循环的嵌套
通过上面的学习,已经学习完三种循环语句,之后要做的就是活学活用。循环的嵌套是指一个循环结构的循环体内又包含另一个完整的循环结构。内嵌的循环中还可以嵌套循环,这样就构成了多重循环。
while 嵌套 while
while()
{
......
while()
{
......
}
.....
}
do-while 嵌套 do-while
do
{
......
do
{
.......
}while();
.....
}while();
for 嵌套 for
for(; ; ; )
{
.....
for( ; ; ; )
{
......
}
......
}
while 嵌套 do-while
while
{
......
do
{
.......
}while();
......
}
for 嵌套 while
for( ; ; )
{
......
while()
{
......
}
......
}
来看一个 for 嵌套 for 的例子:打印三角。
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
int l = 0;
for (i = 0; i <= 5; i++)/*打印出三角形边长的 “ * ”个数 */
{
for (j = 1; j <= 5 - i; j++)/*打印出空格*/
{
printf(" ");
}
for (l = 1; l <= 2 * i - 1; l++)/*打印出 “ * ” */
{
printf("*");
}
printf("\n");
}
}
运行结果:
这个例子就不进行解释了,想知道是如何运行出结果的,可以在编译器上面进行单步调试。
2、转向语句
在C语言中还有一类语句,即转向语句,它可以改变程序的流程,使程序从其所在的位置转向另一处执行。转向语句包括3 种,即 goto 语句、break 语句和 continue 语句。
其中 goto 语句是无条件转移语句。break、continue 语句经常用在 while 语句、do-while、for语句和switch 语句中,二者使用时有区别。continue 只结束本次循环,而不是中止整个循环;而break 则是中止本循环,并从循环中跳出。
2.1 goto 语句
goto 语句是无条件转向语句,即转向到指定语句标号处,执行标号后面的程序。其一般语法格式为:
goto 语句标号;
例如:
again:/*语句标号的标记格式,注意:语句标号后面跟冒号 “ : ”,而不是分号*/
goto again;/*使用语法格式*/
看两段代码对比使用 goto 语句和不使用 goto 语句的区别:
使用 goto 语句
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
int l = 0;
for (i = 0; i <= 5; i++)/*打印出三角形边长的 “ * ”个数 */
{
for (j = 1; j <= 5 - i; j++)/*打印出空格*/
{
printf(" ");
}
for (l = 1; l <= 2 * i - 1; l++)/*打印出 “ * ” */
{
printf("*");
}
printf("\n");
if (i > 3)/*当 i 大于3时跳转到标记 end 的标签*/
{
goto end;
}
}
end: /*标记 end 的标签*/
return 0;
}
运行结果:
不使用 goto 语句
#include<stdio.h>
int main()
{
int i = 0;
int j = 0;
int l = 0;
for (i = 0; i <= 5; i++)/*打印出三角形边长的 “ * ”个数 */
{
for (j = 1; j <= 5 - i; j++)/*打印出空格*/
{
printf(" ");
}
for (l = 1; l <= 2 * i - 1; l++)/*打印出 “ * ” */
{
printf("*");
}
printf("\n");
}
}
运行结果:
以上两个例子的代码都有注释,就不解释一遍了,相信都会使用 goto 语句了;
注意:①语句标号必须是合法的标识符,它的命名规则与变量名相同,即由字母数字和下划线组成,第1个字符必须为字母或下划线,而不能使用整数来作标号如:goto 12;是不合法的。②现代程序设计方法主张尽可能地限制 goto 语句的使用。可以使用 if、if-else 和 while 等结构来代替它,以增强代码的可读性。
2.2 break 语句
在上一篇博客里已经说了 break 语句在 switch 语句中的作用是退出switch 语句。那么它在循环语句中使用时,可使程序跳出当前循环结构,执行循环后面的语句。根据程序的目的,有时需要程序在满足另一个特定的条件时立即终止循环,程序继续执行循环体后面的语句,使用 break语句可以实现此功能。
一般的语句格式 为:
break;
break 语句用在循环语句的循环体内的作用是终止当前的循环语句。
注意:break 语句只能用在 switch 语句和循环语句中,而不能用在其他任何语句中。如果 break 语句在循环嵌套中,则只能退出其所在那一层的循环。
2.3 continue 语句
根据程序的目的,有时需要程序在满足另一个特定的条件时跳出本次循环,使用 continue语句可实现该功能。continue 语句的功能与 break 语句不同,它是结束当前循环语句的当前循环,而执行下一次循环。在循环体中,continue 语句被执行之后,其后面的语句均不再执行。
例如: 计算100内所有数之和。
不使用 continue 语句和 使用 continue 语句的差别。
不使用 continue语句:
#include<stdio.h>
int main()
{
int i = 0;
int sum = 0;
for (i = 0; i <= 100; i++)
{
sum += i;
}
printf("100内所有数之和: %d\n", sum);
return 0;
}
结果:
使用 continue语句:
#include<stdio.h>
int main()
{
int i = 0;
int sum = 0;
for (i = 0; i <= 100; i++)
{
if (i == 50)
{
continue;
}
sum += i;
}
printf("100内所有数之和: %d\n", sum);
return 0;
}
结果:
说明: 不使用 continue 语句和 使用 continue 语句的程序运行结果可以看出,使用continue 语句的程序运行结果少50。是因为当 i 等于50时,结束本次循环未执行的语句,继续下次判断。
注意: ① continue 语句用在循环体中,它的作用是忽略循环体中位于它之后的语句重新回到条件表达式的判断。② continue 语句与 break 的区别是:continue 语句只结束本次循环,并不结束整个循环;而 break 语句则结束整个循环不再进行循环条件的判断。在循环嵌套结构中,continue 语句只在它所在的循环控制层内起作用。