C语言
第四章
4.1.1循环
数数几位数
- 程序要读入一个4位以下(含4位)的正整数,然后输出这个整数的位数。如:
- 输入352.输出:3
人VS计算机
- 人的方式:眼睛一看就知道了
- 计算机的方式:判断数的范围来决定它的位数
- 352∈[100,999]->3位
- 人不擅长,因为人对数字的计算能力比文字弱
程序实现
int x;
int n = 1;
scanf("%d",&x);
if(x>999){
n = 4;
}else if(x>99){
n = 3;
}else if(x>9){
n = 2;
}else{
n = 1;
}
printf("%d\n",n);
- 因为题目明确了4位数及以下的正整数,所以可以简化一些判断
- 因为从高处往下判断,所以不需要判断上限了
- 问题:任意范围的正整数怎么办?
- 不可能每多加一位数就多加一个if,这样下去无穷尽也
换个方式想
- 352->3 很快
- 123812843267518273618273612675317是几位数?
- 数数!
数数
- 123812843267518273618273612675317
- 人怎么数?从左往右数,一次划掉一个数字
- 计算机怎么划掉那个数字呢?
三位数逆序的题
- 352
- 那么123812843267518273618273612675317%100000000000000000000000000000000->23812843267518273618273612675317
- 怎么得到那100000000000000000000000000000000?
人VS计算机
- 如果换一下,从右边开始划
- 123812843267518273618273612675317/10->12381284326751827361827361267531
- 去掉最右边的数,然后?
- 不断地划,直到没数可以划…
试试代码
int x;
int n=0;
scanf("%d",&x);
n++;
x/10;
if(x>0){
n++;
x/=10;
if(x>0){
n++;
x/=10;
if...
}
}
printf("%d",n);
int x;
int n=0;
scanf("%d",&x);
n++;
x/10;
while(x>0){
n++;
x/=10;
}
printf("%d",n);
4.1.2WHILE循环
if(x>0){
x/=10;
n++;
}
while(x>0){
x/=10;
n++;
}
(循环体内要有改变条件的机会)
while循环
- 如果我们把while翻译作“当”,那么一个while循环的意思就是:当条件满足时,不断地重复循环体内的语句。
- 循环执行之前判断是否继续循环,所以有可能循环一次也没有被执行。
- 条件成立是循环继续的条件。
再想想
int x;
int n=0;
scanf("%d",&x);
n++;
x/10;
while(x>0){
n++;
x/=10;
}
printf("%d",n);
int x;
int n=0;
scanf("%d",&x);
while(x>0){
n++;
x/=10;
}
printf("%d",n);
看程序运行结果
- 人脑模拟计算机的运行,在纸上列出所有的变量,随着程序的进展不断重新计算变量的值。当程序运行结束时,留在表格最下面的就是程序的最终结果。
验证
- 测试程序常使用边界数据,如有效范围两端的数据、特殊的倍数等
调试
int x;
int n=0;
scanf("%d",&x);
n++;
x/10;
while(x>0){
n++;
x/=10;
}
printf("%d",n);
4.1.3DO-WHILE循环
数位数的算法
- 用户输入x;
- 初始化n为0;
- x=x/10,去掉个位;
- n++;
- 如果x>0,回到3;
- 否则n就是结果。
do-while循环
- 在进入循环的时候不做检查,而是在执行完一轮循环体的代码之后,再来检查循环的条件是否满足,如果满足则继续下一轮循环,不满足则结束循环
do
{
<循环体语句>
}while(<循环条件>);
(左边do-while,右边while)
两种循环
- do-while循环和while循环很像,区别是在循环体执行结束的时候才来判断条件。也就是说,无论如何,循环都会执行至少一遍,然后再来判断条件。与while循环相同的是,条件满足时执行循环,条件不满足时结束循环。
int x;
int n=0;
scanf("%d",&x);
do{
n++;
x/=10;
}while(x>0);
printf("%d",n);
4.2.1循环计算
log?x
int x;
int ret=0;
scanf("%d",&x);
while(x>1){
x/=2;
ret ++;
};
printf("log?x of %d is %d.",x,ret);
输出结果每次都是1,因为循环除以2最后永远是1(整数)。那么,这个log?x错在哪呢?
小套路
int x;
int ret=0;
scanf("%d",&x);
int t=x;
while(x>1){
x/=2;
ret ++;
};
printf("log?x of %d is %d.",t,ret);
这些值是怎么定的?
int x;
int ret=0;
scanf("%d",&x);
int t=x;
while(x>1){
x/=2;
ret ++;
};
printf("log?x of %d is %d.",t,ret);
为什么ret从0开始?
为什么while的条件里面是x>1?
因为在循环中,各个数值之间是有关联的,比如做累加,初始值一般为0,但如果累乘就一般为1。
计数循环
int count=100;
while(count>=0){
count--;
printf("%d\n",count);
}
printf("发射!\n");
- 这个循环需要执行多少次?
- 循环停下来的时候,有没有输出最后的0?
- 循环结束后,count的值是多少?
(小套路:如果要模拟运行一个很大次数的循环,可以模拟较少的循环次数,然后作出推断。)
4.2.2猜数游戏
猜数游戏
- 让计算机来想一个数,然后让用户来猜,用户每输入一个数,就告诉他是大了还是小了,直到用户猜中为止,最后还要告诉用户他猜了多少次。
- 因为需要不断重复让用户猜,所以需要用到循环
- 在实际写出程序之前,我们可以先用文字描述程序的思路
- 核心重点是循环的条件
- 计算机随机想一个数,记在变量number里;
- 一个负责记次数的变量count初始化为0;
- 让用户输入一个数字a;
- count递增(加1);
- 判断a和number的大小关系,如果a大,就输出“大”;如果a小就输出“小”;
- 如果a和number是不相等的(无论大还是小),程序转回到第3步;
- 否则,程序输出“猜中”和次数,然后结束。
(循环的条件是a和number不相等)
scrand(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("你猜的数大了。");
}else if(a<number){
printf("你猜的数小了。");
}
}while(a != number);
printf("太好了!你用了%d次就猜到了答案。\n",count);
随机数
%100
4.2.3算平均数
算平均数
- 让用户输入一系列的正整数,最后输入-1表示输入结束,然后程序计算出这些数字的平均数,输出输入的数字的个数和平均数
- 变量->算法->流程图->程序
变量
- 一个记录读到的整数的变量
- 平均数要怎么算?
- 只需要每读到一个数,就把它加到一个累加的变量里,到全部数据读完,再拿它去除以读到的数的个数就可以了
- 一个变量记录累加的结果,一个变量记录读到的数的个数
算法
- 初始化变量sum和count为0;
- 读入number;
- 如果number不是-1,则将number加入sum,并将count加1,回到2;
- 如果number是-1,则计算和打印出sum/count(注意换成浮点来计算)。
#include<stdio.h>
int main(){
int number;
int sum=0;
int count=0;
do{
scanf("%d",&number);
if(number!=-1){
sum+=number;
count++;
scanf("%d",&number);
}
}while(number != -1);
printf("%f\n",1.0*sum/count);
return 0;
}
4.2.4整数逆序
整数的分解
- 一个整数是由1至多位数字组成的,如何分解出整数的各个位上的数字,然后加以计算
- 对一个整数做%10的操作,就得到它的个位数;
- 对一个整数做/10的操作,就去掉了它的个位数;
- 然后再对上一步结果做%10,就得到原来数的十位数了;
- 以此类推。
#include<stdio.h>
int main(){
int x;
scanf("%d",&x);
int digit=0;
int ret=0;
while(x>0){
digit=x%10;
printf("%d",digit);
ret=ret*10+digit;
x/=10;
}
return 0;
}
(这里有个小问题,输入007,输出为7,输入其他第一个数字不为0的都可以顺利逆置)
|