C语言实战:带你手写一个带"计时功能"的猜数字小游戏

今天这篇博客,为大家详细拆解一个经典的 C 语言入门项目------猜数字游戏。

我们在基础逻辑之上,加入了一个有趣的功能:记录玩家每次猜测的耗时。通过这个项目,我们可以深入理解随机数生成、循环控制以及时间函数的使用。

一、 完整代码实现

为了方便大家阅读和运行,这里先放出完整的代码。注意看代码中的注释,那是理解逻辑的关键。

c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 游戏核心逻辑函数
void game()
{
    // 1. 生成 1-100 的随机数
    int r = rand() % 100 + 1;
    int guess = 0;
    int count = 5; // 限制猜测次数

    while (count)
    {
        printf("\n你还有 %d 次机会\n", count);
        printf("请猜数字 >:");

        // --- 特色功能:计时开始 ---
        clock_t start_time = clock();

        scanf("%d", &guess);

        clock_t end_time = clock();
        // 计算耗时(秒)
        double time_spent = (double)(end_time - start_time) / CLOCKS_PER_SEC;
        // -------------------------

        if (guess < r)
        {
            printf("猜小了!本次猜数耗时: %.2f 秒\n", time_spent);
        }
        else if (guess > r)
        {
            printf("猜大了!本次猜数耗时: %.2f 秒\n", time_spent);
        }
        else
        {
            printf("恭喜你,猜对了!本次猜数耗时: %.2f 秒\n", time_spent);
            break; // 猜对后跳出循环
        }
        count--;
    }

    if (count == 0)
    {
        printf("你失败了,正确值是: %d\n", r);
    }
}

// 菜单显示函数
void menu()
{
    printf("***********************\n");
    printf("******  1. play  ******\n");
    printf("******  0. exit  ******\n");
    printf("***********************\n");
}

int main()
{
    int input = 0;

    // 2. 设置随机数种子(只需执行一次)
    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;
}

二、 核心逻辑深度解析

1. 预处理与环境配置

在代码的最开头,我们看到了这样一行:

#define _CRT_SECURE_NO_WARNINGS

  • 作用:这是 Visual Studio 编译器特有的宏定义。
  • 原因 :VS 认为 scanf 等标准 C 函数不够安全,会报错。加上这行代码可以屏蔽警告,让编译顺利通过。当然,如果你使用的是 GCC(Dev-C++、VSCode)或 Clang,这行其实是可以省略的。

2. 游戏核心:随机数与计时(game 函数)

这是整个程序的灵魂部分。

生成随机数

c 复制代码
int r = rand() % 100 + 1;

利用取模运算 %,我们将 rand() 生成的巨大随机数限制在了 1 到 100 之间。

创意亮点:计时功能

为了增加游戏的紧张感,我们使用了 <time.h> 库中的 clock() 函数:

  • 开始计时 :在 scanf 之前调用 clock() 记录起始时间点。
  • 结束计时 :在用户输入完成后再次调用 clock()。
  • 计算差值 :(end - start) / CLOCKS_PER_SEC。这里的 CLOCKS_PER_SEC 是一个常量,代表每秒有多少个时钟周期,除之后就能得到标准的秒数。

3. 程序入口与种子初始化(main 函数)

很多初学者容易犯的一个错误是把 srand 放在 game() 函数里。

注意 :srand((unsigned int)time(NULL)); 必须放在 main 函数中,且只执行一次。

  • 原理 :srand 是用来设置随机数种子的。如果放在循环里,因为计算机运行速度极快,同一秒内种子可能相同,导致生成的随机数也是一样的。放在 main 开头能确保每次运行程序种子都不同。

4. 交互循环结构

我们使用了经典的 do...while 循环配合 switch 语句来构建菜单:

  • do...while:保证菜单至少打印一次,用户体验更好。
  • while(input):利用 C 语言"非 0 即真"的特性,只要用户输入的不是 0,游戏就会一直循环下去。

三、 总结与拓展

这段代码虽然短小,但涵盖了 C 语言初学者的几个重要考点:

  1. 函数的模块化设计(menu、game、main 分离)。
  2. 循环与分支结构的嵌套使用。
  3. 标准库函数的实际应用(rand、srand、clock)。

拓展思考:

如果你想让游戏更难一点,可以尝试修改 count 的值;或者利用我们计算的 time_spent,如果玩家耗时超过 10 秒,直接判定失败,以此来训练玩家的反应速度!

相关推荐
iotxiaohu3 小时前
用 cflow 查看 C 函数调用关系
c语言·开发语言·cflow
iCxhust5 小时前
51单片机电力载波应用开发(九)51产品化
c语言·数据库·嵌入式硬件·mysql·51单片机·软件工程·c51
Logic1016 小时前
C语言/数据结构字符串题解:统计“chhc“子串权值总和——一次遍历模式匹配
c语言·数据结构·算法·字符串·时间复杂度·空间复杂度·ascii
m0_547486667 小时前
《数据结构 (C语言)》期末试卷及答案(10套)2026版
c语言·开发语言·数据结构
八月的雨季 最後的冰吻7 小时前
FFmepg-- 42-ffplay.c 线程安全机制深度分析
c语言·安全·ffmpeg
逐光者9338 小时前
滤波器的 R 与 C 如何选择:从截止频率到工程实践
c语言·开发语言·r语言
水饺编程8 小时前
第2章:Linux 基础,whoami 命令
linux·c语言·汇编
Logic10110 小时前
C语言/数据结构动态规划题解:字符串变回文的最少操作次数——最长回文子序列(LPS)
c语言·数据结构·算法·动态规划·时间复杂度·回文串·最长回文子序列
wuminyu10 小时前
ZGC染色指针在虚拟线程stackChunkOop上的并发屏障全景分析
java·linux·c语言·jvm·c++