c语言学习之路4

下面对于while循环、do-while循环、for循环相关的知识进行学习记录
4.1判断是几位数

 #include<stdio.h> 
 int main(){
     int x;
     scanf("%d",&x);
     if(x>999) {
  	printf("4");
     }else if(x>99){
 	printf("3");
     }else{
        printf("2");
     }
 }

这个程序只能判断2位,3位,4位的数,如果很多位数,比如123344557676879955…怎么办?

#include<stdio.h> 
 int main(){
     int x,count=0;
     scanf("%d",&x);
     count++;//处理0的问题 输入0应该输出1 
     x=x/10;
     while(x>0) {
          count++;
 	  x=x/10;
     }
     printf("%d",count);
}

while循环
·如果我们把while翻译作“当”,那么一个while循环的意思就是:当条件满足时,不断地重复循环体内的语句。

·循环执行之前判断是否继续循环,所以有可能循环一次也没有被执行。

·条件成立是循环继续的条件。
在这里插入图片描述

如果没有外面的运算?

#include<stdio.h> 
 int main(){
     int x,count=0;
     scanf("%d",&x);
     while(x>0) {
        count++;
    	x=x/10;
     }
     printf("%d",count);
}

当输入352 输出3 结果正确
当输入0 输出0 结果错误
删掉外面的运算之后的程序处理不了0的问题

验证
·测试程序常使用边界数据,如有效范围两端的数据、特殊的倍数等
如: ·个位数、10、0、负数

do-while循环
·在进入循环的时候不做检查,而是在执行完一轮循环体的代码之后,再来检查循环的条件是否满足,如果满足则继续下一轮循环,不满足则结束循环

do{
<循环体语句>
}while(<循环条件>);
在这里插入图片描述
用do-while循环实现

#include<stdio.h> 
int main(){
    int x,count=0;
    scanf("%d",&x);
    do{
        count++;
        x=x/10;
    }while(x>0);//后面需要有分号 
    printf("%d",count);
}

两种循环
·do-while循环和while循环很像,区别是在循环体执行结束的时候才来判断条件。也就是说,无论如何,循环都会执行至少一遍,然后再来判断条件。与while循环相同的是,条件满足时执行循环,条件不满足时结束循环。

4.2循环计算 计算log2(X)

#include<stdio.h> 
int main(){
    int x,ret=0; 
    scanf("%d",&x); 
    int t = x; //保存原始值
    while(x>1){
  	x = x/2;
  	ret++;
    }
    printf("log2 of %d is %d",t,ret);//此时x的值已经改变了,所以需要在前面保存他的值 
}

4.3猜数游戏
·让计算机随机产生一个数,然后让用户来猜,用户每输入一个数,就告诉她是大了还是小了,直到用户猜中为止,最后还要告诉用户他猜了多少次。

#include<stdio.h> 
#include<stdlib.h>
#include<time.h>
int main(){   
    srand(time(0));
    int number=rand()%100;//0-99
    int a,count=0;
    scanf("%d",&a);
    count++;
    while(number!=a){
        count++;
  	if(a>number){
           printf("too big\n");
        }else if(a<number){
           printf("too small\n");
        }else{
           break;
        }
        scanf("%d",&a);
    } 
    printf("right!你用了%d次就猜对了\n",count);
}

随机数
·每次使用rand()就得到一个随机的整数

%100
·x%n的结果是[0,n-1]的一个整数

4.4算平均数
·用户输入一系列的正整数,最后输入-1表示输入结束,然后程序计算出这些数字的平均数,输出输入的数字的个数和平均数

#include<stdio.h> 
int main(){
    int number,count=0,sum=0;
    scanf("%d",&number);
    while(number!=-1){
        sum+=number;
        count++;
     scanf("%d",&number);
    }
    double avg = sum*1.0/count;
    printf("%f",avg);   
}  

4.5整数逆序

#include<stdio.h> 
int main(){
    int x,digit,ret=0;
    scanf("%d",&x); 
    while(x>0){
       digit=x%10;//分离出来的每一位的数字 
       ret=ret*10+digit; 
       printf("x=%d digit=%d ret=%d\n",x,digit,ret);
       x=x/10;
    }
}

使用整数的分解的思想,取出x的每一位数字来进行逆序的操作

for循环

4.6阶乘
n!=1×2×3×…×n
用while循环实现

#include<stdio.h> 
int main(){
    int n,p=1;
    scanf("%d",&n);
    while(n>0){
        p=p*n;
        n--;
    } 
    printf("%d",p);
}

用for循环实现

#include<stdio.h> 
int main(){
    int n,p=1;
    scanf("%d",&n);
    if(n==0){
        p=1;
    }
    for(int i=1;i<=n;i++){
        p=p*i;
    }
    printf("%d",p);
}

·for循环像一个计数循环:设定一个计数器,初始化它,然后在计数器到达某值之前,重复执行循环体,而每执行一轮循环,计数器值以一定步进进行调整,比如加1或者减1。如:

for(i=0;i<5;i=i+1){
printf("%d",i)
}

for=对于
·for(count=10;count>0;count–)
·就读成:“对于一开始的count=10,当count>0时,重复做循环体,每一轮循环在做完循环体内语句后,使得count–。”

循环次数
·for(i=0;i<n;i++)
·则循环的次数是n,而循环结束以后,i的值是n。循环的控制变量i,是选择从0开始还是从1开始,是判断i<n还是判断i<=n,对循环的次数,循环结束后变量的值都有影响。

for(初始动作;条件;每轮的动作){
}
·for中的每一个表达式都是可以省略的
for(;条件;)==while(条件)

tips
·如果有固定次数,用for
·如果必须执行一次,用do-while
·其他情况用while

4.7素数
只能被1和自己整除的数,不包括1.
2,3,5,7,11,13,17,19…

#include<stdio.h> 
int main(){
    int x;//x是否为素数 
    scanf("%d",&x); 
    int isPrime=1;
    for(int i=2;i<x;i++){
         if(x%i==0){//x不是一个素数 
             isPrime=0;
             break;
         }
     }
     if(isPrime){
         printf("x=%d是素数",x); 
     }else{
         printf("x=%d不是素数",x); 
     }
}

break VS continue
·break:跳出循环
·continue:跳过循环这一轮剩下的语句进入下一轮

嵌套的循环
·循环里面还是循环

4.8 100以内的素数

#include<stdio.h> 
int main(){
    for(int i=2;i<=100;i++){
    int isPrime=1;//注意要卸载循环里面 对于每一个数字都需要初始化isPrime=1 
    for(int j=2;j<i;j++){
         if(i%j==0){
             isPrime=0;
             break;
         }
    }
    if(isPrime){
         printf("i=%d是素数\n",i);
    }
  }
}

4.9 输出前50个素数

#include<stdio.h> 
int main(){
    int x=2,count=0;
    while(count<50){
        int isPrime=1;
        for(int i=2;i<x;i++){
            if(x%i==0){
                isPrime=0;
                break;
            }
        }
        if(isPrime){
             count++;//是素数才+1 
             printf("%d是素数\n",x);
        }
        x++;
     }
}

4.10 凑硬币
·如何用1角、2角和5角的硬币凑出10元以下的金额呢

#include<stdio.h> 
int main(){
    int x;
    //i:one   j:two  k: five 
    scanf("%d",&x);
    for(int i=1;i<=x*10;i++){
        for(int j=1;j<=x*10/2;j++){
            for(int k=0;k<=x*10/5;k++){
                int sum=i+j*2+k*5;
                if(sum==x*10){
                    printf("可以用%d个一角加%d个两角加%d个五角得到%d元\n",i,j,k,x);
                }
            }
        }
    }
}

如果只需要得到一个结果,组合出一个结果就结束,可以使用break或continue

#include<stdio.h> 
int main(){
    int x;
    //i:one   j:two  k: five 
    scanf("%d",&x);
    int exit = 0;
    for(int i=1;i<=x*10;i++){
        for(int j=1;j<=x*10/2;j++){
            for(int k=0;k<=x*10/5;k++){
                int sum=i+j*2+k*5;
                if(sum==x*10){
                    printf("可以用%d个一角加%d个两角加%d个五角得到%d元\n",i,j,k,x);
                    exit=1;
                    break;
                }
            }
            if(exit) break;
        }
        if(exit) break;
    }
}

break和continue
·只能对它所在的那层循环做

也可以使用goto

#include<stdio.h> 
int main(){
    int x;
    //i:one   j:two  k: five 
    scanf("%d",&x);
    for(int i=1;i<=x*10;i++){
        for(int j=1;j<=x*10/2;j++){
            for(int k=0;k<=x*10/5;k++){
                int sum=i+j*2+k*5;
                if(sum==x*10){
                    printf("可以用%d个一角加%d个两角加%d个五角得到%d元\n",i,j,k,x);
                    goto out;
                }
            }
        }
    }
 out: 
    return 0;
}

goto适合在多重循环中需要从最内层跳出到最外层时使用

4.11求和
f(n)= 1+1/2+1/3+1/4+…+1/n

#include<stdio.h> 
int main(){
    int n;
    scanf("%d",&n);
    double sum=0;
    for(int i=1;i<=n;i++){
        sum+=1.0/i;
    } 
    printf("f(%d)=%f",n,sum);
}

若f(n)= 1-1/2+1/3-1/4+…+1/n,前n项和是多少

方法一:奇数项前面是加号,偶数项前面是减号

#include<stdio.h> 
int main(){
    int n;
    scanf("%d",&n);
    double sum=0;
    for(int i=1;i<=n;i++){
        if(i%2!=0){
           sum+=1.0/i;
        }else{
           sum-=1.0/i;
        }  
    } 
    printf("f(%d)=%f",n,sum);
}

方法二:使用sign,首先设定为sign=1,每加一个数sign变号

#include<stdio.h> 
int main(){
    int n;
    scanf("%d",&n);
    double sum=0;
    int sign=1;
    for(int i=1;i<=n;i++){
        sum+=sign*1.0/i;
        sign=-sign;
    }
    printf("f(%d)=%f",n,sum);
}   

可以直接让sign为double类型的,这样在sum计算那里就不需要乘以1.0了

4.12 正序分解整数
·输入一个非负整数,正序输出它的每一位数字
·输入:13425
·输出: 1 3 4 2 5

思路一:先把数字逆序 ,再对这个数字进行逆序分解

#include<stdio.h> 
int main(){
    //先逆序再分解
    int x;
    scanf("%d",&x);
    int t=0;
    do{
      int d=x%10;
      t=t*10+d;
      x/=10;
    } while(x>0);
    printf("x=%d,t=%d\n",x,t);
    x=t;
    do{
      int d=x%10;
      printf("%d",d);
      if(x>9){
         printf(" ");
      }
      x/=10;
    }while(x>0);
    printf("\n");
}

输入 12345
输出:1 2 3 4 5
结果正确

输入:700
输出:7
结果错误

所以先逆序再逆序分解的方案只适合用于末尾没有0的数字

思路二:

#include<stdio.h> 
int main(){
    int x;
    scanf("%d",&x);
    int t=x;
    int mask=1;
    while(t>9){
        t=t/10;
        mask=mask*10;
    }
    printf("x=%d,mask=%d\n",x,mask);
    do{
        int digit = x/mask;
        printf("%d",digit);
        if(mask>9){
            printf(" ");
        }
        x=x%mask;
        mask=mask/10;
    }while(mask>0);
    printf("\n");
}

4.13求最大公约数
·输入两个数a和b,输出它们的最大公约数

方法一:枚举
(1)设t为2
(2)如果u和v都能被t整除,则记下这个t
(3)t加后重复第2步,直到t等于u或v
(4)那么,曾经记下的最大的可以同时整除u和v的t就是gcd

#include<stdio.h> 
int main(){
    int a,b;
    int min;
    scanf("%d %d",&a,&b);
    if(a<b){
        min=a;
    }else{
        min=b;
    }
    int ret=0;
    int i;
    for(i=1;i<min;i++){
        if(a%i==0){
            if(b%i==0){
                ret=i;
            }
        }
    }
    printf("%d和%d的最大公约数是%d",a,b,ret);
}

方法二:辗转相除法
(1)如果b等于0,计算结束,a就是最大公约数
(2)否则,计算a除以b的余数,让a等于b,而b等于那个余数
(3)回到第一步

#include<stdio.h> 
int main(){
    int a,b,t;
    scanf("%d %d",&a,&b);
    while(b!=0){
        t=a%b;
        a = b;
        b=t;
    }
    printf("gcd=%d",a); 
}

例:
a b t
12 18 12
18 12 6
12 6 0
6 0

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值