[C]第二章--分支语句与循环语句(2)--实战演练


只有在实际应用中才可以感受到分支与循环语句的微妙之处.
以下列举几个笔者练习过的比较经典的例题.

拉门帘

要求:

  • 编写代码,演示多个字符从两端移动,向中间汇聚.达到拉门帘的效果.
#include<stdio.h>
#include<stdlib.h>
#include <Windows.h>
#include <string.h>
int main(){
   char arr1[] = "I like C programming!";//被掀开的内容
   char arr2[] = "#####################";//掀开前的内容
   int left = 0;
   int right = strlen(arr1) - 1;
   printf("%s\n", arr2);
//接下面代码
  1. while 实现
	while (left <= right) {
		//需要包含头文件<windows.h>
		Sleep(1000);//可有可无,不过加上会有动态效果

		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		++left;
		--right;
		printf("%s\n", arr2);
	}
    system("pause");
    return 0;
}
  1. for 实现
   for(left = 0,right = strlen(arr1) - 1;left <= right;++left,++right){
   		Sleep(1000);
   		arr2[left] = arr1[left];
   		arr2[right] = arr1[right];
   		printf("%s\n",arr2);
   	}
   system("pause");
   return 0;
}

ATM机登录界面

int main(){
	char pas[1024] = "";//用户输入的密码
	char password[] = "123456";
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; ++i) {
		printf("请输入密码:\n");
		scanf("%s", pas);
		if (strcmp(pas, password) == 0) {
			break;
		}
	}
	//循环结束的情况只有两种
	//1.输错三次,不满足i < 3,登录失败.
	//2.输入了正确的密码,登陆成功.
	if (i == 3) {
		printf("输入错误三次,退出\n");
	}
	else {
		printf("登陆成功!\n");
	}
    system("pause");
    return 0;
}

注:

  1. 字符串比大小遵循的是字典序
    若第一个参数等于第二个参数,返回0.
    若第一个参数小于第二个参数,返回负数.
    若第一个参数大于第二个参数,返回正数.
    从第一个元素向后判断.
  2. 字符串比较的是两个字符串首地址是否相同,之后详解.

折半查找(二分查找)

先要明晰查找该如何实现:

int main(){
	int xiabiao;
	int num = 7;//查找的元素
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};
	for (int i = 0; i < 10; i++){
		if (num == arr[i]){
			xiabiao = i;//找到目标元素将下标赋值给index
		}
	}
	printf("%d\n", xiabiao);
	system("pause");
}

这样做太过于繁琐,需要将索引值与 数组中所有值进行比较,直到找到那个值或者全部判断完没有这个值才结束,时间复杂度很大,那么就引入了简化的折半查找.

函数体中的折半查找:

int main(){
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int left = 0;
	int right = sizeof(arr) / sizeof(arr[0]) - 1;
	int to_find = 7;
	int mid = 0;
	while (left <= right) {
		mid = (left + right) / 2;
		if (arr[mid] > to_find) {
			right = mid - 1;
		}
		else if (arr[mid] < to_find) {
			left = mid + 1;

		}
		else
			break;
	}
	if (left <= right) {
		printf("找到了,下边是%d\n", mid);
	}
	else
		printf("没找到.\n");
    system("pause");
    return 0;
}

实现一个折半查找的函数:(函数定义中实现)

int search(int arr[],int left,int right,int to_find){
	int mid = 0;
	while(left <= right){
		mid = (left + right) >> 1;
		//等价于mid = (left + right) / 2;
		if(arr[mid] > to_find){
			right = mid - 1;
		}
		else if(arr[mid] < to_find){
			left = mid + 1;
		}
		else
			return mid;
	}
	return -1;
	//找不到的话返回-1;	
}

其实折半查找的思维很简单,就是把两侧值(最大与最小值)的平均值作为中值和要找的值进行对比,

  • 如果要找的值大于中值,说明需要找的值在这个中值右边,左半边就不需要查找了,所以重新规划范围,将最左值更新为mid + 1,重新进行下一次查找.
  • 如果要找的值小于中值,说明需要找的值在这个中值左边,右半边就不需要查找了,所以重新规划范围,将最右值更新为mid - 1,重新进行下一次查找.

注:

  1. 整形数组可以通过 sizeof(arr) / sizeof( arr[0] )的方式确定数组中有多少元素.
  2. 这个查找的数组必为有序数组,不然无法实现.

猜数字

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
void menu() {
	printf("----------------\n");
	printf("----欢迎游戏----\n");
	printf("----开始:1-----\n");
	printf("----退出:2-----\n");
	printf("----------------\n");
	printf("----请选择:----\n");
}
void game() {
	int random_num = rand() % 100 + 1;//保证在1~100范围之内
	int input = 0;
	while (1) {
		printf("请输入猜的数字:\n");
		scanf("%d", &input);
		if (input > random_num) {
			printf("猜大了!\n");
		}
		else if (input < random_num) {
			printf("猜小了!\n");
		}
		else {
			printf("猜对了,恭喜你!\n");
			break;
		}
	}
}
int main(){
	int input = 0;
	srand((unsigned)time(0));//设置随机种子,需要包含头文件<time.h>
	do {
		menu();
		scanf("%d", &input);
		switch (input) {
		case 1:
			game();//开始游戏
			break;
		case 0://退出游戏
			break;
		default:
			printf("输入错误,重新输入!\n");
			break;
		}
	} while (input);
    system("pause");
    return 0;
}

srand((unsigned)time(0));这句设置随机种子的语句需要详细解读一下

  • srand() 函数是随机数发生器的初始化函数,要想让其产生随机数,那么里面的参数就要是随机值.
  • time(0) 想想现实生活中什么是随机的?最常见的就是时间,所以在这里引入时间戳的概念.
    (简单来说就是从格林威治时间1970年1月1日与现在时间的秒数之差)
    所以这个time(0)就获取了当前时间的时间戳,引入srand函数
  • (unsigned)
    因为time(0)时间戳返回的是一个time_t,也就是long int类型的数据(64位整数),而srand返回的是32位整数,转换时会发生精度丢失,所以这里用一句强制类型转换的语句unsigned (int),保证精度对齐.

random_num = rand() % 100 + 1;是如何保证取值范围在1~100之间的呢?
rand()函数生成的随机值与100取模就保证了数据范围在0~99之间
再给数据集加上1,所以范围约束在了1~100之间了

关机小程序

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(){
	char input[10] = { 0 };
	system("shutdown -s -t 60");
again:
	printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:\n");
	scanf("%s", input);
	if (strcmp(input, "我是猪") == 0) {
		system("shutdown -a");
	}
	else {
		goto again;
	}
    system("pause");
    return 0;
}

一个简单的恶搞小程序,利用goto与标签跳转结合的方式实现.
需要注意的是:

  • 因为这里输入的时候,输入界面无法输入汉字字符,所以只能通过复制粘贴的方式实现输入,而且不可以通过 ctrl + v的方式进行粘贴,只能右键点击 -> 粘贴.
    解决方案:可以通过让用户输入i am a pig等效替代
  • 这里运用了系统指令system( )语句,可以控制PC机开关机,是不是感觉打开了新世界的大门?其实你也可以把代码编辑器看做一个控制台,这就和cmd指令控制是一样的,其他的功能有需要的同学可以自行百度~~

猜你喜欢

转载自blog.csdn.net/qq_42351880/article/details/84825705
今日推荐