编程DIY一.几个有趣的小程序

Posted ·潇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编程DIY一.几个有趣的小程序相关的知识,希望对你有一定的参考价值。

系列前言
兴趣是最好的老师。本系列介绍一些非常容易上手编写的小程序,这些小程序给博主的学习之路带来了许多欢乐,特记录分享!

编程语言:C语言
编程环境:Visual Studio 2019

本篇预备知识

【C语言从青铜到王者】第零篇·与C语言来个约会

【C语言从青铜到王者】第一篇·详解分支与循环


文章目录


让程序“动起来”:标题浮现小程序

C语言还可以做动画?相信读到这的你会有点不可思议。今天就让我们来编写一个让标题逐渐浮现的小程序吧


思路分析:
程序的思路是让标题逐渐出现,那我们就需要一行“***************”作为幕布,来遮掩我们的标题,然后把幕布的前后元素依次与标题的字符做交换,直至标题完全显现。
思路转化成代码:
我们需要两个等长的字符串,一个是我们的标题,一个是“幕布”,所以需要定义的变量就是两个字符串数组。由于需要使用数组,为了明确数组下标,我们先计算出数组元素个数,然后就可以确定左下标和右下标。再让两字符串最左和最右的元素分别交换。这样我们就打印出了这个动画的“每一帧”

然后我们介绍两个知识:一个是Sleep()函数,它的作用是让内容在屏幕上停留一段时间,括号内可以填数字代表停留的时间,单位是ms;另一个是系统命令system(“cls”),cls是clean screen,意思是清空屏幕。Sleep函数的头文件是windows.h,system函数的头文件是stdlib.h,使用它们前都得先引用头文件

我们在每次打印出“一帧”的语句后使用sleep函数来让它停留一段时间和system(“cls”)来清空屏幕,这样就实现了动画的效果
给出原码:

#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<stdlib.h>
int main()

	char arr1[] = "welcome to the world of C !";
	char arr2[] = "###########################";
	int left = 0;
	int right = strlen(arr1) - 1;
	while (left <= right)
	
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\\n", arr2);
		Sleep(200);
		system("cls");
		left++;
		right--;
	
	printf("%s\\n", arr2);
	return 0;


模拟密码输入:输密码小程序

我们每天需要登录游戏,登录社交软件,登录银行账户…生活中输入密码的情况无处不在。今天就让我们来编写一个输入密码的小程序吧


知识补充一:getchar和putchar

由于博主才疏学浅,在这里引用大佬的解释,真的是没有一句废话。我配了张图方便大家理解

getchar()
用于读取用户从键盘输入的单个字符,它有一个整型的返回值,当发生读取错误的时候,返回字符串EOF(整型值为-1),当读取正确的时候,它会返回用户从键盘输的第一个字符的ASCII码。
当程序调用getchar运行程序时,getchar就等着用户从按键输入,用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回车字符\\n也会被放在缓冲区中),当用户键入回车之后,getchar才开始从输入流中每次读入一个字符,输入的字符不只一个的时候,后续的getchar调用不会等待用户按键,而直接读取缓冲区中的字符,直到缓冲区中的字符读完之后,才等待用户按键。
getchar函数输入数字也按字符处理。
单个的getchar函数输入多于一个字符时,只接收第一个字符。
putchar()
向终端输出一个字符。其格式为putchar(ch),其中ch可以是被单引号(英文状态下)引起来的一个字符,可以是介于0~127之间的一个十进制整型数(包含0和127,超过127就不是ASCII码了),也可以是事先用char定义好的一个字符型变量。
当c为一个被单引号(英文状态下)引起来的字符时,输出该字符(该字符也可为转义字符 )。
当c为一个介于0~127(包括0及127)之间的十进制整型数时,它会被视为对应字符的ASCII代码,输出该ASCII代码对应的字符;
当c为一个事先用char定义好的字符型变量时,输出该变量所指向的字符。
当整型变量ch超出8位变量的范围时,ch则会变强制转化为8位变量(即取其低八位传过去输出),当为负数的时候,由于计算机存储负数是用补码表示的,所以传过去的二进制补码也被当做正数处理,也是取其低八位
getchar()和putchar()函数包含在头文件stdio.h中,使用时需先声明此头文件

原文连接:详解getchar和putchar

#include<stdio.h>
int main()

	int ch = 0;
	ch = getchar();
	putchar(ch);
	return 0;

运行效果就是:输入一个字符,按下回车,屏幕上会在下一行打印这个字符

  • 小问题解答:为什么ch是整型变量却可以接收字符?
    我们可以看一下getchar函数到底长啥样的,右键getchar,选择转到定义

    可以看到getchar()的返回值是int

使用代码清空缓冲区

在这里引出getchar的目的其实来学习编写一个非常常用的清空缓冲区的小程序:

	int tmp = 0;
	while ((tmp = getchar()) != '\\n')
	
		;
	//清空缓冲区里的所有字符

while后的条件是getchar获取的字符不是“换行/回车”时,就跳出循环,其他所有字符都执行循环
这个循环的循环体是一个“;”,这是啥?这表示的是一条空语句,也就是说我们啥都不干。所以这个循环的目的就是:getchar拉取缓冲区所有除了“回车”的字符,拉取到回车的时候跳出循环,由于回车是我们向缓冲区输入字符的终止命令,所以回车必然是缓冲区的最后一个字符。这样一来,就实现了清空缓冲区


知识补充二:字符串比较函数strcmp

使用函数需要引用头文件string.h
语法是

strcmp (字符串1,字符串2);

结果会返回整型值,
若字符串1和字符串2的每个字符都相等,则返回0;
若字符串1与字符串2不相等:
比较第一对不相等的字符的ASCII码值,谁的值大就代表哪个字符串大
若字符串1>字符串2,则返回正数;
若字符串1<字符串2,则返回负数。


代码实现模拟输入密码

我们来编写一个模拟我们日常输入密码的小程序
程序的功能是这样的:我们先自己创建密码,然后确认密码,然后输入密码。有三次输入密码的机会,一次正确就跳出循环,如果都输错了就没有机会了。
思路分析:
我们需要进行三个步骤,一个是创建密码,一个是确认密码,一个是登录时输入密码
思路转化成代码:
首先考虑需要创建的变量,我们需要创建三个字符数组来存储这三次键入的密码。每次输入密码后需要比较密码,需要用到刚刚讲过的字符串比较函数,需要用到判断结构,字符串相等就说明密码正确,不等即错误。仅有三次输入密码的机会,需要用到循环结构,在次数为三的时候跳出循环。确认密码失败的时候要结束程序,使用goto语句直接跳转到程序末尾。每次输入密码时,为了保证读取的就是当前输入的东西,要使用刚刚讲的技巧清空缓冲区的字符。
给出原码:

#include<stdio.h>
#include<string.h>
int main()

	char password[20] =  0 ;
	printf("请创建初始密码:\\n");
	scanf("%s", password);
	int tmp = 0;
	while ((tmp = getchar()) != '\\n')
	
		;
	//清空缓冲区里的所有字符
	printf("请确认密码:\\n");
	char password1[20] =  0 ;
	int i = 0;
	for (i = 0; i < 3; i++)
	
		scanf("%s", password1);
		if (strcmp(password, password1) == 0)
		
			printf("确认密码正确,已自动储存\\n");
			break;
		
		else
		
			printf("确认密码失败,请重新输入\\n");
		
	
	if (i == 3)
	
		printf("确认密码错误,退出程序\\n");
		goto end;
	
	int tmp1 = 0;
	while ((tmp1 = getchar()) != '\\n')
	
		;
	
	printf("请输入密码:\\n");
	char password2[20] =  0 ;
	int j = 0;
	for (j = 0; j < 3; j++)
	
		scanf("%s", password2);
		if (strcmp(password, password2) == 0)
		
			printf("登录成功!\\n");
			break;
		
		else
		
			printf("密码错误,请重新输入:\\n");
		
	
	if (i == 3)
	
		printf("三次密码均错误,退出程序\\n");
	
end:
	return 0;


人生第一款小游戏:猜数字小游戏


知识补充三:时间戳与生成随机数

如何在C语言中生成一个随机数呢?我们可以直接调用库函数rand(),它的头文件是stdlib.h
来看一下效果:

#include<stdio.h>
#include<stdlib.h>
int main()

	int a = rand();
	printf("%d", a);


随机数是不是就生成成功了呢?并不是,当我们多次运行程序时,结果是:



这是为什么呢?
原来C语言规定使用rand()函数前必须先调用函数srand()函数来设置随机数的生成器,查阅库函数表可知srand()有参数,是unsigned int(无符号整型),我们随便输一个100进去,来看一下效果:

#include<stdio.h>
#include<stdlib.h>
int main()

	srand(100);
	int a = rand();
	printf("%d", a);


结果是365,和上面的41不一样了
当我们重复运行时



还是365?怎么又是一个确定的值了呢?我们试着改变一下srand的参数,比如输个200

#include<stdio.h>
#include<stdlib.h>
int main()

	srand(200);
	int a = rand();
	printf("%d", a);


结果是691,也就是说生成的数值会随着srand参数的变化而变化
那我们现在就需要一个不受人为控制的,不断的变化的数,来充当srand()的参数,这样就可以生成随机数了
在此引入时间戳的概念。时间戳是我们系统的时间转换出来的一个数字
给出网页链接,大家可以看看自己系统的时间是怎么转换成一个常数的(其实是现在的时间相较于你这台计算机出生的时间的差值,可以说是你这台计算机的年龄)

在线时间戳转换

那怎么用时间戳呢?时间戳的函数是time(),返回值是一个有符号整型,为了配合srand函数我们使用一下强制类型转换;time()有参数,但是我们这里不需要用,所以参数写NULL;time()有头文件,名为time.h

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()

	srand((unsigned int)time(NULL));
	int a = rand();
	printf("%d", a);

看一下结果:



我们终于生成了随机数!


代码实现猜数字小游戏

游戏规则是这样的:
我们在程序中产生一个0-100之间的随机数,然后我们来不断猜它,猜大了就输出猜大了,猜小了就输出猜小了,最后看看谁猜的次数最少
思路分析:
我们刚刚已经知道了怎么产生随机数,现在要做的就只需要读取玩家输入的数字,和这个随机数不断作比较,我们再给出比较的结果提示就好了
思路转化成代码:
刚刚产生的随机数过大,我们需要的是生成1-100的随机数,我们将上面用时间戳生成的随机数对100取模,这样生成的随机数就是0-99了,然后再+1,这样范围就是1-100了:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()

	srand((unsigned int)time(NULL));
	int a = rand();
	int b = a % 100 + 1;
	printf("%d", b);



在主程序里,为了让我们的游戏更有模有样,我们来打印一个菜单,使用函数来写放在主程序外部,这样主程序比较清晰。打印出菜单以后我们需要赋予菜单功能,所以需要定义一个变量存储玩家输入的1/0的指令,判断是否游玩需要用到选择结构,不断游玩需要用到循环结构。然后整个游戏的程序我们再定义一个函数game放在主程序外部
在game函数中,变量定义上,我们需要用刚刚产生随机数的方法来产生随机数,需要一个guess变量来存储玩家输入的数,比较玩家的数和随机数的大小需要用到选择结构,给出提示需要在每次判断后打印出提示语句。再一次游玩中,还需要定义一个变量num来记录猜数字的次数,每次猜错都要+1,加上最终猜对的那一次,一共需要(猜错次数+1次),所以变量初始化为1.每一次游玩结束,为了使用户体验更好,还可以穿插system(“cls”)语句来清空屏幕。
给出原码:

#include<string.h>
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()

	printf("******************************\\n");
	printf("********   1: play    ********\\n");
	printf("******************************\\n");
	printf("******************************\\n");
	printf("********   0: exit    ********\\n");
	printf("******************************\\n");



void game()

	srand((unsigned int)time(NULL));
	int a = rand();
	int b = a % 100 + 1;
	int guess = 0;
	int num = 1;
	while (1)
	
		printf("请猜数字(1-100):");
		scanf("%d", &guess);
		if (guess < b)
		
			printf("猜小了\\n");
			num++;
		
		else if (guess > b)
		
			printf("猜大了\\n");
			num++;
		
		else
		
			printf("恭喜你,猜中啦!\\n");
			printf("你一共用了%d次\\n", num);
			break;
		
	

int main()

	int input = 0;
	menu();
	do
	
		printf("请选择是否玩耍(1/0):");
		scanf("%d", &input);
		switch (input)
		
		case 1:
			system("cls");
			printf("猜数字游戏开始!\\n");
			Sleep(2000);
			system("cls");
			game();

			break;
		case 0:
			Sleep(200);
			system("cls");
			printf("已退出游戏\\n");
			break;
		default:
			printf("选择错误,请重新选择\\n");
			break;

		
	 while (input);

下面是游玩截图




人生第一款“黑客”软件:强制关机小程序

知识补充四:调用系统命令行

我们的电脑(windows系统)有一个应用程序叫cmd——命令提示符。我们在这个提示符里输入一些指令,电脑就会自动的根据指令做出行动。
在程序中调用的语法是

system(“命令行内容”);

system函数的头文件是stdlib.h
关机的命令行是shutdown -s -t 60
shutdown -s是设置关机,-t是倒计时,60是60秒
取消关机的命令行是shutdown -a

代码实现强制关机小程序

这个程序的要求是可以让电脑自动进入倒计时为一分钟的关机程序,如果用户输入“我是猪”,就可以结束关机
思路分析:
我们既然直接进入关机,那么就直接调用系统命令行输入命令即可。然后再用选择语句判断一下,如果用户很乖,确实输入的是“我是猪”,那就再次调用系统命令行输入终止关机的命令
思路转化成代码:
变量定义部分只需要一个变量来存储用户输入的内容,这个内容是汉字,我们需要使用字符串数组,数组长度给一个大一点的数(20就够了)。判断字符串是否是“我是猪”需要用到字符串比较函数strcmp()。如果用户不输入“我是猪”,就用goto跳转到scanf语句继续接受内容。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()

	char input[20] =  0 ;
	system("shutdown -s -t 100");
	printf("同学,你的电脑将在100秒内关机\\n");
again:
	printf("如果你输入:我是猪,就取消关机\\n");
	scanf("%s", input);
	if (strcmp(input,"我是猪") == 0)
	
		system("shutdown -a");
	
	else
	
		printf("不乖的话你的电脑就要关机了哦");
		goto again;
	
	return 0;

同学们可以自己和好朋友之间玩玩,也可以自己修改强制输入的内容。但是一定不要过火,分寸很重要哦!

以上是关于编程DIY一.几个有趣的小程序的主要内容,如果未能解决你的问题,请参考以下文章

编程DIY一.几个有趣的小程序

简单有趣的小项目,用Python六行代码分解GIF美女动图,初学者的福音

几个C#编程的小技巧

分享几个有趣的内容

编程,很有趣,也很催泪

中关村-DIY之主流笔记类工具比较