C语言基础 4. While&DoWhile

C语言基础 4. While&DoWhile

4.1. 循环

  • 数数几位数:

    • 程序要读入一个4位以下的(含4位)的正整数, 然后输出这个整数的位数.

      • 比如:
        输入: 352
        输出: 3
  • 思考:

    • 人 VS 计算机

      • 人的方式: 眼睛一看就知道了, 352 -> 3
      • 计算机的方式: 判断数的范围来决定它的位数, 352(100, 999) -> 3 , 但是人不擅长, 因为人对数字的计算能力比文字弱
  • 问题:

    • 四位数的正整数可以, 那么任意范围的正整数怎么办?

    • 换个方式想:

      • 352 -> 3 很快
      • 12423534524562324784765 是几位, 总不能数吧!?
  • 数数:

    • 1242353452456232478476543245687696543245
    • 人: 从左向右数, 一个一个数
    • 计算机: 如果换一下, 从右向左, 让这个数每次都整除10, 去掉最右边的数,不断地去,直到没数可去, 在这个过程中不断地计数.
  • if语句数数几位数的代码:

#include <stdio.h>

int main()
{
	int num = 0;
	int weishu = 0;

	printf("请输入一个4位以下(包含4位)的正整数: ");
	scanf("%d", &num);

	if (num >= 1000) {
		weishu = 4;
	}
	else if (num >= 100) {
		weishu = 3;
	}
	else if (num >= 10) {
		weishu = 2;
	}
	else {
		weishu = 1;
	}

	printf("位数: %d位", weishu);
}
  • 循环来数数几位数的代码:
#include <stdio.h>

int main()
{
	int num = 0;		// 输入num时别用124235345245623247847654去试, 因为C语言中的int是有范围的
	int weishu = 0;

	printf("请输入一个任意位数的正整数: ");
	scanf("%d", &num);		// num/10, weishu++;

	while (num) {	// while(判断条件), 非0为真, 0为假, 真则进入循环, 假则跳出
		weishu++;	// 计数
		num /= 10;
	}

	printf("位数: %d位", weishu);
	return 0;
}

4.2. While

  • while:

    • 可以把while翻译成"当", 意思是当条件满足时, 不断重复循环体内的语句. 因为是先判断, 所以有可能循环一次也没有被执行.

    • 跟if语句形式很像, 就是将if语句中的if换成while即可, 不同的是,if是一次性的, 而while是反复不断的.

      if (num) {
      	weishu++;
      	num / 10;
      }
      
      while (num) {
      	weishu++;
      	num / 10;
      }
      
  • 调整:

    • while循环中要有能够改变判断条件的机会, 要不然有可能变成死循环

      • 比如:
        while (num) {
        	weishu++;
        	// num / 10;	// 将这段代码注释掉, 就变成了死循环
        }
        
  • 程序中的错误:

    	while (num) {
    		weishu++;
    		// num /= 10;
    	}
    	
    	错误信息: 超时
    	错误原因: while循环中少了调整判断条件的代码
    	解决办法: 添加上即可
    	得出结论: 程序编译通过也不一定算是正确了, 也有可能是代码有逻辑上的错误.
    
  • 数位数的代码:

#include <stdio.h>

int main()
{
	int num = 0;
	int weishu = 0;

	printf("请输入一个任意位数的正整数: ");
	scanf("%d", &num);

	while (num) {
		weishu++;
		num /= 10;
	}

	printf("位数: %d位", weishu);
	return 0;
}

4.3. DoWhile

  • 回顾:

    • 刚才的程序有点缺陷, 就是它不能判断0的位数, 所以我们想使用一个先执行循环再判断的循环结构.
  • do while:

    • 在进入循环时先执行, 再判断, 如果满足条件则继续下一轮循环, 不满足则结束循环.

    • 形式:

      • do {
        语句;
        } while (判断条件); // 注意: while()后面有个分号
  • while和do while:
    它们很像, 区别在于它们的循环体执行和判断条件有先有后, while可能一次都不执行, do while是至少执行一次的.

  • do while完成的代码:

#include <stdio.h>

int main()
{
	int num = 0;
	int weishu = 0;

	printf("请输入一个任意位数的正整数: ");
	scanf("%d", &num);

	do {
		weishu++;
		num /= 10;
	} while (num);

	printf("位数: %d位", weishu);
	return 0;
}

4.4. Test

  • 4.4.1. 猜数游戏:

    • 让计算机来想一个数, 然后让用户来猜, 用户每输入一个数, 就告诉它是大了还是小了, 直到用户猜中为止, 最后还要告诉用户它猜了多少次.

    • 疑问: 如何让计算机来想一个数, 这是个问题, 是让它通过一个特定的东西来生成一个随机数?

      • 已经懂了!
      #include <time.h>
      #include <stdlib.h>
      
      srand(time(0));
      int suijishu = rand() % 100;	// 这段代码可以生成一个随机数, %100是为了将这个数
      									控制在1-99, 因为这个随机数太大了
      
  • 代码:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
	srand(time(0));
	int suijishu = rand() % 100;
	int num = 0;
	int count = 0;

	printf("欢迎进入猜数字游戏, 现在计算机会自动生成一个1-99之间的数, 然后你来猜, 请输入一个数: \n");

	do {
		scanf("%d", &num);

		if (num > suijishu) {
			printf("大了, 请重新输入: \n");
		}
		else if (num < suijishu) {
			printf("小了, 请重新输入: \n");
		}
		count++;
	} while (num != suijishu);
	printf("恭喜你, 猜中了! 你一共猜了%d次.\n", count);
	return;
}
  • 4.4.2. 算平均数:

    • 让用户输入一系列的正整数, 最后输入-1表示输入结束, 然后程序计算出这些数的平均数, 输出输入的数字个数和平均数.
  • 程序中的错误:

    • scanf(“%d”, num);

      错误信息:“scanf”: 格式字符串“%d”需要类型“int *”的参数,但可变参数 1 拥有了类型“int”
      错误原因: scanf()中没有在变量前面加上&
      解决办法: 加上即可

  • 代码:

#include <stdio.h>
	
int main()
{
	int num = 0;
	int average = 0;
	int count = 0;
	int sum = 0;

	printf("提示: 这个程序是帮你算出这些数的平均数的, 请输入多个正整数, 每输入一个数之后请按一下回车, 接着输入第二个数, 最后输入-1表示输入结束: \n");

	while (num != -1) {
		sum += num;
		scanf("%d", num);		// 1 2 3 8 9 -1
		count++;
	}

	average = sum / (count - 1);

	printf("你一共输入了%d个数, 它们的平均数是: %d", count - 1, average);
	return 0;
}
  • 4.4.3. 整数的分解:

    • 一个整数是由1至多位数字组成的, 如何分解出整数的各个位上的数字, 然后加以计算?

      • 对一个整数做%10的操作, 就得到了它的个位数;
      • 对一个整数做/10的操作, 就去掉了它的个位数;
      • 然后再对第二步的结果做%10, 就得到了原来数的十位数了;
      • 以此类推.
  • 整数求逆:

    • 输入一个正整数, 输出逆序的数, 结尾的0逆序之后要求处理掉.
  • 代码:

#include <stdio.h>

int main()
{
	int num = 0;
	int digit = 0;
	int ret = 0;

	printf("请输入一个正整数, 会将它逆序输出: \n");
	scanf("%d", &num);

	while (num > 0) {
		digit = num % 10;
		// printf("%d", digit);	// 这段可以让700逆序成007
		ret = ret * 10 + digit;	// 核心:每次循环都让原来的结果(ret)往左移一位(*10),再加上新的digit
		num /= 10;
	}

	printf("%d", ret);
	return 0;
}

4.5. PAT

  • 04-0. 求符合给定条件的整数集(15)

    • 给定不超过6的正整数A,考虑从A开始的连续4个数字。请输出所有由它们组成的无重复数字的3位数。

    • 输入格式:
      输入在一行中给出A。

    • 输出格式:
      输出满足条件的的3位数,要求从小到大,每行6个整数。整数间以空格分隔,但行末不能有多余空格。

    • 输入样例:
      2

    • 输出样例:
      234 235 243 245 253 254
      324 325 342 345 352 354
      423 425 432 435 452 453
      523 524 532 534 542 543

  • 代码:

#include <stdio.h>

int main()
{
	int a;
	scanf("%d", &a);
	int i, j, k;
	//计数
	int count = 0;
	i = a;
	while (i <= a + 3) {
		j = a;
		while (j <= a + 3) {
			k = a;
			while (k <= a + 3) {
				//去掉有重复数字的数
				if (i != j && i != k && j != k) {
					printf("%d%d%d", i, j, k);
					//完成指定的格式
					count++;
					if (count == 6) {
						printf("\n");
						count = 0;
					}
					else {
						printf(" ");
					}
				}
				k++;
			}
			j++;
		 }
		i++;

	}
	return 0;
}
  • 04-1. 水仙花数(20)

    • 水仙花数是指一个N位正整数(N>=3),它的每个位上的数字的N次幂之和等于它本身。例如:153 = 1^3 + 5^3+ 3^3。本题要求编写程序,计算所有N位水仙花数.

    • 输入格式:
      输入在一行中给出一个正整数N(3<=N<=7)。

    • 输出格式:
      按递增顺序输出所有N位水仙花数,每个数字占一行。

    • 输入样例:
      3

    • 输出样例:
      153
      370
      371
      407

  • 代码:

#include <stdio.h>

int main()
{
	int n;
	scanf("%d", &n);
	//假设n为3, 产生100-999之间的数
	int i = 1;
	int first = 1;
	while (i < n) {
		first *= 10;
		i++;
	}
	//printf("%d", first);

	//遍历100-999
	i = first;		// 疑问: 为什么这里及以下的i不能用first直接替代
	while (i < first * 10) {
		//将这个数的每一位都取出来
		int tmp = i;
		int sum = 0;
		int j = 0;
		while (j < n) {
			int digit = tmp % 10;
			tmp /= 10;
			j++;
			//求每一位的n次幂
			int k = 0;
			int p = 1;
			while (k < n) {
				p *= digit;
				k++;
			}
			//将求出的n次幂求和
			sum += p;
		}

		//判断次幂的和与该数是否相等
		if (sum == i) {
			printf("%d\n", i);
		}
		i++;
	}
	return 0;
}
  • 04-2. 打印九九口诀表(15)

    • 下面是一个完整的下三角九九口诀表:

      1*1=1   
      1*2=2   2*2=4   
      1*3=3   2*3=6   3*3=9   
      1*4=4   2*4=8   3*4=12  4*4=16  
      1*5=5   2*5=10  3*5=15  4*5=20  5*5=25  
      1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36  
      1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49  
      1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64  
      1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81  
      
    • 本题要求对任意给定的1位正整数N,输出从11到NN的部分口诀表。

    • 输入格式:
      输入在一行中给出一个正整数N(1<=N<=9)。

    • 输出格式:
      输出下三角N*N部分口诀表,其中等号右边数字占4位、左对齐。

    • 输入样例:
      4

    • 输出样例:

      1*1=1   
      1*2=2   2*2=4   
      1*3=3   2*3=6   3*3=9   
      1*4=4   2*4=8   3*4=12  4*4=16 
      
  • 代码:

#include <stdio.h>

int main()
{
	int i = 1;
	
	int n;
	scanf("%d", &n);

	while (i <= n) {
		int j = 1;
		while (j <= i) {

			if (j * i <= 9) {
				printf("%d*%d=%d   ", j, i, j * i);
			}
			else if (j * i >= 10) {
				printf("%d*%d=%d  ", j, i, j * i);
			}
			j++;
		}
		printf("\n");
		i++;
	}
	return 0;
}
  • 04-3. 统计素数并求和(20)

    • 本题要求统计给定整数M和N区间内素数( 素数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数 ) 的个数并对它们求和。

    • 输入格式:
      输入在一行中给出2个正整数M和N(1<=M<=N<=500)。

    • 输出格式:
      在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以空格分隔。

    • 输入样例:
      10 31

    • 输出样例:
      7 143

  • 代码:

#include <stdio.h>

int main()
{
	int m, n;
	scanf("%d %d", &m, &n);
	//计数, 求和
	int count = 0;
	int sum = 0;
	//产生m到n之间的数
	int num = m;
	while (num <= n) {
		
		//产生除数
		int chushu = 2;
		while (chushu < num) {
			//试除
			if (num % chushu == 0) {
				break;
			}
			chushu++;
		}
		//全部试除之后, 符合条件的就是素数
		if (num == chushu) {
			count++;
			sum += num;
		}
		num++;
	}
	printf("%d %d", count, sum);
	return 0;
}
  • 04-4. 猜数字游戏(15)

    • 猜数字游戏是令系统随机产生一个100以内的正整数,用户输入一个数对其进行猜测,需要你编写程序自动对其与随机产生的被猜数进行比较,并提示大了(“Too big”),还是小了(“Too small”),相等表示猜到了。如果猜到,则结束程序。程序还要求统计猜的次数,如果1次猜出该数,提示"Bingo!“;如果3次以内猜到该数,则提示"Lucky You!”;如果超过3次但是在N(>3)次以内(包括第N次)猜到该数,则提示"Good Guess!“;如果超过N次都没有猜到,则提示"Game Over”,并结束程序。如果在到达N次之前,用户输入了一个负数,也输出"Game Over",并结束程序。

    • 输入格式:
      输入第一行中给出2个不超过100的正整数,分别是系统产生的随机数、以及猜测的最大次数N。随后每行给出一个用户的输入,直到出现负数为止。

    • 输出格式:
      在一行中输出每次猜测相应的结果,直到输出猜对的结果或"Game Over"则结束。

    • 输入样例:
      58 4
      70
      50
      56
      58
      60
      -2

    • 输出样例:
      Too big
      Too small
      Too small
      Good Guess!

  • 代码:

#include <stdio.h>

int main()
{	
	int num1, n, num2 = 0;
	scanf("%d %d", &num1, &n);

	//计数
	int count = 0;
	while (num2 >= 0) {
		//让用户输入猜的数
		scanf("%d", &num2);
		//计数
		count++;
		//判断是否正确
		if (num1 < num2) {
			printf("Too big\n");
		}
		else if (num1 > num2) {
			printf("Too small\n");
		}
		else {
			if (count == 1) {
				printf("Bingo!\n");
				break;
			}
			else if (count <= 3) {
				printf("Lucky You!\n");
				break;
			}
			else {
				printf("Good Guess!\n");
				break;
			}
		}
		if (count == n) {
			printf("Game Over!\n");
			break;
		}
	}
	if (num2 < 0) {
		printf("Game Over!");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值