for (表达式1;表达式2;表达式3)
语句 //反复执行部分,即循环体。循环体只能是单条语句,如果需要执行多条语句需要用{}括起来
E.g:
for (i=1; i<=3; i++) //三个表达式以分号隔开的,而不是逗号
printf("%d",i); //循环体
/*输出结果为123*/
for 语句执行流程
- 首先执行表达式1;
- 然后判断表达式2的值是真(非0)还是假(0);
- 若为真,则执行一次循环体,在执行表达式3,然后转向第2步;
- 若为假,则结束循环,转向循环体之后的语句执行。
- 表达式1一般用于给循环变量赋初值; //给i赋值为1
- 表达式2则是循环的条件; //判断是否满足循环条件,当i<=3时进入循环体
- 表达式3一般用于递变循环变量的值。 //当一个循环体执行结束后i++
一般而言,如果“循环变量赋初值、循环条件、循环变量递变“三部分不复杂,可使用for循环。反之,则使用while循环,更加明了直观。
相互平行的循环例子:
#include
int main()
{
int i;
for (i=1; i<=5; i++) //两个循环平行,先做第一个循环
printf("%d", i*i);
for (i=1; i<=6; i++) //再做第二个循环,且平行循环的循环变量名允许同名
printf("%d", i*i*i);
return 0;
/*输出结果为1491625(第一个循环)182764125216(第二个循环)*/
}
素数的判断
素数的定义
- 只能被1和自己整除的数,不包括1
初始代码如下,输入某一个值:
#include
int main()
{
int x;
scanf("%d", &x);
return 0;
}
为了判断是否为素数,我们要看这个数是否能被2、3、4…(x-1)整除,因此引入一个循环变量i
接着考虑使用什么循环语句,由于变量i有明显的递增,因此使用for循环,更加简洁明了。
#include
int main()
{
int x;
scanf("%d", &x);
int i;
for (i=2; i
该算法可继续被优化。
- 添加一个新的量isPrime,来判断是否是素数。
- 在循环体中添加一个break语句跳出循环。
- 添加一个if语句,判断isPrime的值,以输出结果。
#include
int main()
{
int x;
int isPrime = 1; //添加新变量,证伪,初始值设置为1(true)
scanf("%d", &x);
int i;
for (i=2; i
注意:==是判断是否相等,而=是赋值!!!!
break 与 continue以唱歌为例子:
B.g:一群同学按照学号轮流站起来唱歌。
- continue:第一个同学起来唱歌,唱得好听,唱完坐下(执行了一次循环体);第二个同学站起来唱歌,唱的不是很好听,中途打断,直接让他坐下让第三个同学起来唱歌(第二次循环体执行中断,直接跳转第三个)。
- break:第一个同学起来唱歌,唱得好听,唱完坐下(执行了一次循环体);第二个同学站起来唱歌,唱的让人无法忍受,打断,老师走出房间,停止本节音乐课。(第二次循环体结束,同时也跳出整个循环,不再执行循环体语句)。
在上一个输入判断是否为素数的程序中做些许修改。
#include
int main()
{
int x;
for (x=2; x<=100; x++){
int isPrime = 1; //请注意!isPrime要在循环体内定义!因为每给出一个新的数x,就要让它默认是素数做判断
int i;
for (i=2; i
输出结果: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,
使用了嵌套的循环。
输出前50个素数。(若使用for循环,不合适,for循环用于次数是确值,或范围是确值)
#include
int main()
{
int x;
int cnt = 0;
while (cnt < 50) { //用while循环
int isPrime = 1; //请注意!isPrime要在循环体内定义!因为每给出一个新的数x,就要让它默认是素数做判断
int i;
for (i=2; i
凑硬币
如何用1角、2角和5角的硬币凑出10元以下的金额呢?
思路:使用枚举法,用3个循环。
#include
int main()
{
int x;
int one, two, five; //引入变量代表1角、2角、5角的个数
scanf("%d", &x);
for (one=0; one<=x*10; one++){ //第一层循环,先固定1角的个数
for (two=0; two*2<=x*10; two++){ //第二层循环,固定2角的个数
for (five=0; five*5<=x*10; five++){ //第三层循环,确定5角的个数,1、2角确定的情况下,将5角符合条件的枚举完
if(one+two*2+five*5==x*10){ //判断加起来是否与x相等
printf("可以用%d个1角,%d个2角,%d个五角凑成%d元。\n",one, two, five, x); //输出结果
}
}
}
}
return 0;
}
(初次看到本题感觉脑袋都大了,如何捋清思路,如何选择语句很重要,使用计算机不怕重复和列举的特性,可以让它把所有的情况都列举出来,从中选择符合条件的结果。)
继续优化:如果想让这个程序找出一个合适的答案就停止。则需要使用break语句/goto语句。
如果添加了一句break
#include
int main()
{
int x;
int one, two, five; //引入变量代表1角、2角、5角的个数
scanf("%d", &x);
for (one=0; one<=x*10; one++){ //第一层循环,先固定1角的个数
for (two=0; two*2<=x*10; two++){ //第二层循环,固定2角的个数
for (five=0; five*5<=x*10; five++){ //第三层循环,确定5角的个数,1、2角确定的情况下,将5角符合条件的枚举完
if(one+two*2+five*5==x*10){ //判断加起来是否与x相等
printf("可以用%d个1角,%d个2角,%d个五角凑成%d元。\n",one, two, five, x); //输出结果
break; //break只能跳出当前它所在的这层循环
}
}
}
}
return 0;
}
发现仍然输出多个答案,经过调试,我们发现break只能跳出当前它所在的那层循环。
但如果在每个循环体都加了1个break,我们发现无论内层循环以什么方式跳出,都会跳出下一层循环,不符合需求。
这时候我们引入一个变量exit,使用if语句来实现跳出功能。称为接力break。
#include
int main()
{
int x;
int one, two, five; //引入变量代表1角、2角、5角的个数
int exit = 0; //引入一个跳出循环的变量
scanf("%d", &x);
for (one=0; one<=x*10; one++){ //第一层循环,先固定1角的个数
for (two=0; two*2<=x*10; two++){ //第二层循环,固定2角的个数
for (five=0; five*5<=x*10; five++){ //第三层循环,确定5角的个数,1、2角确定的情况下,将5角符合条件的枚举完
if(one+two*2+five*5==x*10){ //判断加起来是否与x相等
printf("可以用%d个1角,%d个2角,%d个五角凑成%d元。\n",one, two, five, x); //输出结果
exit = 1; //找出答案,将1赋值给exit
break; //break跳出当前它所在的这层循环
}
}
if (exit = 1) break; //使用if循环和exit,实现接力break
}
if (exit = 1) break;
}
return 0;
}
goto
语法:
goto 标号;
标号:
#include
int main()
{
int x;
int one, two, five; //引入变量代表1角、2角、5角的个数
scanf("%d", &x);
for (one=0; one<=x*10; one++){ //第一层循环,先固定1角的个数
for (two=0; two*2<=x*10; two++){ //第二层循环,固定2角的个数
for (five=0; five*5<=x*10; five++){ //第三层循环,确定5角的个数,1、2角确定的情况下,将5角符合条件的枚举完
if(one+two*2+five*5==x*10){ //判断加起来是否与x相等
printf("可以用%d个1角,%d个2角,%d个五角凑成%d元。\n",one, two, five, x); //输出结果
goto out; //goto跳转到out
}
}
}
}
out: //直接跳出多重循环,来到结束
return 0;
}
循环应用
前n项求和
思路不难,但是要注意细节
#include
int main()
{
int n;
int i;
double sum = 0;
scanf("%d", &n);
for(i=1; i<=n; i++){
sum += sum + 1.0/i;
}
printf("f(%d)=%d", n, sum);
return 0;
}
题目修改一下:
#include
int main()
{
int n;
int i;
double sum = 0;
double sign = 1.0; //引入一个浮点数sign
scanf("%d", &n);
for(i=1; i<=n; i++){
sum += sum + sign/i;
sign = -sign; //sign符号反转
}
printf("f(%d)=%d", n, sum);
return 0;
}
正序分解整数
需求:
#include
int main()
{
int number;
int n; //number的替身,用于算出几位数
int mask = 1; //取最高位
int d; //商
scanf("%d", &number);
n = number;
while ( n>9 ){ //翁恺老师的思路真的牛,让mask记录输入的数是几位,同时为接下来除和取余做准备
n=n/10;
mask *= 10;
}
// printf("%d, %d\n", m, mask);
// 这一步可以输出mask的值判断一下是否正确
while (mask > 0) {
d = number/mask;
number = number%mask;
if (mask == 1) {
printf("%d",d);
} else {
printf("%d ",d);
}
mask /= 10;
}
return 0;
}
翁恺老师的思路真的太绝了!
可以归纳出几个写程序的tips- 写程序可以先把思路以注释的形式写下来
- 先搭建一个框架,再逐步求精
- 可以在循环后面加printf输出,看循环是如何实现的
- 联系相似题目,运用已有的经验,比如输出逆序整数的题中,取出每一位对应的数,可以用整除/和取余%
- 写完程序后,要测试几个极值,特殊值来确定是否考虑周全
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)