目录
在第二章的学习中,我们了解到了变量如何定义和使用,还有分支语句和循环语句。这次我们将把这些学到的知识运用起来,用代码去感悟。
第一节:猜数字小游戏
1-1.scanf函数
在正式写代码之前,我们先来认识一个函数:scanf。它的用法与 printf 函数类似,printf 函数的功能是打印,即从变量-->电脑屏幕;而 scanf 函数的功能是从键盘读取数据到变量,即从电脑键盘-->变量。
如下是 scanf 函数与 printf 函数用法的对比:
int a = 10;
int b;
printf("%d", a);
scanf("%d", &b);
它们的用法十分相似,但是scanf函数传入的变量参数前有一个“&”。这个符号与以后会讲的指针类型有关,这里不作解释,用就完了。
键盘输入后按Enter,即回车键表示完成输入
1-2.游戏规则与编写思路
游戏规则:
运行程序时,它会生产一个0--100的随机数,这个随机数用户并不知道。然后用户输入自己猜测的数字,程序就会告诉用户是猜大了、猜小了或者是猜中了,然后用户继续猜测数字,直到猜中了。如果猜中了,游戏结束,并告诉用户猜测的数量。
编写思路:
根据以上规则,我们可以归纳出以下思路,然后一一实现:
1、游戏菜单,输入1表示开始游戏,输入0表示退出
2、开始游戏就生成一个0--100的随机数
3、让用户输入数字
4、猜测数加1,判断猜测的数字与实际的数字的大小关系
5、没猜中重复3、4步
6、猜中了显示猜测数量并返回菜单
1-3.实战
1-3-1.游戏菜单
游戏菜单简单的使用 printf 函数打印即可:
#include <stdio.h>
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
return 0;
}
然后需要让用户输入一个数字进行选择,所以先定义一个 int 类型的变量 select,然后用 scanf 函数从键盘获取数字给它赋值:
#include <stdio.h>
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
//---------------------------------------------------
int select;
printf("请选择:");
scanf("%d", &select);
return 0;
}
根据输入的值选择 开始游戏 或者 退出 ,这里就需要分支语句 用 if 语句或者 switch 语句都可以:
#include <stdio.h>
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:");
scanf("%d", &select);
//---------------------------------------------------
switch (select)
{
case 1: // 开始游戏
// 游戏逻辑
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
return 0;
}
ps:在 main 函数中的 return 表示程序结束,所以 case 0 使用 return 时程序就结束了,不用考虑下面的代码,也就不需要 break 来分隔它。
1-3-2.游戏逻辑
首先要生成一个随机数:
#include <stdio.h>
#include <stdlib.h> // 包含函数 srand 和 rand 的文件
#include <time.h> // 包含函数 time 的文件
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:");
scanf("%d", &select);
switch (select)
{
case 1: // 开始游戏
//-------------------------------------------------
srand(time(NULL)); // 用时间戳设置随机数种子
int random = rand(); // 获取一个随机数
random = random % 101; // 让随机数的值在0--100之间
//-------------------------------------------------
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
return 0;
}
出现的陌生知识有点多,接下来我一个一个介绍:
NULL:NULL是一个指针类型,表示没有指向任何地方,这个以后在指针部分会详细说明
time 函数:time 函数用来获得一个时间戳,时间戳是一个数字,从1970年1月1日00:00:00开始到你使用time 函数的时间,然后换算成秒。它的值是随时间不断变化的。
srand 函数:srand 函数是为 rend 函数服务的,它用时间戳设置了一个随机数种子。因为时间戳是不断变化的,所以重新启动程序时获得的随机数也是不一样的。
rand 函数:获得一个随机数,如果不用 srand 函数和 time 函数设置随机数种子,每次重新启动程序,用它获得的随机数的顺序会是一样的。随机数的取值范围是:0--32767
% 符号:表示取余数,因为余数一定小于除数(101),所以可以获得0--100内的数
然后获取用户猜测的数字:
#include <stdio.h>
#include <stdlib.h> // 包含函数 srand 和 rand 的文件
#include <time.h> // 包含函数 time 的文件
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:");
scanf("%d", &select);
switch (select)
{
case 1: // 开始游戏
srand(time(NULL)); // 用时间戳设置随机数种子
int random = rand(); // 获取一个随机数
random = random % 101; // 让随机数的值在0--100之间
//-------------------------------------------------
int guess;
printf("请输入你猜测的数字:");
scanf("%d",&guess);
//-------------------------------------------------
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
return 0;
}
接下来用 guess 作判断,大于、小于或者等于,还要记录猜测的次数:
#include <stdio.h>
#include <stdlib.h> // 包含函数 srand 和 rand 的文件
#include <time.h> // 包含函数 time 的文件
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:")
scanf("%d", &select);
switch (select)
{
case 1: // 开始游戏
srand(time(NULL)); // 用时间戳设置随机数种子
int random = rand(); // 获取一个随机数
random = random % 101; // 让随机数的值在0--100之间
//-----------------------------------------
int count = 0; // 记录猜测次数,count在这里定义与变量的生命周期有关,学了下一章就知道原因了
//-----------------------------------------
int guess;
printf("请输入你猜测的数字:");
scanf("%d",&guess);
//-----------------------------------------
if (guess > random) // 大于
{
printf("猜大了\n");
count++;
}
else if (guess < random) // 小于
{
printf("猜小了\n");
count++;
}
else // 等于
{
count++;
printf("恭喜你,猜中了\n");
printf("共猜了 %d 次\n", count);
}
//-------------------------------------------------
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
return 0;
}
要让猜测的过程能够重复,所以需要加上循环,使用 while 循环即可:
#include <stdio.h>
#include <stdlib.h> // 包含函数 srand 和 rand 的文件
#include <time.h> // 包含函数 time 的文件
int main()
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:");
scanf("%d", &select);
switch (select)
{
case 1: // 开始游戏
srand(time(NULL)); // 用时间戳设置随机数种子
int random = rand(); // 获取一个随机数
random = random % 101; // 让随机数的值在0--100之间
int count = 0; // 记录猜测次数
while(1) // 在这里添加----------------------------------------
{
int guess;
printf("请输入你猜测的数字:");
scanf("%d", &guess);
if (guess > random) // 大于
{
printf("猜大了\n");
count++;
}
else if (guess < random) // 小于
{
printf("猜小了\n");
count++;
}
else // 等于
{
count++;
printf("恭喜你,猜中了\n");
printf("共猜了 %d 次\n", count);
break; // 跳出循环
}
} // 在这里结束----------------------------------------
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
return 0;
}
ps:在C语言中0为假,非0为真。上一章的条件表达式经过判断后,如果为假会返回0被识别,如果为真会返回1被识别。这个 while 循环的条件表达式是1,表示一直为真,即一直循环,直到猜中了用 break 跳出循环(是的,break 不仅能跳出 switch 还能用来跳出循环)
因为,游戏结束后还需要重新返回菜单,所以最外面还需要一个 while 循环:
#include <stdio.h>
#include <stdlib.h> // 包含函数 srand 和 rand 的文件
#include <time.h> // 包含函数 time 的文件
int main()
{
while(1) // 在这里添加----------------------------------------
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:");
scanf("%d", &select);
switch (select)
{
case 1: // 开始游戏
srand(time(NULL)); // 用时间戳设置随机数种子
int random = rand(); // 获取一个随机数
random = random % 101; // 让随机数的值在0--100之间
int count = 0; // 记录猜测次数
while (1)
{
int guess;
printf("请输入你猜测的数字:");
scanf("%d", &guess);
if (guess > random) // 大于
{
printf("猜大了\n");
count++;
}
else if (guess < random) // 小于
{
printf("猜小了\n");
count++;
}
else // 等于
{
count++;
printf("恭喜你,猜中了\n");
printf("共猜了 %d 次\n", count);
break;
}
}
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
} // 在这里结束----------------------------------------
return 0;
}
至此代码以及完成了,但是编译时会出现这个错误:
它的意思是说 scanf 函数不安全,用它提供的 scanf_s 函数。这个我们不管,在代码最前面加上如下代码以忽略这个错误:
#define _CRT_SECURE_NO_WARNINGS
至此,完整的代码为:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // 包含函数 srand 和 rand 的文件
#include <time.h> // 包含函数 time 的文件
int main()
{
while(1)
{
//游戏菜单
printf("************************************\n");
printf("*************1.开始游戏*************\n");
printf("*************0.退 出*************\n");
printf("************************************\n");
int select;
printf("请选择:");
scanf("%d", &select);
switch (select)
{
case 1: // 开始游戏
srand(time(NULL)); // 用时间戳设置随机数种子
int random = rand(); // 获取一个随机数
random = random % 101; // 让随机数的值在0--100之间
int count = 0; // 记录猜测次数
while (1)
{
int guess;
printf("请输入你猜测的数字:");
scanf("%d", &guess);
if (guess > random) // 大于
{
printf("猜大了\n");
count++;
}
else if (guess < random) // 小于
{
printf("猜小了\n");
count++;
}
else // 等于
{
count++;
printf("恭喜你,猜中了\n");
printf("共猜了 %d 次\n", count);
break;
}
}
break;
case 0: // 退出
return 0;
default:// select既不是1也不是0,即一个非法的输入
printf("非法的输入,请重新选择\n");
}
}
return 0;
}
然后来游玩一下吧
第二节:九九乘法表
2-1.循环嵌套
循环是允许嵌套的,即大循环里面可以有小循环,比如上面的猜数字游戏:
while(1)
{
// 游戏菜单等
while(1)
{
// 游戏逻辑
}
}
而打印九九乘法表就需要循环嵌套。
2-2.实战
我们先来看看九九乘法表的样子:
对于每一行:乘号左边是递增的,但不大于乘号右边;乘号右边在行与行之间递增
所以以乘号右边为大循环,嵌套依次递增的乘号左边。
我们先完成大循环的部分:
#include <stdio.h>
int main()
{
for(int j = 1;j < 10;j++) // j会从1递增到9
{
}
return 0;
}
再完成小循环部分:
#include <stdio.h>
int main()
{
for(int j = 1;j < 10;j++) // j会从1递增到9
{
for (int i = 1; i <= j; i++) // i会从1递增到j
{
}
}
return 0;
}
在小循环中打印每一行的式子:
#include <stdio.h>
int main()
{
for(int j = 1;j < 10;j++) // j会从1递增到9
{
for (int i = 1; i <= j; i++) // i会从1递增到j
{
//----------------------------------------
int sum = j*i;
printf("%dX%d=%d ", j, i, j * i);
//----------------------------------------
}
}
return 0;
}
ps:”*“是乘号,j * i 表示 j 乘以 i
它的执行结果是:
行与行之间没有分开,所以每打印完一行就要打印一个换行符:
#include <stdio.h>
int main()
{
for(int j = 1;j < 10;j++) // j会从1递增到9
{
for (int i = 1; i <= j; i++) // i会从1递增到j
{
int sum = j*i;
printf("%dX%d=%d ", j, i, j * i);
}
//----------------------------------------
printf("\n");
//----------------------------------------
}
return 0;
}
但是还有一个问题,请看第四行和第五行并没有对齐,这是因为不同位数的数字所占的位置大小是不同的,所以要把 %d 变成加上 %-2d,表示打印时占用两位数的位置,然后向左对齐,不加负号就是向右对齐(第一个%d和第二个%d不需要改变,因为i与j最大就是9)
最后的代码和执行结果如下:
#include <stdio.h>
int main()
{
for(int j = 1;j < 10;j++) // j会从1递增到9
{
for (int i = 1; i <= j; i++) // i会从1递增到j
{
printf("%dX%d=%-2d ", j, i, j * i);
}
printf("\n");
}
return 0;
}
这样就看起来很舒服了。
下期预告:
第三章的标题是:变量进阶与函数,具体介绍以下内容:
1、局部变量与全局变量,生命周期,static关键字
2、函数的基本用法
更新时间在2024年8月8日前
传送门:C语言-第三章:变量进阶与函数