前言
欢迎来到我的C语言的语法博客,本篇致力于帮助同学们快速上手熟练C语言的逻辑结构使用,并实现一个迭代版的猜数字游戏。
不必担心,不会涉及过多C语言后面的知识,我们目的就是练习。
建议同学们任读一本C语言书籍的这部分内容,再看此篇博客,课本有的用不着我说,我谈我的经验。
近日,学习Java想写相关博客,发现与C高度相似(重点写差别部分),为此又写一篇Java的分支循环没有意义,不如完善此篇。java部分用紫色标注,不了解Java无视即可。
学习目的:
1.掌握 rand函数,srand函数 ,time函数,会学会生成固定范围的随机数。
2.熟练if……else ,switch case ,break,continue;while ,do while ,for这些关键字的适用。
适用人群:
初学C语言的小萌新。
注意:为了代码简洁,配有注释;代码简单易懂,人性化;头文件省略,请自行补上。
赠君一席话:你的时间有限,忽视别人对我们的指点,谁在乎?只有我们自己,记住往后的人生,为自己而活,别为他人而活。
我来这个世界,世界是为了我而服务;万法注我,我心即路。
猜数字游戏实现的结构分析
要素:一个要猜的数字+玩家输入数字。
int main()
{
int input = 0;
int goal = 7;//任写一个要猜数字
printf("请输入一个数字\n");
printf(">");
scanf("%d", &input);
return 0;
}
玩家输入的数字跟要猜的数字,无非就是三种可能,即猜大了,猜小了,猜对了;
if(条件表达式)
表达式1;
对于C语言来说:0表示假,非0表示真。if结构,条件表达式结果为真,则执行后面的语句,否则只判断条件,不执行。
Java:if(),括号里面的表达式必须为布尔表达式,即表达式结果必须为true或者false。
Java中true不表示1,false不表示0,它们是单独的boolean类型。
对比C语言,宏定义明示常量(编译时替换),true false分别表示 1 , 0;true和false本质是int类型。
#define false 0 #define true 1
简而言之,Java判断真假只能是true false,C语言中本质用整型0,非0来辨别真假。
这里有三种情况(猜大,猜小,猜对)
if(条件表达式)
{
语句1;
}else{
语句2;
}
显然if……else的分支结构也不行,用来表示两种完全相反的情况。
if(条件表达式1)
{
语句1;
}else if(条件表达式2){
语句2;
}else{
语句3;
}
这种结构,中间可以插入无数条else if分支(只要你愿意),三种情况就可以表示了。
下面加入if_else if_else语句;
int main() { int input = 0; int goal = 7; printf("请输入一个你要猜的数字\n"); printf(">"); scanf("%d", &input); if (input > goal) { printf("猜大了\n"); }else if (input == goal) { printf("猜对了\n"); }else { printf("猜小了\n"); } return 0; }
这种写法,自上而下先判断if语句,再判断else if语句,最后再考虑执行else里语句。
中间判断成立了就不再进行后续的判断。
讲先后,有顺序!
Java的if else完全一样。
很显然,我们只能猜一次,为了能保证猜对正确答案,多猜几次,写个while循环实现。
while(条件表达式)
{
语句1;
语句2;
……
}
Java中while小括号内必须为布尔表达式。
猜对答案就终止循环了,表达式怎么写呢?
如果你不清楚表达式具体怎么写,先写while(1),这么写循环会一直执行,这个时候借助break就行了,当数字猜对了就用break结束循环。
int main() { int input = 0; int goal = 7; printf("请输入一个你要猜的数字\n"); while (1) { printf(">");//输入必须包括在循环内,否则死循环。 scanf("%d", &input); if (input > goal) { printf("猜大了\n"); } else if (input == goal) { printf("猜对了\n"); break; } else { printf("猜小了\n"); } } return 0; }
下面总结一下:
1.while特点 先判断后执行;
特别适用于一开始循环条件难找,可以先进循环,满足条件再用break打破循环。
2.break特点 强制打破循环
补充:针对while循环 for循环 do……while循环,和分支中的switch。请记住,break只能打破当前的上述4种结构。请注意它们自身或者互相嵌套的适用。
break只能在循环和开关(switch)使用,否则编译器会告诉你。
3.while和break对于Java也一样,注意表达式是布尔表达式即可。
我们要设计一个初始界面,控制游戏的开始进行,先把上面的的猜数字游戏封装成一个函数game;像下面一样操作即可。
void game() { int input = 0; int goal = 7; printf("请输入一个你要猜的数字\n"); while (1) { printf(">"); scanf("%d", &input); if (input > goal) { printf("猜大了\n"); } else if (input == goal) { printf("猜对了\n"); break; } else { printf("猜小了\n"); } } }
下面设置一个菜单函数,方便玩家选择
void menu() { //连续用printf打印即可。 printf("*****************\n"); printf("**** 1.-> play **\n"); printf("**** 0.-> exit **\n"); printf("*****************\n"); }
初始界面打印菜单,供玩家选择;
玩家选择上面菜单的1或者0选择play或者exit。这种只涉及整数的分支结构,就用switch case的分支结构。
switch(整型表达式)
{
case 常量1:
相关语句;
case 常量2:
相关语句;
…………
default:
相关语句;
}
switch case的注意事项有点多,请先记住这个结构,结合下面代码。
int main() { int input = 0; menu();//菜单函数调用 printf("请输入一个数字\n"); printf(">"); scanf("%d", &input); switch (input) { case 1: game();//玩猜数字的游戏 break; case 0: printf("退出游戏\n"); exit(0);//程序正常结束。 default: printf("非法输入!\n"); break; } return 0; }
简单梳理一下switch case:
1.switch后面紧跟着小括号(),小括号里面是整型表达式(表达式结果为整型),或者整型常量,整型变量,字符类型。
对于Java:switch的小括号内必须是 小于等于4字节的整数类型,或者字符类型,不能是布尔表达式。
列举一下:byte short int char ,注意long这种整型不行。另外字符串类型和枚举类型也可以。
2.case,case后面跟着数字或字符常量值,多个case后面不能跟着相同的常量值。
3.case一般后面跟着break,因为case决定了入口,进去了会一直向下执行。如果单独实现某个分支语句记得加break。break能跳出当前的switch,但是对if……else没有作用。
4.default相当于if else中的else的地位,若没有case满足,则default就是入口。
2,3,4条Java完全相同。
上面的写法玩家只能选择一次(玩或者退出),我们再加上循环,可以反复玩,再由玩家决定是否退出。
这里我们希望它先执行一次,正好do while循环满足先执行再判断。
do
{
语句1;
语句2;
…………;
}while(条件表达式/布尔表达式);
这种循环会先进入执行一次,再做判断要不要继续执行!
这里使用system("cls");//清理了控制台,需要引windows.h的头文件!
system("pause"),暂停观察结果,头文件同上。
int main() { int input = 0; do { menu();//菜单函数调用 printf("请输入一个数字\n"); printf(">"); scanf("%d", &input); switch (input) { case 1: game(); system("pause");//暂停观看结果。 system("cls");//完成一次游戏清理一下控制台 break; case 0: printf("退出游戏\n"); exit(0); default: printf("非法输入!\n"); } } while (input); return 0; }
do while循环的特点和易错点分析:
1.先循环后判断
2.while(表达式)后面要跟分号;
这里没有涉及for循环,continue.请同学们自行多加练习。
好了,前戏已经结束了,生成随机数的问题没解决。
请重点观看下面的内容。
一、生成随机数相关函数介绍
1.1前言
C语言相关知识:
1.顺序,分支,循环结构的使用。
学完指针重新回顾此篇吧。
1.2rand函数
头文件:stdlib.h
int rand (void);
功能:生成随机数,随机数范围0~32767(看编译器) ,32767==2^15-1
返回值:返回一个伪随机数。
int rand (void);//函数原型
什么是伪随机数?试着多次运行下列程序,程序结果都是一样,真随机结果都是无法预测的。
伪随机数不是真正的随机数,是通过某种算法⽣成的随机数。
事实上,rand函数基于一个种子算法进行某种运算得到的。 之所以前⾯每次运⾏程序产⽣的随机数序列是⼀样的,那是因为rand函数⽣成随机数的默认种⼦是1,如果要让每次结果不一样,我们就要每次运行时都要改变这个种子,接下来我们介绍srand函数。
#include<stdio.h>
#include<stdlib.h>//
int main()
{
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
1.3srand函数:详情看下
头文件:stdlib.h(和rand函数头文件相同)
void srand (unsigned int seed);
参数类型:unsigned int 无符号整数
返回类型为 空类型。
随机值在调用rand1函数之前先调用srand改变种子,通过 srand 函数的参数seed来设置rand函数⽣成随机数的时候的种⼦,只要种⼦在变化,每次⽣成的随机数序列也就变化起来了。但是产生一个随机数需要输入另外一个随机数,这很矛盾。这里的种子要有常量改成变量,且不需要我们认为输入。接下来我们用程序运行时间(稍后我们会介绍一个函数)作为种子,程序运行时间是不断变化的,我们就不用手动输入随机数,因此每次运行结果就不同了。
1.4time函数
头文件:time.h
C语言中有一函数为 time,就可以获得这个时间。函数原型如下:
time_t time (time_t* timer);
返回类型
time 函数会返回当前的⽇历时间,其实返回的是1970年1⽉1⽇0时0分0秒到现在程序运⾏时间之间的差值,单位是秒。因此每次运行程序时间不同,所以生成的随机数不同。
time_t我们用vs2022选中time_t按键盘F12转到定义。
typedef是类型重命名的关键字,简单理解给这个数据类型起了一个新名。
typedef __time64_t time_t;
typedef __int64 __time64_t;
所以time_t是一位64位的整型数据类型。
函数参数
time函数的参数 timer 如果是⾮NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存 中带回去。
我们只需知道,如果 timer 是NULL(空指针),就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。
时间戳(Unix timestamp)转换工具 - 在线工具 (tool.lu)
#ifndef NULL//空指针的定义
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
简而言之,我们只是希望这个函数返回时间戳,就可以简单写成如下,
time(NULL);//调⽤time函数返回时间戳,这⾥没有接收返回值
1.5设置随机数范围
由于随机数在给定范围内任意,我们人为指定范围就要通过下面的运算了。
%取余操作符,我们这里讨论a,b均为正整数的情况,不难看出a%b(除数不能为0)的范围是[0,b-1]。
所以得到0~100的范围可以是rand%(101)结果必然是[0,100]。
因此,若(a<b),则a+rand()%(b-a+1)表示[a,b]的范围。
二、猜数字游戏
2.1初步实现
#include<stdio.h>
#include<windows.h>
#include<time.h>
void menu()
{
printf("*****************\n");
printf("**** 1.-> play **\n");
printf("**** 0.-> exit **\n");
printf("*****************\n");
}
void game()
{
int input = 0;
srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
int goal = rand()%101;//生成0~100的随机数
printf("请输入你要猜的一个数字\n");
while (1)
{
printf(">");
scanf("%d", &input);
if (input > goal)
{
printf("猜大了\n");
}
else if (input == goal)
{
printf("猜对了\n");
break;
}
else
{
printf("猜小了\n");
}
}
}
int main()
{
int input = 0;
do
{
menu();//菜单函数调用
printf("请输入一个数字\n");
printf(">");
scanf("%d", &input);
switch (input)
{
case 1:
game();
system("pause");//暂停观察结果。
system("cls");//完成一次游戏清理一下控制台
break;
case 0:
printf("退出游戏\n");
exit(0);
default:
printf("非法输入!\n");
}
} while (input);
return 0;
}
过去的版本
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void game()
{
int r = rand() % 100 + 1;
int guess = 0;
while (1)
{
printf("请猜数字>:");
scanf("%d", &guess);
if (guess < r)
{
printf("猜小了\n");
}
else if (guess > r)
{
printf("猜大了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
}
void menu()
{
printf("***********************\n");
printf("****** 1. play ******\n");
printf("****** 0. exit ******\n");
printf("***********************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
2.2优化游戏内容
下面我们来尝试优化游戏内容:
作者做出了如下调整:
1.调整了函数名和变量名,增强了可读性。
2.修改了菜单,使其变得更加美观。
3.检查了输入的有效性。
4.打印信息修改为英文,注释为中文,方便阅读代码。
限定猜的次数
#include<stdio.h>
#include<windows.h>
#include<time.h>
void PrintMenu()
{
printf("*************************\n");
printf("**Guess the number game**\n");
printf("** 1.-> play **\n");
printf("** 0.-> exit **\n");
printf("*************************\n");
}
void PlayGame()
{
int guess = 0;
int total_count = 10;//合计猜的总的次数
int now_count = 0;//当前使用的次数
srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
int goal = rand()%101;//生成0~100的随机数
printf("Choose an integer number(0~100) ,please.\n");
while (1)
{
printf(">");
if (1 != scanf("%d", &guess))//限定了guess的范围0~100。
{
while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
printf("Invalid input. Please enter an integer.\n");
continue;//到下一次循环重新输入!
}
if (guess < 0 || guess>100)
{
printf("Range : from 0 to 100\n");//范围不符合要求。
continue;//到下一次循环重新输入!
}
if (guess > goal)
{
printf("Too high , try a smaller number.\n");
}
else if (guess == goal)
{
printf("That's right!\n");
break;
}
else
{
printf("Too low , try a higher number.\n");
}
now_count++;
printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
if (now_count == total_count)//失败了的情况
{
printf("------------------------------------------\n");
printf("You failed. The correct answer is %d\n", goal);
}
}
}
int main()
{
int input = 0;
do
{
PrintMenu();//菜单函数调用
printf("Please choose.\n");
printf("1 -> YES\n");
printf("0 -> NO \n");
printf(">");
scanf("%d", &input);
switch (input)
{
case 1:
PlayGame();
system("pause");//暂停观察结果。
system("cls");//完成一次游戏清理一下控制台
break;
case 0:
printf("See you again!\n");
exit(0);
default:
printf("Input error,pleae try again!\n");
system("pause");//暂停观察结果。
system("cls");
}
} while (input);
return 0;
}
显示输入记录
这里用一个简单的一维数组存储每次输入的整数。
#define MAX_Count 10//定义了一个宏,数组的元素个数
#include<stdio.h>
#include<windows.h>
#include<time.h>
#define MAX_Count 10//定义了一个宏
void PrintMenu()
{
printf("*************************\n");
printf("**Guess the number game**\n");
printf("** 1.-> play **\n");
printf("** 0.-> exit **\n");
printf("*************************\n");
}
void PlayGame()
{
int guess = 0;
int total_count = 10;//合计的总的次数
int now_count = 0;//当前使用的次数
int arr[MAX_Count];//定义一个元素个数为10的数组。
srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
int goal = rand()%101;//生成0~100的随机数
printf("Choose an integer number(0~100) ,please.\n");
while (1)
{
printf(">");
if (1 != scanf("%d", &guess))//限定了guess的范围0~100。
{
while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
printf("Invalid input. Please enter an integer.\n");
continue;//到下一次循环重新输入!
}
if (guess < 0 || guess>100)
{
printf("Range : from 0 to 100\n");//范围不符合要求。
continue;//到下一次循环重新输入!
}
arr[now_count] = guess;//存储有效的数据。
if (guess > goal)
{
printf("Too high , try a smaller number.\n");
}
else if (guess == goal)
{
printf("That's right!\n");
break;
}
else
{
printf("Too low , try a higher number.\n");
}
now_count++;
printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
if (now_count == total_count)//失败了的情况
{
printf("------------------------------------------\n");
printf("You failed. The correct answer is %d\n", goal);
break;
}
}
//打印输入的信息
printf("-------Input Record-------\n");
for (int i = 0; i < now_count; i++)
{ //计算猜的数与实际的差值
printf("%2d :%4d %4d\n", i + 1, arr[i], abs(arr[i] - goal));//abs绝对值函数,stdlib.h头文件上。
}
}
int main()
{
int input = 0;
do
{
PrintMenu();//菜单函数调用
printf("Please choose.\n");
printf("1 -> YES\n");
printf("0 -> NO \n");
printf(">");
scanf("%d", &input);
switch (input)
{
case 1:
PlayGame();
system("pause");//暂停观察结果。
system("cls");//完成一次游戏清理一下控制台
break;
case 0:
printf("See you again!\n");
exit(0);
default:
printf("Input error,pleae try again!\n");
system("pause");//暂停观察结果。
system("cls");
}
} while (input);
return 0;
}
划分难度等级
可以说是最终版本了,分难度等级。自行阅读。
#include<stdio.h>
#include<windows.h>
#include<time.h>
#define MAX_Count 10//定义了一个宏
void PrintMenu()
{
printf("*************************\n");
printf("**Guess the number game**\n");
printf("** 1.-> play **\n");
printf("** 0.-> exit **\n");
printf("*************************\n");
}
void PlayGame()
{
srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
int input = 0;//选择难度
int guess = 0;//要猜的值
int goal = 0;//随机值
int max = 0;//根据难度确定右值
int total_count = 10;//合计的总的次数
int now_count = 0;//当前使用的次数
int arr[MAX_Count];//定义一个元素个数为10的数组。
//Random难度的准备
int left = 0;//左右值的初始化
int right = 0;
do {
printf("Please choose your difficulty level\n");
printf("1.->Practice: 0~9\n");//新手入手
printf("2.->Easy: 0~99\n");//初级
printf("3.->Intermediate:0~999\n");//中级
printf("4.->Advanced: 0~9999\n");//高级
printf("5.->Random: ?~?\n");//随机难度
if (1 != scanf("%d", &input))
{
while (getchar() != '\n');//清理缓冲区
printf("Invalid input. Please enter an integer.\n");
continue;//到下一次循环重新输入!
}
while (getchar() != '\n');
switch (input)
{
case 1:
goal = rand() % 10;//生成0~9的随机数
max = 9;
goto start;//跳转
case 2:
goal = rand() % 100;//生成0~99的随机数
max = 99;
goto start;
case 3:
goal = rand() % 1000;//生成0~999的随机数
max = 999;
goto start;
case 4:
goal = rand() % 10000;//生成0~9999的随机数
max = 9999;
goto start;
case 5:
left = rand();//左值
right = rand();//右值
if (left > right)
{
int tmp = left;
left = right;
right = tmp;
}
max = -1;//进入随机难度的标志
goal = left + rand() % (right-left)+1;//范围(left---right);
goto random;
default:
printf("Input error,pleae try again!\n");
}
} while (1);
start :
printf("Choose an integer number(0~%d) ,please.\n",max);
while (1)
{
printf(">");
if (1 != scanf("%d", &guess))
{
while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
printf("Invalid input. Please enter an integer.\n");
continue;//到下一次循环重新输入!
}
while (getchar() != '\n');
if (guess < 0 || guess>max)
{
printf("Range : from 0 to %d\n", max);//范围不符合要求。
continue;//到下一次循环重新输入!
}
arr[now_count] = guess;//存储有效的数据。
if (guess > goal)
{
printf("Too high , try a smaller number.\n");
}
else if (guess == goal)
{
printf("That's right!\n");
break;
}
else
{
printf("Too low , try a higher number.\n");
}
now_count++;
printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
printf("------------------------------------------\n");
if (now_count == total_count)//失败了的情况
{
printf("------------------------------------------\n");
printf("You failed. The correct answer is %d\n", goal);
break;
}
}
if (max == -1)
{
random:
printf("Choose an integer number.(? ~ ?)\n");
while (1)
{
printf(">");
if (1 != scanf("%d", &guess))
{
while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
printf("Invalid input. Please enter an integer.\n");
continue;
}
if (guess < 0)
{
printf("Range : at least >= 0 \n");//范围不符合要求。
continue;//到下一次循环重新输入!
}
arr[now_count] = guess;//存储有效的数据。
if (guess > goal)
{
printf("Too high , try a smaller number.\n");
}
else if (guess == goal)
{
printf("That's right!\n");
break;
}
else
{
printf("Too low , try a higher number.\n");
}
now_count++;
printf("You still have %2d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
printf("------------------------------------------\n");
if (now_count == total_count)//失败了的情况
{
printf("------------------------------------------\n");
printf("You failed. The correct answer is %d\n", goal);
break;
}
}
}
//打印输入的信息
printf("-------Input Record-------\n");
for (int i = 0; i < now_count; i++)
{ //计算猜的数与实际的差值
printf("%2d :%5d %5d\n", i + 1, arr[i], abs(arr[i] - goal));//abs绝对值函数,stdlib.h头文件上。
}
}
int main()
{
int input = 0;
do
{
PrintMenu();//菜单函数调用
printf("Please choose.\n");
printf("1 -> YES\n");
printf("0 -> NO \n");
printf(">");
if (1 != scanf("%d", &input))
{
while (getchar() != '\n');//清理缓冲区
printf("Invalid input. Please enter an integer.\n");
system("cls");
continue;//到下一次循环重新输入!
}
while (getchar() != '\n');//清理缓冲区
switch (input)
{
case 1:
PlayGame();
system("pause");//暂停观察结果。
system("cls");//完成一次游戏清理一下控制台
break;
case 0:
printf("See you again!\n");
exit(0);
default:
printf("Input error,pleae try again!\n");
system("pause");//暂停观察结果。
system("cls");
}
} while (input);
return 0;
}
计时(最终版本)
尝试学习time函数如何计算运行时间的差值部分吧
#include<stdio.h>
#include<windows.h>
#include<time.h>
#define MAX_Count 10//定义了一个宏
void PrintMenu()
{
printf("*************************\n");
printf("**Guess the number game**\n");
printf("** 1.-> play **\n");
printf("** 0.-> exit **\n");
printf("*************************\n");
}
void PlayGame()
{
srand((unsigned)time(NULL)); // 每次程序运行生成不同的种子。
int input = 0;//选择难度
int guess = 0;//要猜的值
int goal = 0;//随机值
int max = 0;//根据难度确定右值
int total_count = 10;//合计的总的次数
int now_count = 0;//当前使用的次数
int arr[MAX_Count];//定义一个元素个数为10的数组。
//Random难度的准备
int left = 0;//左右值的初始化
int right = 0;
time_t startTime, endTime;
double elapsedTime;
do {
printf("Please choose your difficulty level\n");
printf("1.->Practice: 0~9\n");//新手入手
printf("2.->Easy: 0~99\n");//初级
printf("3.->Intermediate:0~999\n");//中级
printf("4.->Advanced: 0~9999\n");//高级
printf("5.->Random: ?~?\n");//随机难度
printf(">");
if (1 != scanf("%d", &input))
{
while (getchar() != '\n');//清理缓冲区
printf("Invalid input. Please enter an integer.\n");
continue;//到下一次循环重新输入!
}
while (getchar() != '\n');
switch (input)
{
case 1:
goal = rand() % 10;//生成0~9的随机数
max = 9;
goto start;//跳转
case 2:
goal = rand() % 100;//生成0~99的随机数
max = 99;
goto start;
case 3:
goal = rand() % 1000;//生成0~999的随机数
max = 999;
goto start;
case 4:
goal = rand() % 10000;//生成0~9999的随机数
max = 9999;
goto start;
case 5:
left = rand();//左值
right = rand();//右值
if (left > right)
{
int tmp = left;
left = right;
right = tmp;
}
max = -1;//进入随机难度的标志
goal = left + rand() % (right-left)+1;//范围(left---right);
goto random;
default:
printf("Input error,pleae try again!\n");
}
} while (1);
start :
printf("Choose an integer number(0~%d) ,please.\n",max);
time(&startTime);
while (1)
{
printf(">");
if (1 != scanf("%d", &guess))
{
while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
printf("Invalid input. Please enter an integer.\n");
continue;//到下一次循环重新输入!
}
while (getchar() != '\n');
if (guess < 0 || guess>max)
{
printf("Range : from 0 to %d\n", max);//范围不符合要求。
continue;//到下一次循环重新输入!
}
arr[now_count] = guess;//存储有效的数据。
if (guess > goal)
{
printf("Too high , try a smaller number.\n");
}
else if (guess == goal)
{
printf("That's right!\n");
break;
}
else
{
printf("Too low , try a higher number.\n");
}
now_count++;
printf("You still have %d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
printf("------------------------------------------\n");
if (now_count == total_count)//失败了的情况
{
printf("------------------------------------------\n");
printf("You failed. The correct answer is %d\n", goal);
break;
}
}
if (max == -1)
{
random:
printf("Choose an integer number.(? ~ ?)\n");
while (1)
{
printf(">");
if (1 != scanf("%d", &guess))
{
while (getchar() != '\n');//清空缓冲区,清除其它非法字符。
printf("Invalid input. Please enter an integer.\n");
continue;
}
if (guess < 0)
{
printf("Range : at least >= 0 \n");//范围不符合要求。
continue;//到下一次循环重新输入!
}
arr[now_count] = guess;//存储有效的数据。
if (guess > goal)
{
printf("Too high , try a smaller number.\n");
}
else if (guess == goal)
{
printf("That's right!\n");
break;
}
else
{
printf("Too low , try a higher number.\n");
}
now_count++;
printf("You still have %2d chance.\n", total_count - now_count);//提醒一下玩家还有多少次机会。
printf("------------------------------------------\n");
if (now_count == total_count)//失败了的情况
{
printf("------------------------------------------\n");
printf("You failed. The correct answer is %d\n", goal);
break;
}
}
}
time(&endTime);
elapsedTime = difftime(endTime, startTime);
printf("It took a total of %.3lf seconds.\n",elapsedTime);
//打印输入的信息
printf("-------Input Record-------\n");
for (int i = 0; i < now_count; i++)
{ //计算猜的数与实际的差值
printf("%2d :%5d %5d\n", i + 1, arr[i], abs(arr[i] - goal));//abs绝对值函数,stdlib.h头文件上。
}
}
int main()
{
int input = 0;
do
{
PrintMenu();//菜单函数调用
printf("Please choose.\n");
printf("1 -> YES\n");
printf("0 -> NO \n");
printf(">");
if (1 != scanf("%d", &input))
{
while (getchar() != '\n');//清理缓冲区
printf("Invalid input. Please enter an integer.\n");
system("cls");
continue;//到下一次循环重新输入!
}
while (getchar() != '\n');//清理缓冲区
switch (input)
{
case 1:
PlayGame();
system("pause");//暂停观察结果。
system("cls");//完成一次游戏清理一下控制台
break;
case 0:
printf("See you again!\n");
exit(0);
default:
printf("Input error,pleae try again!\n");
system("pause");//暂停观察结果。
system("cls");
}
} while (input);
return 0;
}
图形库(自学,这里只是个标题)
以下为过去的版本,可以看看。
我们可以自己丰富一下这个游戏。方便起见,函数原型和函数定义均在同一源文件上。读者可自行丰富改进代码。
#define _CRT_SECURE_NO_WARNINGS 1//vs2022,scanf函数不安全要使用必须加上这行代码。
#include<stdio.h>//调用printf,scanf要引用的头文件
#include<stdlib.h>//调用rand,srand的头文件
#include<time.h>//调用time的头文件
void menu(void);//游戏菜单函数声明
void game(void);//猜数字游戏内部函数
int main()
{
int input;
//选择开始游戏,退出游戏的变量。
do
{
menu();//游戏菜单,具体看函数定义
printf("请输入一个数字:\n");
printf("1->play\n");
printf("0->exit\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();//游戏内容的具体实现
break;
case 0:
printf("游戏愉快!\n");
break;
default:printf("选择错误,重新选择!\n");
break;
}
} while (input);
return 0;
}
void menu(void)//不需要传参和返回,只需要该函数打印游戏开始界面即可
{
printf("***********************\n");
printf("****** 1. play ******\n");
printf("****** 0. exit ******\n");
printf("***********************\n");
return;
}
void game(void)
{
int guess;
srand((unsigned int)time(NULL));
printf("请问是否需要自定义难度(自定义范围+次数限制):\n");
printf("1->YES\n");
printf("0->NO\n");
int n = 0;
int ret;
int a, b;
unsigned int cnt = 1;//默认难度始终为一
int flag = 1;//是否需要自定义难度的标志。cnt变量可以赋值更改了,变为while循环次数限制的变量
scanf("%d", &n);
switch (n)
{
case 1:
{
do
{
error:
printf("请输入两个数表示你要猜的数字范围(注意右边数大于左边数):");
scanf("%d%d", &a, &b);
if (a > b)
{
printf("非法输入,请遵守规则!\n");
goto error;
}
printf("请输入限制的次数:\n");
scanf("%u", &cnt);
flag = 0;
ret = a + rand() % (b - a + 1);
if (a >= b)
printf("输入错误,请重新选择\n");
} while (a >= b);
break;
}
default:
printf("输入错误,默认开启正常难度\n");
case 0:
printf("注意:默认范围是0~100,无次数限制\n");
ret = rand() % 100 + 1;
}
while (cnt)
{
if (flag == 0)
{
printf("你还有%2u次机会,", cnt);
}
printf("请输入你要猜的数字:->");
if (scanf("%d", &guess) != EOF)
{
if (guess > ret)
{
printf("猜大了\n");
printf("--------\n");
}
else if (guess < ret)
{
printf("猜小了\n");
printf("--------\n");
}
else
{
printf("恭喜你,猜对了!,答案就是%d。\n", ret);
break;
}
if (!flag)//循环调整,循环一次,cnt次数减一。
--cnt;
}
else
{
printf("输入错误,正确答案是%d,欢迎下次挑战。\n", ret);
break;
}
}
if (cnt == 0)
printf("你失败了,正确答案是%d,下次加油\n", ret);
printf("----------------\n");
return;
}
结尾
C语言是一门程序型设计语言,顺序,分支,循环。谨以此篇巩固学习,权当记录了。
路漫漫其修远兮,吾将上下而求索。-----23年11月写下
今日偶然想起此篇,更Java的同时完结C语言的此篇。
如果我感到痛苦的话,我会先怀疑世界,然后给自己两嘴巴。--------2024/5/7,5:48.
早安,朋友们!