目录
4.1 break和continue的区别-- 判断是否一个数是否是素数
4.2 多重循环-- 输出100以内的素数(变形:输出前50个素数)
事实上你能熬过“循环”这一关,就赢了70%的自学者!视频中的例子主要是为了讲语法,例子之间有递进的关系。课后刷题才是度过这关的重要手段。通过刷题,可以见多识广,下次遇到类似问题的时候,会给你启发。通过刷题,遇到错误,调试并修正错误,这是学习的重要途径。没有人可以不劳而获,没有人可以坐享其成。
1 while循环-- 判断一个正整数是几位数
条件不满足,可能一次都不执行。循环体内要有改变条件的机会,要不然会变成死循环。
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
int cnt = 0;
int t = x;
while(x != 0){
x /= 10;
cnt++;
}
printf("%d为%d位数.\n",t,cnt);
return 0;
}
验证
上面的程序有个问题,当输入是0时,程序就不对了。尽管题目给出了正整数的要求,但要是以后遇到求所有整数的位数呢???负数好办,直接变成正数再进行判断,但现在的这个程序处理不了0的问题。怎么修改呢?
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
int cnt = 0;
int t = x;
if(x > 0){
while(x > 0){
x /= 10;
cnt++;
}
}else{
cnt = 1;//对0的情况单独处理
}
printf("%d为%d位数.\n",t,cnt);
return 0;
}
/*
int cnt = 0;
int t = x;
cnt++;//在循环外先让cnt加一
x /= 10;
while(x != 0){
x /= 10;
cnt++;
}
*/
2 do-while循环-- 数位数的算法
不管三七二十一,先执行一次。
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
int cnt = 0;
int t = x;
do{
cnt++;
x /= 10;
}while(x > 0);
printf("%d为%d位数.\n",t,cnt);
return 0;
}
while循环和do-while循环的流程图比较。
3 for循环-- 计算log2(x)
循环本身语法并不难,编程难在哪?难在想问题,怎么把问题变成程序。
//计算log2(x)
#include <stdio.h>
int main()
{
int x;
scanf("%d",&x);
int cnt = 0;
int t = x;
while(x > 1){
cnt++;
x /= 2;
}
printf("log2 of %d = %d.\n",t,cnt);
return 0;
}
小套路:
-
计算之前先保留原始的值,后面可能有用。
-
循环初始值设置(一般来说累加sum=0,累乘fact=1)
-
如果要模拟运行很大次数的循环,可以模拟较少的循环次数,然后作出推断。
3.1 求平均数
#include <stdio.h>
int main()
{
int sum = 0;
int cnt = 0;
int x,average;
scanf("%d",&x);
while(x != -1){
sum += x;
cnt++;
scanf("%d",&x);
}
average = sum/cnt;
printf("average is %d\n",average);
return 0;
}
3.2 猜数游戏
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(0));
int number = rand()%100 + 1;
int count = 0;
int a = 0;
printf("我已经想好了一个1到100之间的数。");
do{
printf("请猜这个1到100之间的数:");
scanf("%d",&a);
count++;
if(a > number){
printf("大了。\n");
}else if(a < number){
printf("小了。\n");
}
}while(a != number);
printf("你用了%d次就猜到了答案。\n",count);
}
0-100的数只要7次,二分查找的思想。
3.3 整数分解
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 5003;
int digit;
int ret = 0;
while(x >0 ){
digit = x%10;
printf("%d",digit);
ret = ret*10 + digit;
// printf("x=%d,digit=%d,ret=%d\n",x,digit,ret);
x /= 10;
}
//printf("%d",ret);
return 0;
}
4 多重循环
4.1 break和continue的区别-- 判断是否一个数是否是素数
引出break:如果输入的数对2取余等于0,那就可以直接判定这个数不是素数,就不需要进行下面的循环了。break的作用:跳出循环。
#include <stdio.h>
int main()
{
int x;
x = 6;
//scanf("%d",&x);
int isPrime = 1;//x是素数
int i;
for(i = 2; i < x; i++){
if(x % i == 0){
isPrime = 0;
break;
}
}
if(isPrime){
printf("是素数\n");
}
else{
printf("不是素数\n");
}
return 0;
}
break和continue的区别:
break:跳出循环
continue:跳过循环这一轮剩下的语句进入下一轮。
注意!!!break:在循环嵌套中,只是离开了自己的循环。break和continue都只能对它所在的那层循环做。
4.2 多重循环-- 输出100以内的素数(变形:输出前50个素数)
输出100以内的素数。
#include <stdio.h>
int main()
{
int x,i;
for(x = 2; x < 100; x++){
int isPrime = 1;
for(i = 2; i < x; i++){
if(x % i == 0){
isPrime = 0;
break;
}
}
if(isPrime){
printf("%d ",x);
}
}
printf("\n");
return 0;
}
输出前50个素数。
#include <stdio.h>
int main()
{
int x = 2;//循环的初值,之前的for循环
int cnt = 0;//循环的条件
while(cnt < 50){
int isPrime = 1;
int i;
for( i = 2; i < x; i++){
if( x % i == 0){
isPrime = 0;
break;
}
}
if(isPrime == 1){
printf("%d ",x);
cnt++;
}
x++;//之前的for循环
}
printf("\n");
return 0;
}
4.3 goto语句和接力break-- 凑硬币
#include <stdio.h>
int main()
{
int one,two,five;
int x;
scanf("%d",&x);
int exit = 0;
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 + 2*two + five*5 == 10*x){
printf("可以用%d个1角%d个2角%d个5角得到%d元\n",one,two,five,x);
}
}
}
}
return 0;
}
那如果只想要输出一种结果的时候怎么做?-----接力break或者goto语句(要从内存循环跳到最外层的时候用)
#include <stdio.h>
int main()
{
int one,two,five;
int x;
scanf("%d",&x);
int exit = 0;
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 + 2*two + five*5 == 10*x){
printf("可以用%d个1角%d个2角%d个5角得到%d元\n",one,two,five,x);
exit = 1;
break;
}
}
if(exit) break;
}
if(exit) break;
}
return 0;
}
#include <stdio.h>
int main()
{
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 + 2*two + five*5 == 10*x){
printf("可以用%d个1角%d个2角%d个5角得到%d元\n",one,two,five,x);
goto out;
}
}
}
}
out:
return 0;
}
5 循环的应用
5.1 求和
5.2 求最大(小)公约数
第一种方法:枚举。
第二种方法:辗转相除法。
#include <stdio.h>
int main()
{
/*如果b等于0,计算结束,a就是最大公约数;
否则,计算a除以b的余数,让a等于b,而b等于那个余数;
回到第一步。
计算12和18的最大公约数
a b t
12 18 12
18 12 6
12 6 0
6 0
*/
int a,b;
int t;
scanf("%d %d",&a,&b);
while( b!= 0){
t = a % b;
a = b;
b = t;
//printf("a=%d,b=%d,t=%d\n",a,b,t);
}
printf("gcd=%d\n",a);
return 0;
}
5.3 正序分解整数
记住:
第一种方法:先逆序,再逆序输出。在输入的数末尾没有0时才适用。
第二种方法:
#include <stdio.h>
int main()
{
int x;
//scanf("%d",&x);
x = 700;
//计算mask的值
int mask = 1;
int t = x;//保留之前的值
while(t > 9){
t /= 10;
mask *= 10;
}
printf("x=%d,mask=%d\n",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;
}