赞
踩
目录
while循环和if选择语句很像,都是在条件表达式为真的时候才执行复合语句中的代码。不同的是if语句只执行一遍,while循环可以根据需要指定循环次数。分为两种:
我们经过while循环语句的学习,可以认识到循环控制语句实际上有三个重要表达式:
见下面例子。
实际上,我们可以将这三个表达式换一种写法,这时候就可以用for循环语句,for循环语句和while循环语句是无条件等价:
for循环语句格式为: for(表达式1; 表达式2; 表达式3) { 循环体; } //注意是表达式之间用分号,不是逗号。再要注意 for(){} 后面不加分号
for循环和while循环的流程图:
for循环的几个变体:见怪不怪
形式一(和while循环语句完全相同):表达式1挪到外面去,表达式3挪到循环体中去,表达式2不挪动。
注意:记得分号保留。
形式二(死循环):没有表达式2,也就是没有判断条件
形式三(瞎搞):直接将定义语句写在表达式1中。
注意:C99支持这种写法,Java和C++中也是这种写法。
形式四(空循环体):把表达式3写成逗号表达式。
注意:这种情况for语句后要加分号,表示循环体为空,这是因为不加分号,会默认下一条语句是循环体。
形式五(for循环的双循环变量法减少循环次数):把表达式1写成逗号表达式,写入两个循环变量 head 和 tail 。我们可以看习题11(习题9的改良),体会该用法。
注:用while循环当然也可以。
原本我们是通过循环的条件表达式来判断是否进入或者跳出循环,而break的作用就是当循环变量没有到达临界值时,可以提前结束循环。break被放置在循环体中,通常结合选择控制语句来使用。
例题:我们通过 习题16(捐款)、习题17(判断素数),来巩固该知识点。
在本次循环中,continue用来跳过它后面的循环语句。continue被放在循环体中,通常也是结合选择控制语句来使用的。如果continue后面没有代码了,那么也起不到什么作用。
例题:我们通过 习题18,来巩固该知识点。
我们很容易想明白,第一点:循环嵌套肯定是要用到多个循环变量,但他的用法不同于我们双循环变量法减少循环次数中的那样;第二点:外层的循环肯定是要等内层的循环完成了,才会继续下去,可见循环的次数是相乘的关系。
打个比方:我们在方格纸上写字,我们是不是要从上往下,从左往右写?那么,我们可以进行类比:写字就是一个两层的循环嵌套。当我们换行书写时,就相当于外层循环,行数是外层循环变量;当我们书写某一行时,就相当于内层循环,列数是内层循环变量。
循环嵌套可以做什么?我们看以下习题来巩固该知识点:
1、代码心得
习题9:计算级数 12+22+32+ ··· ··· 的前10项和。
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int times = 1; //既作为循环变量,又作为求和变量
- int sum = 0; //和,这里一定要初始化
- while (times <= 10)
- {
- sum = sum + times*times;
- times++;
- }
- printf("1^2+2^2+...+10^2的值为: %d\n", sum);
- return 0;
- }
习题11:计算级数 12+22+32+ ··· ··· 的前terms项和,这里terms要求用户输入。
- 1. 输入简单级数的求和项数
- 2. 双循环变量法,head <= tail 时进入循环
- 2.1 从级数首、尾同时求和
- 2.2 改变两个循环变量
- 3. 判断i和j是否差2(因为项数存在奇偶,若是奇数项,循环结束后i比j大2,偶数项则没问题)
- 3.1 如果是
- 那么,循环求和结果减去重复项
- 4. 显示求和结果
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int terms; //级数求和项数
- int sum = 0;
- int head, tail; //双循环变量
- puts("确认你想求和的项数");
- scanf("%d", &terms);
- for ( head = 1, tail = terms; head <= tail; head++, tail--)
- {
- sum += head*head + tail*tail;
- }
- if (head - tail == 2)
- {
- sum -= (head-1)*(head-1);
- }
- printf("1^2+2^2+...+%d^2的值为: %d\n", terms, sum);
- return 0;
- }
习题12:计算交错级数: 的前10项和:
- 1. while循环,在i <= 10的时候进入循环
- 1.1 改变循环变量term的值(此时term是级数的第i项的绝对值)
- 2.2 求和
- 2.3 改变循环变量flag的值(此时flag是级数的第i项前的符号)
- 2.4 改变循环变量i
- 2. 打印结果
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int i = 1; //循环变量,仅用于控制循环次数
- double term = 1; //代表某一项的循环变量
- double sum = 0;
- double flag = 1; //表示符号的循环变量
- while (i <= 10)
- {
- term = 1.0/(2*i-1);
- sum += flag*term;
- printf("%lf\n", term); //小技巧,相当于断点调试功能
- flag = -flag;
- i++;
- }
- printf("sum = %lf\n", sum);
- return 0;
- }
习题13:输入两个整数,用辗转相除法求解它们的最大公因数,最小公倍数
- 1. 输入两个整数,分别保存在dividend(被除数)和divisor(除数)中
- 2. 保存两个整数的乘积
- 3. 判断除数是否大于被除数
- 3.1 如果是
- 那么,交换它们,保证被除数大于除数
- 4. 取出这两个数的余数,记为rem
- 5. while循环,当rem不为0时进入循环
- 5.1 改变循环变量dividend,上一次除数作为下一次的被除数
- 5.2 改变循环变量divisor,上一次余数作为下一次的除数
- 5.3 改变循环变量rem
- 6. rem为0,循环结束,此时的除数就是最大公因数,输入的两个数的乘积除以这个最大公因数就是最小公倍数
- 7. 打印输入的两个数的最大公因数和最小公倍数
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int dividend; //被除数,作为循环变量
- int divisor; //除数,作为循环变量
- int rem; //余数,作为循环变量
- int dataSmall; //临时变量, 保证被除数比除数大
- int product; //被除数和除数的乘积
- puts("请输入两个数");
- scanf("%d %d", ÷nd, &divisor);
- product = dividend * divisor;
- if (divisor > dividend)
- {
- dataSmall = dividend;
- dividend = divisor;
- divisor = dataSmall;
- }
- rem = dividend % divisor;
- while (rem != 0)
- {
- dividend = divisor;
- divisor = rem;
- rem = dividend % divisor;
- }
- printf("这两个数的最大公因数为%d\n", divisor);
- printf("这两个数的最小公倍数为%d\n", product / divisor);
- return 0;
- }
习题14:将一个正整数每位加5,若相加超过9,则保留个位,最后逆序输出,比如输入2645后,输出0917。
- 1. 输入正整数x
- 2. while循环,在x不等于0时进入循环
- 2.1 取出x的最后一位,加5,再取个位
- 2.2 打印刚才得到的数
- 2.3 改变循环变量x,舍弃掉x的最后一位
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int x; //输入的数,作为循环变量
- int y; //每一位转化后的数
- printf("请输入一个正整数:");
- scanf("%d", &x);
- while (x != 0)
- {
- y = ((x % 10) + 5) % 10;
- printf("%d", y);
- x = x / 10;
- }
- return 0;
- }
习题15:列出0~999中所有的水仙花数,若一个正整数等于其各位数字的立方和,那么这个数称为水仙花数。
- 1. for循环, 让i从0遍历到999
- 1.1 获取i的个位
- 1.2 获取i的十位
- 1.3 获取i的百位
- 1.4 判断是否是水仙花数
- 1.4.1 如果是
- 那么,打印出来
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int i; // 0~999的数
- int a, b, c; //分别存储i的个位、十位、白位
- for (i = 0; i <= 999; i++)
- {
- a = i % 10; // 个位
- b = i / 10 % 10; // 十位
- c = i / 100; // 百位
- if (i == a * a * a + b * b * b + c * c * c)
- printf("%d是个水仙花数\n", i);
- }
- return 0;
- }
习题16:不限次数捐款,但是当捐款总数超过10万元后,不再接受捐赠,最后统计捐款总额、人数。
- 1. for循环,循环变量是捐赠人数(从1开始),可以缺少表达式2(死循环)
- 1.1 输入本次捐赠数目
- 1.2 计入捐款总额之中
- 1.3 判断总额是否大于10万元
- 1.3.1 如果是,
- 退出循环
- 2. 打印当前捐款总额和捐款人数
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int numOfPeople;
- float totalMoney = 0;
- float donations;
- for ( numOfPeople = 1; ;numOfPeople++)
- {
- puts("请输入捐款的数目");
- scanf("%f", &donations);
- totalMoney = totalMoney + donations;
- if (totalMoney >= 100000)
- {
- break;
- }
- }
- printf("累计捐款%.2f元,超过10万元,不再接受捐款\n", totalMoney);
- printf("总捐款人数是:%d\n", numOfPeople);
- return 0;
- }
习题17:输入一个正整数,判断它是否是素数,若一个数只能被1和其自身整除,那么这个数就是素数,否则为合数。
- 1. 输入一个正整数ddata
- 2. for循环遍历,循环变量divisor从2开始,小于等于ddata的算术平方根时进入循环
- 2.1 判断这个正整数是否能整除divisor
- 2.1.1 如果能,
- 那么,它不是质数,令质数标志=0
- break,退出循环
- 3. 判断质数标志是否为1
- 3.1 如果是,
- 那么,该数是质数
- 3.2 否则,
- 那么,该数是合数
- #include <stdio.h>
- #include <math.h>
- int main(int argc, char const *argv[])
- {
- int ddata; //输入的整数
- int divisor; //被除数,作为循环变量
- int primeYesOrNot = 1; //先默认是质数
- printf("请输入一个整数:\n");
- scanf("%d", &ddata);
- for (divisor = 2; divisor <= sqrt(ddata); divisor++){
- if (ddata % divisor == 0)
- {
- primeYesOrNot = 0;
- break;
- }
- }
- if (primeYesOrNot == 1){
- printf("%d是质数\n", ddata);
- }else{
- printf("%d是合数\n", ddata);
- }
- return 0;
- }
习题18:统计10个非零的输入值的和。也就是当输入的值是0时,要求这次重新输入,最后计算这些值的和。
- 1. while循环,10次
- 1.1 输入整数
- 1.2 判断输入的整数是否是0
- 1.2.1 如果是
- 那么,要求用户重新输入
- continue,回到循环开头,不执行1.3和1.4
- 1.3 求和
- 1.4 改变循环变量
- 2. 打印输入数的和
代码:
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int times = 0; //循环变量
- int m; //键盘输入的值
- int sum; //求和
- while (times < 10)
- {
- printf("请输入第%d个非零整数\n", times+1);
- scanf("%d", &m);
- if (m == 0)
- {
- puts("请重新输入");
- continue;
- }
- sum += m;
- times++;
- }
- printf("结果是%d\n", sum);
- return 0;
- }
习题19:输出下三角矩阵“99乘法表”。
- 1. for循环,当行号i<=9时,进入循环
- 1.1 for循环,当列号j<=行号i时,进入循环
- 1.1.1 打印i*j的大小
- 1.2 打印完一行后换行
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int i; //行
- int j; //列
- for(i = 1; i <= 9; i++){
- for(j = 1; j <= i; j++){
- printf("%d*%d=%-2d ",i, j, i*j);
- }
- putchar('\n');
- }
- return 0;
- }
习题20(百元买鸡问题):用100元去买100只鸡,假设母鸡3元/只,公鸡2元/只,小鸡0.5元/只,请问有几种购买方案?
- 1. for循环,当公鸡数x <=33时,进入循环
- 1.1 for循环,当母鸡数y <=50时,进入循环
- 1.1.1 用x、y这两个主变量确定小鸡数z这个自由变量(方程一)
- 1.1.2 判断x、y、z是否满足方程二
- 1.1.2.1 如果满足,
- 那么,显示公鸡、母鸡、小鸡分别有多少个
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int x, y, z;
- for (x = 0; x <= 33; x++){
- for (y = 0; y <= 50; y++){
- z = 100 - x - y;
- if (3*x+2*y+0.5*z == 100){
- printf("公鸡%d只,母鸡%d只,小鸡%d只\n", \
- x, y, z);
- }
- }
- }
- return 0;
- }
习题21(考试排考问题):高校期末有英语、计算机、高等数学这三门考试,排考要求如下:①周一到周五考试;②每天最多一门考试;③高数考试时间这三门里最早;④计算机不能在周四考;
- 1. for循环,循环变量math从1开始,<=3时进入循环
- 1.1 for循环,循环变量english从math+1开始,<=5时进入循环
- 1.1.1 for循环,循环变量computer从math+1开始,<=5时进入循环
- 1.1.1.1 判断计算机和英语是否不在一天,并且计算机不在周四
- 1.1.1.1.1 如果是,
- 那么,打印方案情况
- 让count自加1,用于保存方案个数
- 2. 打印一共有几种方案
- #include <stdio.h>
- int main(int argc, char const *argv[])
- {
- int math, english, computer;
- int count = 0; //排考方案数
- for (math = 1; math <= 3; math++){
- for (english = math + 1; english <= 5; english++){
- for (computer = math + 1; computer <= 5; computer++){
- if (computer != english && computer != 4){
- count++;
- printf("周%d考高数,周%d考英语,周%d考计算机\n", math, english, computer);
- }
- }
- }
- }
- printf("总共有%d种排考方案\n", count);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。