C语言控制流程:循环结构
- C语言
- 2024-06-11
- 430热度
- 0评论
while循环
循环结构的必要性
前面讨论了编程中进行判断的各种方法,然而有些问题仅仅通过判断还不能解决。某些情况中,为解决一个问题常常需要重复执行一个或多个操作。例如,要求输出从1—5分别乘以10所得的乘法表。
例:输出从1—5分别乘以10所得的乘法表
程序清单 sample.c
#include <stdio.h>
int main()
{
int result1,result2,result3,result4,result5;
result1 = 1 * 10;
printf("1 * 10 = %d\n",result1);
result2 = 2 * 10;
printf("2 * 10 = %d\n",result2);
result3 = 3 * 10;
printf("3 * 10 = %d\n",result3);
result4 = 4 * 10;
printf("4 * 10 = %d\n",result4);
result5 = 5 * 10;
printf("5 * 10 = %d\n",result5);
}
程序编写5条语句计算乘积,再编写另外5条语句显示这些乘积。如果要求输出1—100的数与10相乘的乘法表呢?就需要重复编写100次这样的语句。这样既费时又费力。我们需要一种方法可以快速有效地执行重复性操作。在C语言中,可以通过循环结构来解决这类问题。
循环结构是程序中一种很重要的结构。其特点是,在给定条件成立时,重复执行某程序段,直到条件不成立为止。给定的条件成为循环条件,反复执行的程序段称为循环体。C语言提供了三种不同形式的循环结构:
while循环结构
用于在特定条件为真的情况下重复执行某些操作,在执行循环体之前先检查条件,一旦条件为假,循环就停止。
do—while循环结构
同样用于在特定条件为真的情况下重复执行某些任务。但是在do—while循环中,是在执行循环语句之后再检查条件。因此,在循环结束前,循环体内的语句至少会被执行一次。
for循环结构
fou循环与while循环在功能上类似,只要条件为真,就会执行循环体中的语句。同样,也是在执行循环语句之前先检查条件,但是,其语法规则与while循环有所不同。
while循环
while循环的一般语法是:
while( 表达式 )
语句;
其中,表达式是循环条件,语句为循环体。while语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句,一旦条件为假,就停止执行循环体。如果条件在开始时就为假,则不执行循环体语句直接退出循环。
循环体语句可以是空语句、单条语句或语句集。如果是语句集,则要用“{”和“}”把它们括起来,用于循环条件的表达式必须返回真或假。
例:输出从1—10分别乘以10所得的乘法表
程序清单 sample.c
#include <stdio.h>
int main()
{
//声明变量num,初值为1
int num=1;
// 声明变量result,存储计算结果
int result;
while( num <=10 )
{
result = num * 10;
printf(" %d * 10 = %d \n",num,result);
//使用自增运算符,修改循环变量
num++;
}
}
程序声明了两个int类型的变量num和result,分别用来存储数字和乘积。然后,将num初始化为1,因为打算在while循环中从1开始执行乘法运算,求出1—10的数字与10的乘积,因此将while循环的条件编写为num<=10。这样确保了只要num小于等于10,就执行while循环;而当此条件变为假时,即num的值达到11时,就结束此循环。循环体中的第一个语句用num乘以10,将计算结果保存在变量result中。第二个语句输出乘法表,循环体中的最后一个语句将num的值递增1,来修改num的值。此处使用了单目自增运算符++,也可以编写为num=num+1,来替代num++。
程序中的num++非常重要,这条语句通过修改num的值来修改循环条件,直到num的值等于11,循环条件为假时退出循环。也就是说,循环条件中的变量,需要在循环中重新赋值,以逐渐改变循环条件的值,直到循环条件为假;否则循环将永远不会停止,这种循环称为“死循环”或者“无限循环”。
例:无限循环
程序清单 sample.c
#include <stdio.h>
int main()
{
int count=0;
while( count < 100 )
{
printf("这将没完没了,帮帮我吧!!!");
printf("试试Ctrl+C吧");
}
}
程序功能主要是演示在while循环语句中,由于缺乏改变条件的语句而导致出现无限循环的问题。
程序中while循环体内没有修改循环变量count的值,导致循环条件一直为真,造成了无限循环。
do-while循环
do-while循环与while循环的不同在于:它先执行循环体中的语句,然后再判断条件是否为真。如果为真则继续循环,如果为假,则终止循环。因此,do-while循环至少要执行一次循环语句。同样当有许多语句参加循环时,要用“{”和“}”把它们括起来。
do-while循环的一般语法是:
do{
语句;
}while(条件)
注意:在do-while语句的表达式后面必须加分号。
例【5-4】do-while循环练习
编程要求:编写一个猜数游戏,要求猜一个介于1—10之间的数字,根据用户猜测的数与标准值进行对比,并给出提示,以便下次猜测能接近标准值,直到猜中为止。
程序清单 sample.c
int main()
{
//初始化猜数的标准数值
int number = 5;
int guess = 0;
printf("猜一个介于 1 与 10 之间的数\n");
do
{
printf("请输入您猜测的数:");
scanf("%d",&guess);
if( guess > number )
printf("太大\n");
else if( guess < number )
printf("太小\n");
}while( guess != number );
printf("您猜中了:答案为 %d\n",number);
}
程序内部设置一个标准值(答案)存储到变量number中,并声明一个guess变量接收用户猜测的数值。采用do-while结构可以确保用户至少能进行一次猜数操作,在循环体内,提示用户输入要猜的数,用户输入猜测的数值后,利用if-else语句和正确答案进行判断,如果用户猜测的数值大于答案,提示用户数太大;如果用户猜测的数值小于答案,提示用户数太小。while语句后面的表达式( guess != number )用于判断循环条件是否满足,如果用户输入的数值和答案不相等,该表达式返回的结果为真,继续执行循环体,要求用户根据提示继续猜数,否则,表达式返回的结果为假,循环条件不满足,程序不再执行循环体,直接执行循环体后面的语句。
do-while语句是一种先执行循环体,然后判断条件的结构,即只有在循环体中的代码执行之后,才会判断循环条件。总的来说,循环结构在开始执行的时候,先执行循环体内的代码,然后通过while里面的条件进行判断,条件成立就继续执行循环,不成立就跳出循环,循环体内代码至少被执行一次。
嵌套循环
就像if语句可以嵌套一样,一个循环也可以嵌套在另一个循环中,一个循环中含有另一个循环就称为嵌套循环。
嵌套循环的工作原理如下:首先外循环的第一轮触发内循环,然后内循环将一直执行到完成为止,然后,外循环的第二轮再次触发内循环,此过程不断重复直到外循环结束,使用嵌套循环时,只有在内循环完全结束后,外循环才会执行下一趟循环,
一个while循环可以嵌套在另一个while循环中,示例1演示了嵌套while循环的用法。
例:while嵌套循环练习1
编程要求:用*输出一个直角三角形图案。
程序清单 sample.c
#include <stdio.h>
void main()
{
int nstars=1,stars;
//外层循环控制输出*的行数
while( nstars <= 10 )
{
stars = 1;
//内层循环控制打印星号的数量
while( stars <= nstars )
{
printf("*");
stars++;
}
printf("\n");
nstars++;
}
}
程序用外层循环控制输出*的行数,循环条件为nstars <= 10,nstars初始化为1,该条件允许输出10行*;内层循环控制*输出的数量,循环条件
为stars <= nstars,内层循环开始前,stars都被赋值为1,然后在内层循环体内做自增操作。
例:while嵌套循环练习2
编程要求:输入字符序列,统计输入的字符数。
程序清单 sample.c
#include <stdio.h>
void main()
{
int x;
char ans;
ans = 'y';
do {
x = 0;
printf("请输入字符序列:\n");
do {
scanf("%c",&ans);
x++;
}while( ans != 'q');
printf("\n输入的字符数为:%d",--x);
printf("\n是否需要输入更多字符序列(Y/N)?");
scanf("%c",&ans);
}while( ans!='N' );
}
程序首先提示用户输入字符序列,进入内层do-while循环,接收用户输入的字符序列,直到用户按下回车键并输入字符q,程序将退出内层的do-while循环。程序接着询问用户是否要输入更多的字符序列,如果用户输入y或Y,do-while外循环的条件为真,则程序将提示用户输入另一序列字符。直到用户按下除y或Y以外的任何键时,外循环才结束。
while循环和do-while循环也可以互相嵌套。例如,可以将示例1的内层while循环修改为do-while循环,或者将外层循环修改为do-while循环。
for循环
for循环语句是C语言提供的功能更强,使用更广泛的一种循环语句。C语言的for循环语句使用最为灵活,不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环条件的情况,它完全可以代替while循环。
for循环的一般语法为:
for(表达式1; 表达式2; 表达式3;)
{
语句;
}
语法说明如下:
■ 表达式1:通常用来给循环变量赋初值,一般是赋值表达式,也允许在for语句外给循环变量赋初值,此时可以省略该表达式;
■ 表达式2:通常是循环条件,一般为关系表达式或逻辑表达式;
■ 表达式3: 通常可用来修改循环变量的值,一般是赋值语句。
for循环中的这三部分必须用分号隔开,组成循环体的语句可以是单条语句或一个语句集(多条语句)。
一般语法中的“语句”即为循环体语句。for语句的语义是:
(1)首先计算表达式1的值,通常为循环变量赋初值;
(2)再计算表达式2的值,即判断循环条件是否为真,若值为真则执行循环体一次,否则跳出循环;
(3)然后再计算表达式3的值,这里通常写更新循环变量的赋值表达式,然后转回第二步重复执行。
在整个for循环过程中,表达式1只计算一次,表达式2和表达式3则可能计算多次。循环体可能执行多次,也可能一次都不执行。
例:for循环练习1
编程要求:使用for循环求数的阶乘。
程序清单 sample.c
#include <stdio.h>
void main()
{
int number,count;
int factorial = 1;
printf("请输入任意一个正整数:");
scanf("%d",&number);
for( count=1;count<=number;count++ )
{
factorial = factorial * count;
}
printf("%d的阶乘 = %d",number,factorial);
}
程序声明了3个int类型的变量,number、count、factorial。分别用于存储输入的整数、循环变量的值、阶乘值。For循环中表达式count=1为变量赋初值,表达式count<=number作为循环条件用来测试是否继续执行循环,表达式count++用来修改循环变量的值。
for语句中的三个表达式都可以是逗号表达式,逗号表达式就是通过“逗号”隔开的多个表达式组成的表达式,逗号表达式从左往右计算。
例: for循环练习2
编程要求:使用for循环输出加法表。
程序清单 sample.c
#include <stdio.h>
void main()
{
int i,j,max;
printf("请输入任意一个数值:");
printf("根据这个值可以输出以下加法表\n");
scanf("%d",&max);
for( i=0,j=max;i<=max;i++,j-- )
{
printf("\n %d + %d = %d",i,j,i+j);
}
}
程序在for循环中,表达式1为逗号表达式,该表达式为循环变量i和j赋初值,执行此表达式后,i被赋值为0,j被赋予max中的当前值;表达式3也是一个逗号表达式,每次循环后,i自加1,j自减1。
前面已讨论,for循环中有三个表达式,for循环中的这三个表达式都可以省略,但要注意分号分割符合不能省略,下面分别讨论for循环中省略部分或者全部表达式的情况。
(1)省略表达式1
for循环语句中表达式1可以省略不写,此时,循环变量应在循环语句之外赋值,例如如下语句:
int i = 0;
for( ; i < 10; i++ )
{
printf("\n %d=", i*2)
}
程序输出20以内的偶数,int i = 0对循环变量进行赋值,因为循环变量i已经被赋值,此时循环语句可以省略表达式1。
(2)省略表达式2
for循环语句中的表达式2,在一定条件下也可以省略, 表达式2主要用于循环条件的判断。如果省略表达式2,就必须要在循环体中增加循环条件判断语句,如果不满足循环条件,则跳出循环。跳出循环可以用break语句,break语句将在后面介绍。省略表达式2的示例语句如下:
int i;
for( i=0;; i++ )
{
if( i >=10 )
break;
printf("\n %d=", i*2)
}
程序在循环体内增加了if( i >= 10 )条件判断语句,如果i>=10为真,则通过break语句跳出循环,如果循环体内没有跳出循环的条件判断语句,程序将进入无限循环。
(3)省略表达式3
for循环语句中的表达式3一般是用来修改循环变量的值,如果在循环体内有修改循环变量的语句,此时表达式3可以省略。例如如下语句:
int i;
for( i=0; i<10; )
{
i = i+1;
printf("\n %d=", i*2)
}
循环体内的i = i+1等同于for( ; i < 10; i++ )语句中的i++,每循环一次,i就进行加1操作,当i自增到10时,循环终止。
(4)三个表达式都省略
三个表达式都省略的情况比较少见,此时,循环体为有循环变量的赋值语句,循环体内应有修改循环变量和循环条件判断的语句,否则很容易形成无限循环。例如如下语句:
int i=0;
for( ;; ; )
{
i = i+1;
if( i >=10 )
break;
printf("\n %d=", i*2)
}
程序中int i=0为循环变量i赋初值,循环体内i = i+1修改循环变量i的值,if( i >= 10 )判断循环变量i的值是否大于等于10,如果条件为真,则跳出循环。
for循环在C编程中应用非常广泛,它不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定而只给出循环条件的情况,它完全可以代替while循环。只要弄明白了for循环的三个表达式,就可以掌握for循环的用法,表达式1是进入第一次for循环之前运行,并且只会执行一次;表示式2是for循环的执行条件,满足这个条件后才能进入循环里面的语句;表达式3是在执行一次循环后执行的语句。
循环跳出
有时可能不知道循环将要执行的次数,终止循环的条件可在以后确定,所以需要提供一种机制在条件满足的时候跳出循环。有时候,我们需要根据条件跳过循环中的一些语句。Java语言提供了break和continue两个关键字,用于改变程序的控制流。
break语句
break语句通常用在前面介绍过的switch语句及循环语句中。当break语句用于switch语句时,可使程序跳出switch语句而执行switch语句之后的语句;当break语句用于while、do-while、for循环语句时,可使程序终止循环而执行循环后面的语句。
break语句实际上就是为了使人能方便地描述从循环执行中退出的动作。通常应把break语句放在条件语句控制之下,以便在某些条件成立时立即结束循环。
例:break语句练习
编程要求:使用break语句退出循环。
程序清单 sample.c
#include <stdio.h>
void main()
{
int i= 0;
while(i<7)
{
i++;
printf("\n 第%d次循环",i);
if(i==5)
{
printf("\n i==5 跳出循环,程序结束", i);
break;
}
}
}
该循环在变量i的值等于5时,满足条件,然后执行break语句,结束整个循环,循环语句后面没有其它语句可执行,程序退出。
continue语句
continue语句只能用在循环里。continue语句的作用是跳过循环体中剩余的语句而准备执行下一次循环。对于while和do-while循环,continue执行之后的动作是条件判断;对于for循环,随后的动作是变量更新。
注意break语句和continue语句的差别。break语句导致循环终止,使程序控制流转向这个循环语句之后;而continue引起的则是循环内部的一次控制转移,使执行控制跳到循环体的最后,相当于跳过循环体里这个语句后面的那些语句,继续下一次循环,下图说明了break语句和continue语句引起的控制转移的情况。
图 5-2 break和continue语句引起的控制转移
例:continue语句练习
编程要求:求整数1—100的累加值,但要求跳过所有个位为3的数。
提示:在循环中加一个判断,如果该数个位是3,就跳过该数不加。如何判断1到100中的那些整数的个位是3呢,还是使用取余运算符“%”,将一个正整数,除以10以后余数是3,就说明这个数的个位为3。
程序清单 sample.c
#include <stdio.h>
void main()
{
int i;
int sum = 0;
for( i =1; i<=100; i++ )
{
if( i % 10 == 3 )
{
continue;
}
sum += i;
}
printf("sum = %d",sum);
}
程序检查i除以10的余数是否等于3,如果是,则意味该数的个位数是3,这种情况下,将使用continue语句跳过后续语句,然后转向for循环的表达式3更新循环变量,继续下一次循环。
和break语句一样,continue语句通常在循环中与条件语句一起使用,用来控制循环。在循环中遇到continue语句后,就不会执行该循环中位于continue后的任何语句。continue语句用于结束当次循环,继续下一次循环。
or嵌套循环
for循环也可以嵌套,它可以和for循环结构,也可以和while循环结构混合嵌套。
嵌套循环时,必须将被嵌套的循环语句完整地包含在外层循环的循环体内,下面给出嵌套循环的示例。
例:for循环嵌套练习
编程要求:用“*”输出一个菱形图案,图案如下:
程序清单 sample.c
#include <stdio.h>
void main()
{
int i, j, k;
// 先打印上边的四行
for (i = 1; i <= 4; i++) {
// 控制要打印的空格数
for (j = 1; j <= 4 - i; j++)
printf(" ");
// 控制要打印的星号数
for (k = 1; k <= 2 * i - 1; k++)
printf("*");
printf("\n");
}
// 打印下边的三行
for (i = 1; i <= 3; i++) {
// 控制要打印的空格数
for (j = 1; j <= i; j++)
printf(" ");
// 控制要打印的星号数
for (k = 1; k <= 7 - 2 * i; k++)
printf("*");
printf("\n");
}
}
程序分为两部分循环,第一部分循环输出菱形图案的上边四行,最外层循环控制输出的行数,内层嵌套了两个for循环,第一个嵌套循环输出打印的空格数,第二个嵌套循环输出打印的星号数;第二部分循环输出菱形图案的下边三行,原理和第一部分循环相同。
例:for循环嵌套练习
编程要求:打印输出100至200之间的全部素数。
提示:素数是指能被1和它本身整除的数。算法比较简单,先将这个数被2除,如果能整除,且该数又不等于2,则该数不是素数。如果该数不能被2整除,再看是否能被3整除,并且该数不等于3,则该数不是素数,否则再判断是否能被4整除,依次类推,该数只要是能被小于其本身的某个数整除时,就不是素数。
程序清单 sample.c
#include <stdio.h>
void main()
{
int i, j, n;
n = 0;
for (i = 100; i <= 200; i++) {
j = 2;
// 从2到i之间寻找第一个能被整除的数
while (i % j != 0)
j++;
// 如果第一个能被整除的数等于该数本身,则说明该数为素数
if (i == j) {
printf("%4d", i);
n++;
// 控制每行输出8个素数
if (n % 8 == 0)
printf("\n");
}
}
printf("\n");
}
程序外层循环控制输出100至200之间的数,内层的while循环用于找寻从2到该数之间第一个能被整除的数,内层循环判断条件为i%j != 0,其中i为当前要判断是否是素数的数,j为从2开始循环递增的数,如果i%j != 0,则说明i不能被j整除,j自增后程序继续执行while循环,如果i%j == 0,则说明i能被j整除,程序跳出while循环,循环后面的if语句判断i与j是否相等,如果相等,则说明i为素数,程序输出i。