一、循环嵌套
循环的嵌套,就是在一个循环的循环体中,又包含了另外的循环结构,也称为多重循环。
在多重循环中,最常用的是双重循环。
例1.双重循环示例。
#include <stdio.h>
int main()
{
int i,j;
for(i=0;i<2;i++)
//外循环
//在下面的括号里面的就是外循环的内容
{
for(j=0;j<3;j++)
printf("%d,%d\n",i,j);
printf("*****\n");
/*这条五个星号的在内内循环外面
在外循环里面
因为循环后面跟的是单条语句
所以有人就会在每个循环后面都加{}来表示区分
即便只有一条语句*/
}
return 0;
}
首先将外循环的循环体看作一个整体,然后将外循环展开(就是写写它能够运行几次跟跳出条件啊啥的)。
然后,依次执行内循环。
二、打印九九乘法表
直接打印自然很难啊
所以想办法拆分
拆着拆着就简单了
编程思路:
首先,只考虑1个等式(比如“19=9”)的打印。
最简单的方法,就是将这个等式,直接作为字符串常量打印。
printf("19=9\n");
这种方式相当于一种半人工方式,不能体现程序控制的优势。
为了体现程序控制的思想,定义两个整型变量,代表等式所处的行号、列号。用行号列号控制程序运行。
打印一个等式“1*9=9”的程序:
#include <stdio.h>
int main()
{
int i,j;
i=9; //行号
j=1; //列号
printf("%d*%d=%d\n",j,i,i*j);
return 0;
}
要打印整个第9行的9个等式,只需要让行号i=9保持不变,然后让列号j从1递增到9,并循环执行打印一个等式的printf语句即可。
打印乘法表一行的源程序:
#include <stdio.h>
int main()
{
int j,i=9;
for(j=1;j<=9;j++)
printf("%d*%d=%d\t",j,i,i*j);
//\t就是转义字符
//代表水平制表符、
//简单点就是tab键
//就为了等式之间能够有间隔
//看起来条理一些
printf("\n");
//换行
return 0;
}
在上面的程序中,变量i的值固定为9,因此只能打印第9行。
要打印所有的9行等式,只需让行号i从1递增到9,并循环执行打印一行的程序段即可。
#include <stdio.h>
int main()
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=9;j++)
printf( "%d*%d=%d\t",j,i,i*j);
printf("\n");
}
return 0;
}
//语句printf("\n");
必须位于外循环体之内
内循环体之外。
效果图
等式的行数,是由外循环的循环次数控制的。
每行中等式的个数,是由内循环的循环次数控制的。
内循环就是j那个循环
可以看到j就是9次
不管有几行(那是外循环的事情)
每行都有9个等式(这室内循环规定的)
这是改成五以后的效果图
要让各行的等式个数随行号而变化,只需让内循环的循环次数,跟随外循环变量的值而变化即可。
决定一个循环的循环次数的因素,是它的初值、终值和步长。
通常的实现方法,是将内循环变量的终值(或初值),设置为包含外循环变量的表达式。
只需要将内循环变量j的终值
设置为与外循环变量i的值相等即可。
for(i=1;i<=9;i++ )
{
for(j=1;j<=i;j++)
printf("%d*%d=%d\t",i,j,i*j);
printf("\n");
这样,内循环的循环次数将变成i次,从而使得第i行输出i个等式。
修正之后的源程序:
#include <stdio.h>
int main()
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
printf("%d*%d=%d\t",j,i,i*j);
printf("\n");
}
return 0;
}
99乘法表的源代码其实并不长
总结:如果要编写双重循环结构的程序,可以先构造出内循环部分。以整个内循环部分作为循环体,加上外层循环语句,形成嵌套结构即可。
三、break语句的使用
break语句只能用于switch语句内部,或者循环体内部。
用于循环体内部时,其功能是从本层的循环体中跳出来,从而提前结束循环。
#include <stdio.h>
int main()
{
int i;
for(i=1;i<=5;i++)
{
if(i>=3)
break;
//这里就是i=3的时候跳出循环
printf( "%d,",i);
return 0;
}
break一般结合if语句执行,就是由if语句提供一个判断条件,决定是否执行break语句。
四、continue语句的使用
continue;
只能用于循环体内部,其功能是跳过continue之后的部分循环体,而继续进行下一次循环。
#include <stdio.h>
int main()
{
int i;
for(i=1;i<=5;i++)
{
if(i<=2)
continue;
//就是如果if表达式的值为真
//那么后面的printf("%d,",i);就不执行了
//就跳过了
//等到if语句为假的时候
//就可以跳过continue;了
printf("%d,",i);
}
return 0;
}
对于for循环,执行continue将转向表达式3(一般就是i++这一类)执行,然后转向循环条件的判断(表达式2,就是i<=5这种)
而对于while循环和do-while循环,执行continue将直接转向循环条件的判断。(因为他的i++通常在循环体里面如果排序的时候continue在i++之前,i++就会被跳过)
while(i<10)
{
printf("%d",i)
continue;
i++
}
五、while(1)循环
while(1)循环的循环条件永远为真
对循环条件进行判断的时机,是至关重要的。
一方面,要保证先给循环变量赋值、后判断循环条件;
另一方面,要保证先判断循环条件、后进行相应处理。
例:从键盘输入若干名学生某一门课程的成绩,然后求出他们的平均成绩。要求以任意负数作为输入结束标记。
编程思路:
要想求平均成绩,必须先求出这些成绩的总和。由于没有明确给出学生的人数,因此可以采用输入结束标记控制循环。
算法设计:
输入一个学生的成绩。如果是结束标记,那么就结束循环;否则,累加到总成绩中,并统计当前学生的人数,然后转向第1步。最后求出平均成绩并输出。
#include<stdio.h>
int main()
{
float g,sum=0,ave;
//sum=0注意
int n=0;
printf("请输入若干个成绩,以任意负数退出:\n");
while(g>=0)
{
scanf("%f",&g);
sum=sum+g;
n++;
}
ave=sum/n;
printf("平均成绩=%.2f\n",ave);
return 0;
}
这样是不对的
while(g>=0)
{
scanf("%f",&g);
sum=sum+g;
n++;
}
很明显while所判断的g一开始并没有被赋值
而且如果输入负数也是先执行循环体
也就是先加到sum中
在进行判断
不合适
所以用do-while
#include <stdio.h>
int main()
{
float g,sum=0, ave;
int n=0;
printf("请输入若干个成绩,以任意负数退出:\n");
{
scanf("%f",&g);
sum=sum+g ;
n++ ;
}
while(g>=0);
ave=sum/n;
printf("平均成绩=%.2f\n" ,ave);
return 0;
}
but
结束标记也是可以被加进去
因为在循环体里面
综上
用while(1)
直接用1作为循环的条件,即循环条件永远为真,从而成为无限循环。
可以通过有条件的break语句,选择适当的时机跳出循环。
#include<stdio.h>
int main()
{
float g,sum=0ave;
int n=0;
printf("请输入若干个成绩,以任意负数退出:\n");
while(1)
{
scanf("%f",&g);
if(g<0)
break;
sum=sum+g;
n++;
}
//这里break的位置美挺有意思的
ave=sum/n;
printf("平均成绩=%f\n" ,ave);
return 0;
}