系列前言
兴趣是最好的老师。本系列介绍一些非常容易上手编写的小程序,这些小程序给博主的学习之路带来了许多欢乐,特记录分享!
编程语言:C语言
编程环境:Visual Studio 2019
本篇预备知识
C语言还可以做动画?相信读到这的你会有点不可思议。今天就让我们来编写一个让标题逐渐浮现的小程序吧
思路分析:
程序的思路是让标题逐渐出现,那我们就需要一行“***************”作为幕布,来遮掩我们的标题,然后把幕布的前后元素依次与标题的字符做交换,直至标题完全显现。
思路转化成代码:
我们需要两个等长的字符串,一个是我们的标题,一个是“幕布”,所以需要定义的变量就是两个字符串数组。由于需要使用数组,为了明确数组下标,我们先计算出数组元素个数,然后就可以确定左下标和右下标。再让两字符串最左和最右的元素分别交换。这样我们就打印出了这个动画的“每一帧”
然后我们介绍两个知识:一个是Sleep()函数,它的作用是让内容在屏幕上停留一段时间,括号内可以填数字代表停留的时间,单位是ms;另一个是系统命令system(“cls”),cls是clean screen,意思是清空屏幕。Sleep函数的头文件是windows.h,system函数的头文件是stdlib.h,使用它们前都得先引用头文件
我们在每次打印出“一帧”的语句后使用sleep函数来让它停留一段时间和system(“cls”)来清空屏幕,这样就实现了动画的效果
给出原码:
#include
#include
#include
#include
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()
用于读取用户从键盘输入的单个字符,它有一个整型的返回值,当发生读取错误的时候,返回字符串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
int main()
{
int ch = 0;
ch = getchar();
putchar(ch);
return 0;
}
运行效果就是:输入一个字符,按下回车,屏幕上会在下一行打印这个字符
在这里引出getchar的目的其实来学习编写一个非常常用的清空缓冲区的小程序:
int tmp = 0;
while ((tmp = getchar()) != '\n')
{
;
}//清空缓冲区里的所有字符
while后的条件是getchar获取的字符不是“换行/回车”时,就跳出循环,其他所有字符都执行循环
这个循环的循环体是一个“;”,这是啥?这表示的是一条空语句,也就是说我们啥都不干。所以这个循环的目的就是:getchar拉取缓冲区所有除了“回车”的字符,拉取到回车的时候跳出循环,由于回车是我们向缓冲区输入字符的终止命令,所以回车必然是缓冲区的最后一个字符。这样一来,就实现了清空缓冲区
使用函数需要引用头文件string.h
语法是
strcmp (字符串1,字符串2);
结果会返回整型值,
若字符串1和字符串2的每个字符都相等,则返回0;
若字符串1与字符串2不相等:
比较第一对不相等的字符的ASCII码值,谁的值大就代表哪个字符串大
若字符串1>字符串2,则返回正数;
若字符串1<字符串2,则返回负数。
我们来编写一个模拟我们日常输入密码的小程序
程序的功能是这样的:我们先自己创建密码,然后确认密码,然后输入密码。有三次输入密码的机会,一次正确就跳出循环,如果都输错了就没有机会了。
思路分析:
我们需要进行三个步骤,一个是创建密码,一个是确认密码,一个是登录时输入密码
思路转化成代码:
首先考虑需要创建的变量,我们需要创建三个字符数组来存储这三次键入的密码。每次输入密码后需要比较密码,需要用到刚刚讲过的字符串比较函数,需要用到判断结构,字符串相等就说明密码正确,不等即错误。仅有三次输入密码的机会,需要用到循环结构,在次数为三的时候跳出循环。确认密码失败的时候要结束程序,使用goto语句直接跳转到程序末尾。每次输入密码时,为了保证读取的就是当前输入的东西,要使用刚刚讲的技巧清空缓冲区的字符。
给出原码:
#include
#include
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
#include
int main()
{
int a = rand();
printf("%d", a);
}
随机数是不是就生成成功了呢?并不是,当我们多次运行程序时,结果是:
这是为什么呢?
原来C语言规定使用rand()函数前必须先调用函数srand()函数来设置随机数的生成器,查阅库函数表可知srand()有参数,是unsigned int(无符号整型),我们随便输一个100进去,来看一下效果:
#include
#include
int main()
{
srand(100);
int a = rand();
printf("%d", a);
}
结果是365,和上面的41不一样了
当我们重复运行时
还是365?怎么又是一个确定的值了呢?我们试着改变一下srand的参数,比如输个200
#include
#include
int main()
{
srand(200);
int a = rand();
printf("%d", a);
}
结果是691,也就是说生成的数值会随着srand参数的变化而变化
那我们现在就需要一个不受人为控制的,不断的变化的数,来充当srand()的参数,这样就可以生成随机数了
在此引入时间戳的概念。时间戳是我们系统的时间转换出来的一个数字
给出网页链接,大家可以看看自己系统的时间是怎么转换成一个常数的(其实是现在的时间相较于你这台计算机出生的时间的差值,可以说是你这台计算机的年龄)
那怎么用时间戳呢?时间戳的函数是time(),返回值是一个有符号整型,为了配合srand函数我们使用一下强制类型转换;time()有参数,但是我们这里不需要用,所以参数写NULL;time()有头文件,名为time.h
#include
#include
#include
int main()
{
srand((unsigned int)time(NULL));
int a = rand();
printf("%d", a);
}
看一下结果:
我们终于生成了随机数!
游戏规则是这样的:
我们在程序中产生一个0-100之间的随机数,然后我们来不断猜它,猜大了就输出猜大了,猜小了就输出猜小了,最后看看谁猜的次数最少
思路分析:
我们刚刚已经知道了怎么产生随机数,现在要做的就只需要读取玩家输入的数字,和这个随机数不断作比较,我们再给出比较的结果提示就好了
思路转化成代码:
刚刚产生的随机数过大,我们需要的是生成1-100的随机数,我们将上面用时间戳生成的随机数对100取模,这样生成的随机数就是0-99了,然后再+1,这样范围就是1-100了:
#include
#include
#include
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
#include
#include
#include
#include
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
#include
#include
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;
}
同学们可以自己和好朋友之间玩玩,也可以自己修改强制输入的内容。但是一定不要过火,分寸很重要哦!