5.1
5.2
知识点提炼
for循环

for循环:更像一个计数循环,设定一个计数器,初始化,然后在一个条件下重复执行循环体,每次执行循环都以一定的步进来调整一个值,直到将这个值调整为不满足条件,且实现目标,并退出循环。
for(int i=1;i<=n;i++)
{
fact*=i;
}
printf("%d!=%d",n,fact);
其中for括号中三个语句,第一句是循环的初始动作(初始化),第二句是循环继续的条件,第三句是循环每次要做的事情。

比如在这个程序中,首先将i初始化为1,当i<=n时候执行fact自乘的那个语句以及i++。不满足时退出。
for(count=10;count>0;count--)
可以解读为:对于一个初始值为10的count变量,当count>0的时候进入循环体,循环体执行一次之后count自减1。
小套路,求和的时候i初始化应该=0,求积的时候i初始化=1。
for(;n>1;n--)
//n初始值即为n,可以写为n=n,也可以直接不写,但是分号不能省略
{
fact*=n;
}
for循环如果不需要i变量,可以省去,但是分号不能省略。
循环次数
for(i=0;i<n;i++)//考虑进入循环的时候n的值以及循环的时候n的值;循环次数
i会自增到不满足i<n为止,也就是最后的i=n,也就是i=n不会执行循环语句,直接跳出。

若写为:i=1;i<=n,循环次数仍然是n,但i初始值为1,循环结束后的值为n+1,注意i++执行的位置。
任何一个for循环都可以改写成while循环。

三种循环的什么时候使用?
for/while/do-while的使用场景

递增/两头范围明确/穷举/枚举/列出所有可能性-----for
嵌套循环--套娃编程
例子:100以内素数的判断,可以是for套for,可以是for套while等等。
一般来说,每一层循环的变量应该是不一样的,除非特殊设计。
break和continue
break:一旦读到break就会离开整个循环,还有多少轮要跑都不跑了,出去了。
continue:结束本轮循环进入语句进入下一轮。读到continue不管循环后面的语句,直接回到for循环,做“步进”。
break和continue只能对它所在的那一层循环做改变!!!!

嵌套循环的break

如果我们想要找到一种方案就行, 在printf后面加上一个break。但是这样可行吗?
运行之后结果没什么变化,这是为什么?原来是因为,break语句只退出了for(five=1...)这个循环,并且是在输出之后才退出,而程序运行到这里本来也是要退出的,于是就约等于一个无用语句了。
当某种条件下跳出所有循环?
接力break
我们的需求是得出一种结果之后就退出所有的循环。那也就是说在每一个循环结尾处都加一个break语句,但是不能是无条件的break,那么一个方案是加入一个变量让它在得出一种结果后改变状态,用这个状态来作为break的条件。
int x;
int one,two,five;
int exit=0;
scanf("%d",&x);
for(one = 1;one < x*10; one++){
for(two = 1; two < x*10/2 ; two++){
for(five=1; five<x*10/5;five++){
if(one+two*2+five == x*10){
printf("可以用%d个1角加%d个2角加%d个5角得到%d元\n",one,two,five,x);
exit=1;
break;
}
}
if(exit) break;
}
if(exit) break; //由于1为真,0为假,if括号里的值为1时它就会执行语句。
}
goto语句
goto后面加上out这个标志(可以自定义),执行这句会直接跳到out:这个语句的位置。
因此goto语句更加适合跳出多重循环
int one,two,five;
int x;
scanf("%d",&x);
for(one = 1;one < x*10; one++){
for(two = 1; two < x*10/2 ; two++){
for(five=1; five<x*10/5;five++){
if(one+two*2+five == x*10){
printf("可以用%d个1角加%d个2角加%d个5角得到%d元\n",one,two,five,x);
exit=1;
goto out;
}
}
}
}
out:
套路:每n个数1行
要有一个变量cnt,计数
if(count%5==0){
printf("\n");}
//这个语句可以每隔5个数字就换一行
要让数字列表对齐输出的话,printf("%d\t"); // \t等于一个制表符,相当于按tab键
解难题思路
由于还没有复习到for循环就先做了题,觉得很难,这里总结以下做比较难的编程题的思路:
从问题到程序
变量
有什么样的数据——控制台输入?函数产生?随机?
运算过程中会产生什么数据,结果——输出?计算?
作为计算我们还需要什么样的数据来辅助
项目学习记录
0213阶乘
int n;
scanf("%d",&n);
int fact=1;
//fact为结果
for(int i=1;i<=n;i++)
{
fact*=i;
}
printf("%d!=%d",n,fact);

这种初始化申明只能在C99模式下面用,需要加上特殊的选项【-std=C99】,编译器接受程度不同。devc++怎么加呢?
0213素数的判断
int i;
scanf("%d",&x);
for(i=2;i<x;i++)
{
if(x%i==0)
{
printf("不是素数");
}
}
那么如果我给一个有多个公因数的数进去,比如6,6可以被2和3整除,所以程序会输出两遍“不是素数”,而且没有办法输出“是素数”。
所以我们对代码进行优化,增加一个判断变量

0213 100以内的素数
int x;
for(x=2;x<=100;x++)
{
int i;
int isprime=1;
for(i=2;i<x;i++){
if(x%i==0){
isprime=0;
break;}
}
if(isprime==1){
printf("%d",x);
}
}
return 0;
穷举1-100:
for(x=2;x<=100;x++)//输出2-100
for(x=1;x<=100;x++)//输出1-100
for(x=1;x<100;x++)//输出1-99
0213 前50个素数
int x;
int count=0;
for(x=2;count<50;x++)
{
int i;
int isprime=1;
for(i=2;i<x;i++){
if(x%i==0){
isprime=0;
break;}
}
if(isprime==1){
printf("%d\t",x);
count++;
// \t等于一个制表符,相当于按tab键
if(count%5==0){
printf("\n");}
//这个语句可以每隔5个数字就换一行
}
}
return 0;
0213凑10块以下的整块

int x;
int one,two,five;
int exit=0;
scanf("%d",&x);
for(one = 1;one < x*10; one++){
for(two = 1; two < x*10/2 ; two++){
for(five=1; five<x*10/5;five++){
if(one+two*2+five == x*10){
printf("可以用%d个1角加%d个2角加%d个5角得到%d元\n",one,two,five,x);
exit=1;
break;
}
}
if(exit) break;
}
if(exit) break; //由于1为真,0为假,if括号里的值为1时它就会执行语句。
}