循环控制
循环控制:
素数:只能被1和本身整除的数,1不是素数
判断一个数是不是素数:
#include<stdio.h>
int main()
{
int x;
scanf("%d", &x);
int i;
int isPrime=1;
for(i=2;i<x;i++){
if(x%i==0){
isPrime=0;
break;
}
printf("%d", i); //break跳出循环,不会输出i
}
if(isPrime==1){
printf("是素数\n");
}else{
printf("不是素数\n");
}
return 0;
}
break和continue:
break是跳出循环,循环内break后面的语句不会再执行,并且不继续下一轮循环
continue是跳过循环内continue后面的语句,不执行循环内continue后面的语句,跳到下一轮循环
#include<stdio.h>
int main()
{
int x=12;
int i;
int isPrime=1;
for(i=2;i<x;i++){
if(x%i==0){
isPrime=0;
continue;
}
printf("%d ", i);
}
if(isPrime==1){
printf("是素数\n");
}else{
printf("不是素数\n");
}
return 0;
}
有continue,当x%10!==0时,才会输出i
多重循环
嵌套的循环:
如何写程序输出100以内的素数?
#include<stdio.h>
int main()
{
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;
}
嵌套的循环:循环里面还是循环
里面的循环和外面的循环,循环变量不一样
输出前50个素数:
#include<stdio.h>
int main()
{
int x;
int cnt=0;
for(x=2;cnt<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 ", x);
cnt++;
}
}
printf("\n");
return 0;
}
离开多重循环:
凑硬币:
如何用1角、2角和5角的硬币凑出10元以下的金额?
#include<stdio.h>
int main()
{
int x; //10元以下的金额
int one, two, five; // 1角、2角、5角的张数
scanf("%d", &x);
for(one=0;one<x*10;one++)
{
for(two=0;two<x*10/2;two++)
{
for(five=0;five<x*10/5;five++)
{
if(one+two*2+five*5==x*10)
{
printf("可以用%d张1角加%d张2角加%d张5角凑出%d元\n", one, two, five, x);
}
}
}
}
return 0;
}
break和continue只对它所在的那层循环起作用
如何在找到一种搭配方案后,使跳出循环,不输出所有方案:
1.接力break
2.
goto out;
...
out:
1.接力break:
#include<stdio.h>
int main()
{
int x; //10元以下的金额
int one, two, five; // 1角、2角、5角的张数
scanf("%d", &x);
int exit=0;
for(one=0;one<x*10;one++)
{
for(two=0;two<x*10/2;two++)
{
for(five=0;five<x*10/5;five++)
{
if(one+two*2+five*5==x*10)
{
printf("可以用%d张1角加%d张2角加%d张5角凑出%d元\n", one, two, five, x);
exit=1;
break;
}
}
if(exit)break; // if(exit) 就等于if(exit==1)
}
if(exit)break;
}
return 0;
}
2. goto out ... out
#include<stdio.h>
int main()
{
int x; //10元以下的金额
int one, two, five; // 1角、2角、5角的张数
scanf("%d", &x);
int exit=0;
for(one=0;one<x*10;one++)
{
for(two=0;two<x*10/2;two++)
{
for(five=0;five<x*10/5;five++)
{
if(one+two*2+five*5==x*10)
{
printf("可以用%d张1角加%d张2角加%d张5角凑出%d元\n", one, two, five, x);
exit=1;
goto out;
}
}
}
}
out: //注意是:不是; out是跳出循环后直接到达的位置
return 0;
}
为什么说goto的名声不好?
goto语句跳转的位置没有限制,可以随意跳转(当然不能跳转到其它函数内),违背了单一入口单一出口的结构化原则
循环应用:
写一个程序计算 f(n)=1+1/2+1/3+1/4+...+1/n
#include<stdio.h>
int main()
{
double sum = 0.0; //注意是sum有小数,所以要用double
int n;
scanf("%d", &n);
for ( int i=1; i<=n; i++ ) {
sum += 1.0/i; // 如果是1/i,那么"/"两边都是整数,得到的结果也是整数,1/10得到的结果会是0,所以用1.0把i和运算结果也变成浮点数
}
printf("f(%d)=%f\n", n,sum);
return 0;
}
写一个程序计算f(n)=1-1/2+1/3-1/4+...+1/n
#include<stdio.h>
int main()
{
double sum = 0.0;
int n;
int sign=1;
scanf("%d", &n);
for ( int i=1; i<=n; i++ ) {
sum += sign*1.0/i;
sign=-sign;
}
printf("f(%d)=%f\n", n,sum);
return 0;
}
或者利用sign将结果变为浮点数:
#include<stdio.h>
int main()
{
double sum = 0.0;
int n;
double sign=1.0;
scanf("%d", &n);
for ( int i=1; i<=n; i++ ) {
sum += sign/i;
sign=-sign;
}
printf("f(%d)=%f\n", n,sum);
return 0;
}
最大公约数:
输入两个数a和b,输出他们的最大公约数。
输入:12 18
输出:6
/*辗转相除法:
如果b等于0,计算结束,a就是最大公约数;
否则,计算a除以b的余数,让a等于b,而b等于那个余数;
回到第一步。
a b t
12 18 12
18 12 6
12 6 0
6 0
做大公约数 6
*/
#include<stdio.h>
int main()
{
int a,b;
int t; //余数
scanf("%d %d", &a,&b);
while(b!=0){
t=a%b;
a=b;
b=t;
}
printf("gcd=%d\n",a);
return 0;
}
整数分解:
输入一个非负整数,正序输出它的每一位数字。
输入:13425
输出: 1 3 4 2 5
/*x=13425
13425/10000->1
13425%10000->3425
10000/10->1000
3425/1000->3
3425%1000->425
1000/10->100
425/100->4
425%100->25
100/10->10
25/10->2
25%10->5
10/10->1
5/1->5
5%1->0
1/10->0
*/
#include<stdio.h>
int main()
{
int x;
scanf("%d", &x);
int t = x;
int mask = 1;
while(t>9){ //根据x的位数获得mask
t/=10;
mask *=10;
} //根据x的位数获得mask
do{
int d = x/mask;
printf("%d", d);
if(mask>9){ //使前面几个输出结果之间有空格,最后一个输出结果后面没有空格
printf(" ");
} //使前面几个输出结果之间有空格,最后一个输出结果后面没有空格
x%=mask;
mask /= 10;
}while(mask>0);
printf("\n");
return 0;
}