在生活中有许多事情需要反复去做,才能达到预期的目的。比如学习的过程,我对陌生的知识通过学习,然后在经过反复的复习才能长期的记住。这样一个反复的过程就是循环。
循环结构就是重复的执行某一过程,直到得出自己想要的结果或者达到循环结束的条件时,结束循环。循环结构能够大大减少程序代码的书写量,提高代码的利用率。
循环结构可以看成是一个条件判断语句和一个向回转向语句的组合。循环结构组成三要素:循环变量、循环体、循环终止条件。
在C语言中,主要有四种循环结构,它们分别是:while循环、do-while循环、for循环以及goto循环。
6.1 循环结构
在C语言中,主要有四种循环结构,它们分别是:while循环、do-while循环、for循环以及goto循环。
为了能够大概理解循环结构,我们在本节将会简单的介绍两种最常用,最早接触的循环结构,它们分别是:当型循环结构(相当于while循环)和直到型循环结构(相当于do-while循环)。无论是当型循环结构还是直到型循环结构,我们高中数学中就有所接触,所以大家应该理解起来非常的容易。
6.1.1 当型循环结构
当型循环结构首先判断是否满足循环条件,如果满足条件,则执行循环体中的语句。否则就是结束循环。

如图6.1(a)中,是当型循环结构的流程图。程序执行时,首先判断“循环条件”,如果“循环条件”为真,则执行“循环体”。如果“循环条件”为假,则结束“循环体”的执行或者根本就不执行“循环体”。
在图6.1(b)中,是一个当型循环的实例流程图。假设程序已经完成的基本的初始化工作,如i初始化为1。首先就会判断是不是“i<=100”为真?也就是“1<=100”,如果为真,则就会执行循环体“i++;”,显然满足循环条件,接着执行循环体。此时i自加以后变成2,再判断“2<=100”?显然仍然满足条件。...我们依次经过100次循环,此时i值等于100,然后我们判断是否“100<=100”?显然这个也满足题意,执行循环体“i++;”。i就变成101,接着进行判断是否“101<=100”?很明显为假。所以结束程序的循环,顺序执行循环体后面的语句。举一个生活中的实例。
6.1.2 直到型循环结构
直到型循环结构首先执行的是循环体中的语句,在判断循环条件。如果满足循环条件,再次执行循环体中的语句,如果不满足循环条件,则结束循环。

如图6.2(a)中,是直到型循环结构的流程图。程序执行时,首先执行“循环体”,然后判断“循环条件”,如果“循环条件”为真,则再次执行“循环体”。如果“循环条件”为假,则结束“循环体”的执行。
在图6.2(b)中,是一个直到型循环的实例流程图。假设程序已经完成的基本的初始化工作,如i初始化为1。首先就会会执行循环体“i++;”,然后再判断是不是“i<=100”为真?也就是“1<=100”,如果为真,则就会继续执行循环体“i++;”,否则结束。显然满足循环条件,接着执行循环体“i++;”。此时i自加以后变成2,再判断“2<=100”?显然仍然满足条件。...我们依次经过100次循环,此时i值等于100,然后我们判断是否“100<=100”?显然这个也满足题意,仍然执行循环体“i++;”。i就变成101,接着进行判断是否“101<=100”?很明显为假。所以结束程序的循环,顺序执行循环体后面的语句。
在生活中这样的例子也是无处不在,比如:当一个男生突然有一天看到了一个心仪的女生,希望这个漂亮的女生能够做他的女朋友。于是,就开始的写他的第一封情书(循环体),可是这个女生不喜欢这个男生,所以直接拒绝了这个男生(循环条件)。但是,这个男生发现他真的喜欢上了这个女生,希望每天都能够见到这个女生,如果哪一天见不到她,就会茶不思饭不想,甚至还天天梦见她。为了追到她,男生写了第二封,第三封情书,,,直到第81封的时候,这个女孩子终于心动了,为这个男生的执着所打动。最后他们幸福的在一起了。从这个例子中我们就会看到“循环体”就是“情书”,循环结束条件就是写到“第81封”的时候结束。小伙伴你是怎么最女生的呢?哈哈。
6.2 while循环结构
6.2.1 while循环结构基本介绍
while循环结构首先判断是否满足循环条件,如果满足条件,则执行循环体中的语句。否则就是结束循环。
while循环的基本语法:
while(表达式) 循环体语句
while循环在执行的过程中,首先判断while后面的“表达式”,如果表达式始终为真,则重复执行循环体。直到表达式为假时,才结束while循环的执行。就是说while循环是先执行表达式的判断,然后根据判断结果来选择是否执行循环体。如图4.1所示,为while循环的流程图。但是在使用的过程中,我们需要注意三点:
(1) while循环中的“表达式”一般为关系表达式或者逻辑表达式,当表达式为真时,执行“循环体语句”。
(2) 如果循环体语句两个及两个以上要用{}(花括号)括起来。
即:
while(表达式)
{
循环体语句1;
循环体语句2;
}
比如:
int a = 1;
while(a <= 10)
{
printf(“%d\n”, a);
a++;
}
同时两个及两个以上组成的循环体语句,又称为复合体语句。还需要注意在写程序时程序需要初始化,否则将会出现不可预知的错误。
(3) 在书写循环时,应尽量保证循环体能够正常结束。除非有特殊要求(比如开机后的操作系统就是一个死循环)。

【例6.1】求1+2+3+…+100的值。
解题思路:我们可以通过循环变量num来控制1~100数值的变化,并初始化为1。然后设定循环结束条件为循环变量小于等于100,再定义另一变量sum作为统计变量的累加和。
编写代码:
#include <stdio.h>
int main()
{
int num = 1, sum = 0;
while (num <= 100)
{
sum += num;
num++;
}
printf("1+2+…+100 = %d\n", sum);
return 0;
}
运行结果:
1+2+…+100 = 5050
Press any key to continue
程序分析:程序第4行,定义变量num并初始化为1。第5~9行为程序核心代码,首先判断num是不是小于100。由于num初始化为1,所以小于100,满足条件执行循环体。第7行又等价于“sum = sum + num;”,表示sum加上num的值赋给sum。第8行等价于“num = num + 1”,表示num的值加上1,再赋值给num。得出的num值再返回第5行,判断num是否小于100,如果小于就继续执行循环。否则跳出while循环执行第10行,输出结果。
此处还可以添加程序实例。实例太少。尽量多的添加代码。while循环的代码。
6.2.2 while循环嵌套
在实际编程中,我们会遇到一层循环中还有一层或多层循环,那么这样多重循环组成的结构成为循环嵌套。
while循环嵌套的基本语法:
外层while循环在执行的过程中,首先判断while后面的“表达式”,如果表达式始终为真,则重复执行循环体。直到表达式为假时,才结束while循环的执行。同理,当外层表达式为真时,就会执行循环体,就是说内层while循环就开始执行了。具体执行规则和方式与执行外层while循环一样。如图6.4所示,为两层while循环嵌套的流程图。但是在使用的过程中,我们需要注意与单层循环类似,此处不再赘述。建议无论多层还是一层循环嵌套,都应该用{}把循环体中要执行的语句括起来,这样会给编程提供很大的便利。

比如:
int a = 1, b = 1;
int sum = 0;
while(a <= 5)
{
b = 1;
while(b <= 50)
{
sum += b;
b++;
}
a++;
}
printf(“%d\n”, sum);
该段程序实现的功能等价于(1+2+…+50)*5的最终结果。
【例6.2】输出九九乘法口诀。
解题思路:
九九乘法口诀表如下:
1×1 =1 |
|
|
|
|
|
|
|
|
1×2=2 | 2×2=4 |
|
|
|
|
|
|
|
1×3=3 | 2×3=6 | 3×3=9 |
|
|
|
|
|
|
1×4=4 | 2×4=8 | 3×4=12 | 4×4=16 |
|
|
|
|
|
1×5=5 | 2×5=10 | 3×5=15 | 4×5=20 | 5×5=25 |
|
|
|
|
1×6=6 | 2×6=12 | 3×6=18 | 4×6=24 | 5×6=30 | 6×6=36 |
|
|
|
1×7=7 | 2×7=14 | 3×7=21 | 4×7=28 | 5×7=35 | 6×7=42 | 7×7=49 |
|
|
1×8=8 | 2×8=16 | 3×8=24 | 4×8=32 | 5×8=40 | 6×8=48 | 7×8=56 | 8×8=64 |
|
1×9=9 | 2×9=18 | 3×9=27 | 4×9=36 | 5×9=45 | 6×9=54 | 7×9=63 | 8×9=72 | 9×9=81 |
由表我们看出,在九九乘法口诀表的同一列中被乘数保持不变,乘数依次加1。在不同的列中,从左向右被乘数依次增加1,同时列中乘式个数依次减1。并且被乘数小于等于乘数。那么我们就可以定义两个变量:一个变量表示被乘数,作用于内层循环。一个变量表示乘数,作用与外层循环。外层变量共循环9次,内层变量小于等于外层变量。具体代码如下。
编写程序:
#include <stdio.h>
int main()
{
int i=1,j=1;
while (i <= 9)/*外层循环*/
{
j=1;
while(j <= i)/*内层循环,内层循环变量小于外层循环变量*/
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;//每一次循环变量加1
}
i++;
printf("\n");//每执行一次外层循环,换行一次
}
return 0;
}
运行结果:
1×1= 1
1×2= 2 2×2= 4
1×3= 3 2×3= 6 3×3= 9
1×4= 4 2×4= 8 3×4=12 4×4=16
1×5= 5 2×5=10 3×5=15 4×5=20 5×5=25
1×6= 6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7= 7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8= 8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9= 9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
Press any key to continue
程序分析:第5~15行为程序的核心代码。本程序共有两个while循环,且属于while循环的嵌套。外层while循环为乘数,内层while循环为被乘数。外层循环执行一次,内层循环就会执行一个循环。
此处while循环嵌套的代码过少,添加实例。
6.3 do-while循环结构
6.3.1 do-while循环结构基本介绍
do-while循环结构是while循环的变体。do-while循环首先执行循环中的语句,然后判断是否满足循环条件,如果满足循环执行循环中的语句,直到不满足循环条件,则结束循环。
do-while循环的基本语法:
do
循环体语句;
while(表达式);
do-while循环在执行的过程中,首先执行循环体,然后判断while后面的“表达式”是否为真,如果表达式始终为真,则重复执行循环体。直到表达式为假时,才结束while循环的执行。就是说while循环是先执行循环体语句,然后进行表达式的判断,根据判断结果来选择是否重复执行循环体。如图6.5所示,为do-while循环的流程图。但是在使用的过程中,我们需要注意两点:
- do-while语句的特点是“先执行,后判断”。即无论“表达式”的初始值为真还是为假,循环体都会先被执行一次。
- 如果do-while循环中,有多条语句组成,必须用{}括起来,形成复合语句。
复合语句的语法:
do
{
循环体语句1;
循环体语句2;
}while(表达式);
比如:
int a = 1;
do
{
printf(“%d\n”, a);
a++;
}while(a <= 100);
即do-while循环里面的语句全部用{}括起来。

【例6.3】求1+2+3+…+100的值。
解题思路:我们可以通过循环变量num来控制1~100数值的变化,并初始化为1。然后设定循环结束条件为循环变量小于等于100,再定义另一变量sum作为统计变量的累加和。前提是我们知道程序至少会执行一次。
编写程序:
#include <stdio.h>
int main()
{
int num = 1, sum = 0;
do/*do-while*/
{
sum += num;//用sum统计100以内的和
num++;//每一次变量加1
}while (num <= 100);
printf("1+2+…+100 = %d\n", sum);//输出结果
return 0;
}
运行结果:
1+2+…+100 = 5050
Press any key to continue
程序分析:程序中用num表示要加的数字,比如:1,2,3,...,100,这些数。用sum统计这些数的值。程序第9行while后面的括号是循环的判断语句。判断语句成立继续执行循环,如果判断语句不成立,则结束循环的执行,转到程序第10行继续执行。
此处添加代码。do-while的代码。
6.3.2 do-while循环嵌套
如同while循环嵌套一样,do-while循环也也可以实现循环的嵌套。如下。
do-while循环嵌套的基本语法:
外层do-while循环每执行一次,内层就会执行一个完整的循环。比如:
int a = 1, b = 1;
int sum = 0;
do
{
b = 1;
do
{
sum += b;
b++;
}while(b <= 50);
a++;
}while(a <= 5);
当外层循环中a每加一次,内层循环b就会从1加到50,做一个50次的循环。
如图6.6所示,为两层do-while循环嵌套的流程图。但是在使用的过程中,我们需要注意与while循环类似,建议为每一层循环,都用{}把循环体中要执行的语句括起来,这样会给编程提供很大的便利,提高程序的可读性。

【例6.4】输出九九乘法口诀。
解题思路:结合程序【例6.2】的分析,我们现在要给写成do-while循环的嵌套。首先do-while循环是先执行循环体语句,然后在进行判断,并且外层循环执行一次,内层就会执行一个循环。所以我们可以把外层循环变量作为被乘数,内层循环变量作为乘数。
编写代码:
#include <stdio.h>
int main()
{
int i=1,j=1;
do
{
j=1;
do
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;
}while(j <= i);/*内层循环*/
i++;
printf("\n");
}while (i <= 9);/*外层循环*/
return 0;
}
运行结果:
1×1= 1
1×2= 2 2×2= 4
1×3= 3 2×3= 6 3×3= 9
1×4= 4 2×4= 8 3×4=12 4×4=16
1×5= 5 2×5=10 3×5=15 4×5=20 5×5=25
1×6= 6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7= 7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8= 8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9= 9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
Press any key to continue
程序分析:程序并不是非常复杂,和【例6.2】类似,大家可以此作为参考。
在程序的实际操作中我们会发现while循环和do-while循环的区别,我们首先看下面一个分别用while循环和do-while循环写程序事例:
程序1:
#include <stdio.h>
int main()
{
int a = 5;
while(a<5)
{
printf("%d\n", a);
a++;
}
return 0;
}
运行结果:
Press any key to continue
程序2:
#include <stdio.h>
int main()
{
int a = 5;
do
{
printf("%d\n", a);
a++;
}while(a<5);
return 0;
}
运行结果:
5
Press any key to continue
通过这两个程序运行结果的对比,我们发现while循环没有输出结果,而do-while循环却输出了一个结果:5。因为什么呢?就是因为while循环和do-while循环他们的运行特性所决定的。while循环是先判断,再执行。所以a=5时,在while循环的表达式中执行判断“a<5”是否为真,因为为假,所以便不会执行循环体。而do-while循环由于先执行循环体,然后在判断表达式,这就决定了会先输出一个5,再a++的值为6,然后在判断表达式“a<5”是否为真,即“6<5”是否为真,显然为假。所以结束do-while循环的执行。
6.4 for循环结构
6.4.1 for循环结构基本介绍
for循环语句是我最喜欢使用的循环语句,同时也是C语言中使用频率频率最高的循环语句。for循环语句又称技术循环语句。for循环比while循环语句和do-while循环语句都要灵活,是一种功能更强、更常用的循环语句。
for循环的基本语法:
for(表达式1; 表达式2; 表达式3)
{
循环体语句;
}
各个表达式的作用:
表达式1:设置初始条件(比如i=1),初始条件可以是零个、一个或多个等,当变量是多个时,用“,”分隔,比如:
for(i=0,sum=1,b=2 ; ... ; ... )
{}
表达式1在for循环中只执行一次,并且是for循环的第一个执行表达式。
表达式2:是for循环的判断表达式,用来判断是否继续执行for循环,还是结束for循环的执行。每次执行循环体前都需要先判断表达式的真假,以此决定for循环的执行方向。比如:
for(i=0,sum=1,b=2; i<10 ; ... )
{}
for循环中执行完“表达式1”,就会执行“表达式2”。
表达式3:循环结构的控制。可以作为循环次数控制,比如:
for(i=0,sum=1,b=2; i<10 ; i++ )
{}
“表达式3”会在“表达式1”,“表达式2”,“循环题语句”执行之后执行。
for循环执行顺序的流程图,如图6.7所示。

其执行顺序为:
- 执行“表达式1”。
- 执行“表达式2”,“表达式2”为判断语句。如果“表达式2”为真,执行“循环体语句”。否则结束for循环语句。
- 执行“表达式3”。
- 转到(2)中,以此循环执行for语句。
- 结束for循环的执行,顺序执行for循环后面的语句。
按上述步骤依次执行循环结构直到程序满足结束条件,或者循环次数就会结束for循环的执行。
for循环一般形式为如下:
for( 循环变量赋初值 ; 循环条件 ; 循环变量增值 )
{
循环体语句;
}
如图6.8 为for循环一般形式的流程图。

比如:
for(i = 1 , sum = 0 ; i <= 100 ; i++ )
{
sum += i;
}
其中:
(1) “i=1”表示:i为循环变量,并赋初值为1;
(2) “i<=100”表示:当i值小于等于100为真时,执行for循环。否则结束for 循环。即i的循环次数为100次。
(3) “sum += i”表示:sum每一次加上i值,然后在赋值给sum,等价于sum=sum+i。 也就是说,该for循环的功能就是实现1~100的累加和。
(4) “i++”表示:控制循环变量的次数,同时有参与循环体语句的运算。“i++” 表示i加上1,然后赋值给i,等价于i=i+1;
总的来说,该程序实现的功能就是计算1+2+3+…+100的累加和。
那么,该for循环还可以变形成为其他结构,比如以下:
- 把初始化的i=1写在for循环的前面,即让“表达式1”省略,但for循环中不能省略“表达式1”后面的“;”。例如:
i = 1;
sum = 0;
for( ; i <= 100 ; i++ )/*此处省略“表达式1”*/
{
sum += i;
}
- 让for循环中的“表达式2”省略,同样“表达式2”后面的分号不能省略。如果“表达式2”省略,则表示for循环成为永真式。比如:
for(i = 1 , sum = 0 ; ; i++ )/*此处省略“表达式2”*/
{
sum += i;
}
如果内存够大程序会一直执行下去。当然,我们也可以用其他的方式让for循环结束执行,比如break语句、exit语句、return语句等,我们将在后面的章节中介绍。
- 如果我们不写“循环体语句”而是把相应的实现功能写到“表达式3”中,那么就会有如下情况:
for(i = 1, sum = 0 ; i <= 100 ; i++ )/*此处省略“循环体语句”*/
{
}
为了是程序可以完整执行,则进一步可以改写成:
for(i = 1 ; i <= 100 ; sum += i , i++ );
- 当然我们也可以省略“表达式3”,如果省略“表达式3”,将会有如下形式:
for( i = 1 , sum = 0 ; i <= 100 ; )/*此处省略“表达式3”*/
{
sum += i;
}
为了是程序可以完整执行,则进一步可以改写成:
for(i = 1 ; i <= 100 ; )
{
sum += i;/*“循环体语句”*/
i++;/*实现“表达式3”的功能*/
}
以for循环的基本语法为例,分别转换成为对应的while循环和do-while循环。
(1) for循环转换为while循环:
表达式1;
while (表达式2)
{
循环体语句;
表达式3;
}
注:二者是无条件等价,即可以实现无缝转换。
- for循环转换为do-while循环:
表达式1;
do
{
循环体语句;
表达式3;
}while(表达式2);
注:二者是有条件转换,即for循环必须至少执行一次,才可以转换成为do-while循环。这由do-while循环的性质所决定。
【例6.5】求1+2+3+…+100的值。
解题思路:我们可以通过循环变量num来控制1~100数值的变化,并初始化为1。然后设定循环结束条件为循环变量小于等于100,再定义另一变量sum作为统计变量的累加和。
编写程序:
#include <stdio.h>
int main()
{
int num, sum;
for(num = 1, sum = 0; num <= 100; num++)/*for循环*/
{
sum += num;//实现结果累加
}
printf("1+2+…+100 = %d\n", sum);//输出结果
return 0;
}
运行结果:
1+2+…+100 = 5050
Press any key to continue
程序分析:大家会发现其实这个程序和【例6.1】以及【例6.3】一样,都是为了解决100以内的和的问题。此处不再赘述。
6.4.2 for循环嵌套
如同while循环和do-while循环的嵌套一样,for循环也也可以实现循环的嵌套。如下。
for循环嵌套的基本语法:
外层for循环每执行一次,内层就会执行一个完整的循环。比如:
int a = 1, b = 1;
int sum = 0;
for(a=1 ; a<=50 ; a++)
{
for( b=1 ; b<=50 ; b++)
{
sum += b;
}
}
当外层循环中a每加一次,内层循环b就会从1加到50,做一个50次的循环。
如图6.9所示,为两层for循环嵌套的流程图。但是在使用的过程中,我们需要注意与while循环或者do-while循环类似,建议为每一层循环,都用{}把循环体中要执行的语句括起来,这样会给编程提供很大的便利,提高程序的可读性。

【例6.6】输出九九乘法口诀。
解题思路:结合程序【例6.2】的分析,我们现在要给写成for循环的嵌套。首先for循环需要循环变量初始化,然后在进行判断,并且外层循环执行一次,内层就会执行一个循环。所以我们可以把外层循环变量作为被乘数,内层循环变量作为乘数。每执行一个内层循环,循环变量都会被初始化为1。
编程程序:
#include <stdio.h>
#define N 9 /*宏定义,定义N代表数字9*/
main()
{
int i,j;
for(i=1; i<=N; i++)/*外层循环*/
{
for(j=1; j<=i; j++)/*内层循环*/
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
}
printf("\n");
}
}
运行结果:
1×1= 1
1×2= 2 2×2= 4
1×3= 3 2×3= 6 3×3= 9
1×4= 4 2×4= 8 3×4=12 4×4=16
1×5= 5 2×5=10 3×5=15 4×5=20 5×5=25
1×6= 6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7= 7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8= 8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9= 9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
Press any key to continue
程序分析:程序第2行的“#define N 9”为宏定义,就是说用N代替数值9,即N的值就是9。第10行在输出时会加上一些空格,是为了保证输出格式的美观。第12行是换行,为了输出成阶梯状的格式。
注意:
#define的三个作用:
- 定义标识,标示有效范围为整个程序。
- 定义常数,比如:#define N 9,即N代表9。
- 定义函数,比如:#define obtainMax(a,b) ((a)>(b)?(a):(b))。
【例6.7】判断200以内的正整数有多少素数,并输出所有的素数。
解题思路:素数只能被1和自身整除的正整数,1不是素数。要判断一个正整数是否为素数,需要检查该数是否能被1和自身以外的其他数整除,即判断正整数n能否被2~n-1之间的数整除,如果能被其中任意一个数整除,那么n不是素数,否则n就是素数。
在程序中可以用求余%来表示能否整除。即n%(2~n-1)进行依次判断。但是在数学中还有一个更加高效的方法,就是区间变成[2, sqrt(n)]。因为如果一个数不是素数,那么它一定可以由两个自然数相乘得到,其中一个大于等于它的平方根,一个小于等于它的平方根。
编写程序:
#include <stdio.h>
int main()
{
int i,j,k=0;
printf("200以内的素数有:\n");
for(i=2;i<=200;i++)/*列举2~200中所有的数*/
{
for(j=2;j<=i;j++)/*判断要求数字是否为可能为素数*/
if(i%j==0) break;
if(j>=i)/*如果j>=i,表明是素数*/
{
printf("%3d ",i);
k++;
if(k%5==0) printf("\n");//按照每行输出5个形式输出结果。
}
}
printf("\n");
}
运行结果:
200之间的素数有:
2 3 5 7 11
13 17 19 23 29
31 37 41 43 47
53 59 61 67 71
73 79 83 89 97
101 103 107 109 113
127 131 137 139 149
151 157 163 167 173
179 181 191 193 197
199
Press any key to continue
程序分析:程序第9行如果i去j的余数为0,表示i可能是素数也可能不是素数,因为如果成多倍整除就不是素数。如果倍数为一,表示为素数。所以就有第10行判断被除数与除数是否相等。相等就是素数。否则,反之。
添加代码。for循环嵌套代码。
6.5 三种循环的相互嵌套
在我们讲解while循环、do-while循环和for循环的时候,我们都相应的介绍的它们各自的循环嵌套格式。但是它们嵌套是它们自己的类型。那么是不是可以while循环嵌套do-while循环呢?或者do-while循环嵌套for循环呢?再或者for循环嵌套while循环呢?答案是肯定的。下面我们将介绍三种循环间的嵌套。
以上6中循环分别是while循环嵌套do-while循环和for循环,如(1)、(2)。do-while循环中嵌套while循环和for循环,如(3)、(4)。for循环中嵌套while循环和do-while循环,如(5)、(6)。此处我们还用九九乘法口诀来实现,输出结果与之前对应例题的效果一样。
- while循环中嵌套do-while循环。
int i=1,j=1;
while (i <= 9)/*外层循环*/
{
j=1;
do
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;
}while(j <= i);/*内层循环*/
i++;
printf("\n");
}
- while循环中嵌套for循环。
int i=1,j=1;
while (i <= 9)/*外层循环*/
{
j=1;
for(j=1; j<=i; j++)/*内层循环*/
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
}
i++;
printf("\n");
}
- do-while循环中嵌套while循环。
int i=1,j=1;
do
{
j=1;
while(j <= i)/*内层循环*/
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;
}
i++;
printf("\n");
}while (i <= 9);/*外层循环*/
- do-while循环中嵌套for循环。
int i=1,j=1;
do
{
for(j=1; j<=i; j++)/*内层循环*/
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
}
i++;
printf("\n");
}while (i <= 9);/*外层循环*/
- for循环中嵌套while循环。
int i,j;
for(i=1; i<=9; i++)/*外层循环*/
{
j=1;
while(j <= i)/*内层循环*/
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;
}
printf("\n");
}
- for循环中嵌套do-while循环。
int i,j;
for(i=1; i<=9; i++)/*外层循环*/
{
j=1;
do
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;
}while(j <= i);/*内层循环*/
printf("\n");
}
6.6 goto循环结构
6.6.1 goto语句循环基本介绍
goto语句又称无条件转移语句,其跳转方向既可以是前方,又可以是后方。goto语句是一种不建议使用的跳转语句,因为如果goto语句的使用会造成程序流程的混乱,是理解和调试都产生困难。
goto语句的基本语法:
goto 语句标号;
C语言中不限制程序中使用标号的次数,但各标号不得重名。goto语句的语义是改变程序流向,转去执行语句标号所标识的语句。
goto语句通常与条件语句配合使用。可用来实现条件转移、构成循环、跳出循环等功能。
比如:
int i;
i = 1;
label:
if( i <= 100)
{
printf("%d\n", i);
i++;
goto label;
}
我们已经介绍了goto语句的基本语法:goto 语句标号;。如上例第8行所示,“goto label;”中的label就是语句标号。而第3行的label就是goto语句要跳转的地方。也就是说执行完第8行的“goto label;”会跳转到第2行的“label:”处,再顺序执行。语句标号就是指明goto语句要跳转到的位置。如图6.10所示为该实例的流程图。

整个程序的执行步骤如下:
- 程序i赋初值。
- 判断i是否小于等于100,如果是执行(3),如果不是执行(5)。
- 输出i的值,并且i++。
- 无条件转移到(2)。
- 结束goto语句的执行,顺序下面的语句。
【例6.8】求1+2+3+…+100的值。
解题思路:我们可以通过循环变量num来控制1~100数值的变化,并初始化为1。然后设定循环结束条件为循环变量小于等于100,再定义另一变量sum作为统计变量的累加和。
编写程序:
#include <stdio.h>
int main()
{
int num, sum;
num = 1, sum = 0;
lable://标签位置
if( num <= 100)
{
sum += num;//统计100以内的和
num++;//数值每次加1
goto lable;//跳转到lable标签的位置。
}
printf("1+2+…+100 = %d\n", sum);
return 0;
}
运行结果:
1+2+…+100 = 5050
Press any key to continue
程序分析:事实上,goto语句在C语言中并不提倡使用,因为过多goto语句的使用会导致程序结构的混乱,为后期的维护带来极大地不便。此处讲解goto语句,仅共大家了解。
6.6.2 goto语句嵌套
同其他三种循环一样,goto也有自己的循环嵌套。当然由于goto语句的嵌套没有固定的位置(既可以向前,又可以向后),所以很难书说明goto语句的嵌套。但是由于其形式同单个goto语句一样。所以理解起来也并非难事。接下来我们将通过具体的实例介绍goto语句的嵌套。
【例6.9】输出九九乘法口诀。
解题思路:结合程序【例6.2】的分析,我们现在给出写成goto语句的循环嵌套。goto语句通过其后面的标签,用于标记出要跳转的位置。
编写代码:
#include <stdio.h>
#define N 9
int main()
{
int i,j;
i=1;
label1://外层标签的位置
if(i<=N)
{
j=1;
label2://内层标签的位置
if(j<=i)
{
printf("%d×%d=%2d ", j,i,i*j);/*输出乘法口诀*/
j++;
goto label2;/*内层循环*/
}
printf("\n");
i++;
goto label1;/*外层循环*/
}
}
运行结果:
1×1= 1
1×2= 2 2×2= 4
1×3= 3 2×3= 6 3×3= 9
1×4= 4 2×4= 8 3×4=12 4×4=16
1×5= 5 2×5=10 3×5=15 4×5=20 5×5=25
1×6= 6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36
1×7= 7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49
1×8= 8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64
1×9= 9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81
Press any key to continue
程序分析:详情请看程内部注释。
6.7 break与continue
在程序的运行过程中,如果我们想要提前结束程序的运行时,怎么办呢?当然C语言为我们准备了两种改变程序运行方向的语句:break和continue语句。break语句的作用是结束有效范围内的整个循环。continue语句的作用是结束本次循环,执行下一次循环。下面就让我们详细的了解这两者详细信息,以及他们的联系与区别吧!!!
6.7.1 break语句的介绍
在循环体中通过break语句,能够提前结束循环体的执行,转去执行循环外的语句。
break语句的基本语法:
break;
其作用就是跳出循环体,去执行循环体之外的语句。如图6.11所示,为break的流程图。
比如:
for(i = 1 , sum = 0 ; i <= 100 ; i++ )
{
sum += i;
if(sum > 100)
{
break;
}
}
printf(“%d\n”, sum);
该程序是求1~100的累加和,但是如果累加和大于100,那么程序就会结束。说白了,就是计算小于100的累加和。如图6.12所示,为改程序的流程图。


注意:
- break语句不能用于循环语句和switch语句以外的其他任何语句中。常与循环语句、switch或if语句配合使用。
- 一个break语句只向外跳一层,如果是多层循环的嵌套,那么需要按照嵌套的次序逐步用break跳出循环。
- break语句应用在switch中,只跳出switch语句。
- 总的来说break语句结束是按照就近原则,结束当前循环。
【例6.10】
6.7.2 continue语句的介绍
我们已经知道break语句是结束当前循环的执行,可是如果我们想要只是结束当前一次循环,而不是整个循环的结束呢?那么continue语句应运而生。
continue语句的基本语法:
continue;
其作用就是就是结束本次循环,执行下一次循环。如图6.13所示,为break的流程图。
比如:
for(i = 1 ; i <= 100 ; i++ )
{
if(0 == i%2)
{
continue;
}
printf("%d\n", i);
}
该程序是输出100以内所有的奇数。如图6.14的流程图所示。


【例6.11】100以内奇数累加和:1+3+…+99 = ?。
解题思路:
我们有两种方法来求:
方法1:我们用变量i表示从1到100的累加变量,用sum表示累加和。判断是否i%2的余数是否为0,如果为零,表示i为偶数,就用continue语句结束该次循环,执行下条循环。否则i就是奇数,就让sum加上对应的让sum加上i。
方法2:我们还是设置变量i从1到100的累加变量,但是i的增值变成了2,即i=i+2,就是i值的变化范围是1,3,5,…,99。然后在定义sum表示累加和,这样直接和sum累加就行。
注:我们此次只介绍方法1,方法2留给同学们自己去思考。
编写代码:
#include <stdio.h>
int main()
{
int i,sum;
for(i = 1 , sum = 0 ; i <= 100 ; i++ )
{
if(0 == i%2)//i取2的余数为0表示i为偶数,否则为奇数。
{
continue;
}
sum += i;
}
printf("1+3+…+99 = %d\n", sum);
return 0;
}
运行结果:
1+3+…+99 = 2500
Press any key to continue
程序分析:程序较简单,不在做过多解释。
注意:
1. continue语句不能用于循环语句和switch语句以外的其他任何语句中。常与循环语句、switch或if语句配合使用。
2. 在一个循环体中,一个continue语句只终止本次循环的执行,即跳过循环体语句中continue语句后面的尚未执行的语句,接着进行下次判断。
6.7.3 break语句与continue语句的联系与区别
6.7 沙场点兵