最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解如何使用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲

 更新時(shí)間:2026年06月29日 09:20:35   作者:時(shí)間的拾荒人  
這篇文章詳細(xì)介紹了如何使用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲,涵蓋了隨機(jī)數(shù)生成、循環(huán)和分支結(jié)構(gòu)的綜合應(yīng)用,以及如何通過(guò)模塊化設(shè)計(jì)提高代碼的可讀性和復(fù)用性,通過(guò)實(shí)現(xiàn)rand()、srand()和time()函數(shù)生成隨機(jī)數(shù),并結(jié)合while和-while循環(huán)和if-else條件判斷實(shí)現(xiàn)游戲邏輯

1. 引言

在前面的學(xué)習(xí)中,我們已經(jīng)掌握了C語(yǔ)言的分支和循環(huán)語(yǔ)句。今天,我們將把這些知識(shí)綜合運(yùn)用起來(lái),編寫一個(gè)非常經(jīng)典且有趣的小項(xiàng)目——猜數(shù)字游戲

通過(guò)這個(gè)項(xiàng)目,你將深入理解:

  • 如何生成隨機(jī)數(shù)
  • 如何結(jié)合循環(huán)和分支控制游戲邏輯
  • 如何設(shè)計(jì)一個(gè)完整的程序結(jié)構(gòu)

這個(gè)游戲雖然簡(jiǎn)單,但卻是面試中經(jīng)常被問(wèn)到的邏輯題,也是你從語(yǔ)法學(xué)習(xí)邁向項(xiàng)目實(shí)戰(zhàn)的第一步。

2. 游戲需求分析

在開始寫代碼之前,我們先明確一下游戲規(guī)則:

  1. 電腦自動(dòng)生成一個(gè)1~100之間的隨機(jī)數(shù)
  2. 玩家猜數(shù)字,在猜的過(guò)程中,程序會(huì)根據(jù)玩家猜測(cè)的數(shù)據(jù)大小給出 “大了”“小了” 的反饋
  3. 直到玩家猜對(duì),游戲結(jié)束

這個(gè)需求看似簡(jiǎn)單,但實(shí)現(xiàn)它的核心在于:如何讓電腦生成一個(gè)真正的隨機(jī)數(shù)?

3. 隨機(jī)數(shù)生成

要想完成猜數(shù)字游戲,首先得產(chǎn)生隨機(jī)數(shù)。C語(yǔ)言為我們提供了幾個(gè)相關(guān)的函數(shù)。

3.1rand函數(shù)

C語(yǔ)言提供了一個(gè)叫 rand 的函數(shù),它可以生成隨機(jī)數(shù),函數(shù)原型如下:

int rand (void);
  • rand 函數(shù)會(huì)返回一個(gè)偽隨機(jī)數(shù),范圍在 0 ~ RAND_MAX 之間
  • RAND_MAX 的大小依賴編譯器實(shí)現(xiàn),大部分編譯器上是 32767
  • 使用 rand 函數(shù)需要包含頭文件:stdlib.h

我們來(lái)測(cè)試一下 rand 函數(shù),多調(diào)用幾次,產(chǎn)生5個(gè)隨機(jī)數(shù):

#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());
    return 0;
}

運(yùn)行結(jié)果分析:

我們先運(yùn)行一次,看看結(jié)果,再運(yùn)行一次再看看結(jié)果,多運(yùn)行幾次會(huì)發(fā)現(xiàn):

  • 第一次運(yùn)行結(jié)果:41 18467 6334 26500 19169
  • 第二次運(yùn)行結(jié)果:41 18467 6334 26500 19169

雖然一次運(yùn)行中產(chǎn)生的5個(gè)數(shù)字是相對(duì)隨機(jī)的,但是下一次運(yùn)行程序生成的結(jié)果和上一次一模一樣,這就說(shuō)明有點(diǎn)問(wèn)題。

知識(shí)點(diǎn): 其實(shí) rand 函數(shù)生成的隨機(jī)數(shù)是偽隨機(jī)數(shù)。偽隨機(jī)數(shù)不是真正的隨機(jī)數(shù),是通過(guò)某種算法生成的隨機(jī)數(shù)。真正的隨機(jī)數(shù)是無(wú)法預(yù)測(cè)下一個(gè)值是多少的。而 rand 函數(shù)是對(duì)一個(gè)叫 “種子” 的基準(zhǔn)值進(jìn)行運(yùn)算生成的隨機(jī)數(shù)。

之所以前面每次運(yùn)行程序產(chǎn)生的隨機(jī)數(shù)序列是一樣的,那是因?yàn)?rand 函數(shù)生成隨機(jī)數(shù)的默認(rèn)種子是1。如果要生成不同的隨機(jī)數(shù),就要讓種子是變化的。

3.2srand函數(shù)

C語(yǔ)言中又提供了一個(gè)函數(shù)叫 srand,用來(lái)初始化隨機(jī)數(shù)的生成器,srand 的原型如下:

void srand (unsigned int seed);

程序中在調(diào)用 rand 函數(shù)之前先調(diào)用 srand 函數(shù),通過(guò) srand 函數(shù)的參數(shù) seed 來(lái)設(shè)置 rand 函數(shù)生成隨機(jī)數(shù)時(shí)的種子,只要種子在變化,每次生成的隨機(jī)數(shù)序列也就變化起來(lái)了。

那也就是說(shuō)給 srand 的種子如果是隨機(jī)的,rand 就能生成隨機(jī)數(shù);但在生成隨機(jī)數(shù)的時(shí)候又需要一個(gè)隨機(jī)數(shù),這就矛盾了。

3.3time函數(shù)

在程序中我們一般是使用程序運(yùn)行的時(shí)間作為種子的,因?yàn)闀r(shí)間時(shí)刻在發(fā)生變化。

C語(yǔ)言中有一個(gè)函數(shù)叫 time,就可以獲得這個(gè)時(shí)間,time 函數(shù)原型如下:

time_t time (time_t* timer);
  • time 函數(shù)會(huì)返回當(dāng)前的日歷時(shí)間,其實(shí)返回的是 1970年1月1日0時(shí)0分0秒 到現(xiàn)在程序運(yùn)行時(shí)間之間的差值,單位是秒
  • 返回的類型是 time_t 類型的,time_t 類型本質(zhì)上其實(shí)就是32位或者64位的整型類型
  • time 函數(shù)的參數(shù) timer 如果是非NULL的指針的話,函數(shù)也會(huì)將這個(gè)返回的差值放在 timer 指向的內(nèi)存中帶回去
  • 如果 timerNULL,就只返回這個(gè)時(shí)間的差值。time 函數(shù)返回的這個(gè)時(shí)間差也被叫做:時(shí)間戳

使用 time 函數(shù)的時(shí)候需要包含頭文件:time.h

// VS2022 上 time_t 類型的說(shuō)明
#ifndef _CRT_NO_TIME_T
    #ifdef _USE_32BIT_TIME_T
        typedef __time32_t time_t;
    #else
        typedef __time64_t time_t;
    #endif
#endif

typedef long                          __time32_t;
typedef __int64                       __time64_t;

如果只是讓 time 函數(shù)返回時(shí)間戳,我們就可以這樣寫:

time(NULL); // 調(diào)用time函數(shù)返回時(shí)間戳,這里沒有接收返回值

3.4 組合使用:生成真正的隨機(jī)數(shù)

現(xiàn)在,我們可以將 srandtime 組合起來(lái),讓 rand 生成真正的隨機(jī)數(shù):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    // 使用time函數(shù)的返回值設(shè)置種子
    // 因?yàn)閟rand的參數(shù)是unsigned int類型,我們將time函數(shù)的返回值強(qiáng)制類型轉(zhuǎn)換
    srand((unsigned int)time(NULL));
    
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    
    return 0;
}

多運(yùn)行幾次看看,每次的運(yùn)行就有差異了。

注意: srand 函數(shù)是不需要頻繁調(diào)用的,一次運(yùn)行的程序中調(diào)用一次就夠了

3.5 設(shè)置隨機(jī)數(shù)的范圍

在實(shí)際開發(fā)中,我們往往需要生成指定范圍內(nèi)的隨機(jī)數(shù)。下面是一些常用的技巧:

目標(biāo)范圍代碼寫法原理說(shuō)明
0 ~ 99rand() % 100余數(shù)的范圍是0~99
1 ~ 100rand() % 100 + 1%100的余數(shù)是099,+1后范圍是1100
100 ~ 200100 + rand() % (200-100+1)余數(shù)的范圍是0100,加100后就是100200

通用公式: 要生成 a ~ b 的隨機(jī)數(shù),方法如下:

a + rand() % (b - a + 1)

4. 猜數(shù)字游戲?qū)崿F(xiàn)

掌握了隨機(jī)數(shù)的生成方法,現(xiàn)在我們來(lái)完整實(shí)現(xiàn)猜數(shù)字游戲。

4.1 基礎(chǔ)版本

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void game()
{
    int r = rand() % 100 + 1;
    int guess = 0;
    
    while (1)
    {
        printf("請(qǐng)猜數(shù)字>:");
        scanf("%d", &guess);
        
        if (guess < r)
        {
            printf("猜小了\n");
        }
        else if (guess > r)
        {
            printf("猜大了\n");
        }
        else
        {
            printf("恭喜你,猜對(duì)了\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("請(qǐng)選擇:>");
        scanf("%d", &input);
        
        switch (input)
        {
            case 1:
                game();
                break;
            case 0:
                printf("游戲結(jié)束\n");
                break;
            default:
                printf("選擇錯(cuò)誤,重新選擇\n");
                break;
        }
    } while (input);
    
    return 0;
}

4.2 進(jìn)階版本:增加次數(shù)限制

為了讓游戲更有挑戰(zhàn)性,我們可以加上猜數(shù)字的次數(shù)限制,如果5次猜不出來(lái),就算失敗。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void game()
{
    int r = rand() % 100 + 1;
    int guess = 0;
    int count = 5;
    
    while (count)
    {
        printf("\n你還有%d次機(jī)會(huì)\n", count);
        printf("請(qǐng)猜數(shù)字>:");
        scanf("%d", &guess);
        
        if (guess < r)
        {
            printf("猜小了\n");
        }
        else if (guess > r)
        {
            printf("猜大了\n");
        }
        else
        {
            printf("恭喜你,猜對(duì)了\n");
            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;
    srand((unsigned int)time(NULL));
    
    do
    {
        menu();
        printf("請(qǐng)選擇:>");
        scanf("%d", &input);
        
        switch (input)
        {
            case 1:
                game();
                break;
            case 0:
                printf("游戲結(jié)束\n");
                break;
            default:
                printf("選擇錯(cuò)誤,重新選擇\n");
                break;
        }
    } while (input);
    
    return 0;
}

5. 代碼結(jié)構(gòu)分析

讓我們來(lái)梳理一下這個(gè)程序的整體結(jié)構(gòu):

5.1 函數(shù)模塊化設(shè)計(jì)

函數(shù)名功能關(guān)鍵點(diǎn)
menu()打印游戲菜單純輸出,無(wú)參數(shù)無(wú)返回值
game()核心游戲邏輯生成隨機(jī)數(shù)、循環(huán)判斷、次數(shù)控制
main()程序入口初始化隨機(jī)種子、菜單循環(huán)、分支選擇

5.2 程序執(zhí)行流程

6. 面試常見問(wèn)題與解答

Q1:rand()和srand()的關(guān)系是什么?

解答: rand() 用于生成偽隨機(jī)數(shù),srand() 用于設(shè)置隨機(jī)數(shù)生成器的種子。如果不調(diào)用 srand()rand() 默認(rèn)使用種子1,導(dǎo)致每次程序運(yùn)行生成的隨機(jī)數(shù)序列相同。通過(guò) srand() 設(shè)置不同的種子(通常使用 time(NULL) 返回的時(shí)間戳),可以讓 rand() 每次生成不同的隨機(jī)數(shù)序列。

Q2:為什么使用time(NULL)作為srand()的參數(shù)?

解答: time(NULL) 返回當(dāng)前時(shí)間的時(shí)間戳(從1970年1月1日到現(xiàn)在的秒數(shù)),這個(gè)值每秒鐘都在變化。用它作為種子,可以確保每次運(yùn)行程序時(shí)種子都不同,從而生成不同的隨機(jī)數(shù)序列。這是最簡(jiǎn)單且有效的獲取變化種子的方法。

Q3:如何生成指定范圍 [a, b] 的隨機(jī)數(shù)?

解答: 使用公式 a + rand() % (b - a + 1)。原理是:rand() % (b - a + 1) 生成 0(b - a) 之間的隨機(jī)數(shù),再加上 a,范圍就變成了 ab。例如生成1~100的隨機(jī)數(shù):1 + rand() % 100。

Q4:猜數(shù)字游戲中,do-while循環(huán)和while循環(huán)哪個(gè)更合適?為什么?

解答: do-while 循環(huán)更合適。因?yàn)橛螒虿藛沃辽傩枰@示一次讓用戶選擇,do-while 保證循環(huán)體至少執(zhí)行一次,符合“先顯示菜單,再判斷是否繼續(xù)”的邏輯。如果使用 while 循環(huán),需要在循環(huán)前額外顯示一次菜單,代碼會(huì)顯得冗余。

Q5:在進(jìn)階版本中,如何實(shí)現(xiàn)“5次猜不對(duì)就失敗”的邏輯?

解答: 使用一個(gè)計(jì)數(shù)器 count 初始化為5。每次循環(huán) count--,當(dāng) count 變?yōu)?時(shí)循環(huán)結(jié)束。循環(huán)結(jié)束后判斷 count == 0,如果是則說(shuō)明用戶沒有在5次內(nèi)猜對(duì),輸出失敗信息。關(guān)鍵代碼:

int count = 5;
while (count) {
    // 猜數(shù)字邏輯
    count--;
}
if (count == 0) {
    printf("你失敗了,正確值是:%d\n", r);
}

7. 總結(jié)

通過(guò)這個(gè)猜數(shù)字游戲項(xiàng)目,我們實(shí)踐了以下重要知識(shí)點(diǎn):

  1. 隨機(jī)數(shù)生成:掌握了 rand()、srand()time() 的配合使用
  2. 循環(huán)結(jié)構(gòu):綜合運(yùn)用了 while 循環(huán)和 do-while 循環(huán)
  3. 分支結(jié)構(gòu):使用了 if-elseswitch-case 進(jìn)行條件判斷
  4. 模塊化設(shè)計(jì):將不同功能封裝成獨(dú)立的函數(shù),提高代碼可讀性和復(fù)用性
  5. 程序流程控制:通過(guò) break 跳出循環(huán),通過(guò) continue(可擴(kuò)展)控制循環(huán)節(jié)奏

建議:這個(gè)猜數(shù)小練習(xí)雖然簡(jiǎn)單,但它涵蓋了C語(yǔ)言程序設(shè)計(jì)的核心思想。建議你親手敲一遍代碼,理解每一行代碼的作用,這樣才能在面試中游刃有余。

以上就是一文詳解如何使用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲的詳細(xì)內(nèi)容,更多關(guān)于使用C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++面向?qū)ο蠛诵模侯愰g關(guān)系與繼承實(shí)戰(zhàn)指南

    C++面向?qū)ο蠛诵模侯愰g關(guān)系與繼承實(shí)戰(zhàn)指南

    C++面向?qū)ο笾?類間耦合與繼承機(jī)制是核心骨架,涉及依賴、關(guān)聯(lián)、組合、繼承五大關(guān)系,及靜態(tài)成員、友元等,本文給大家介紹C++面向?qū)ο蠛诵模侯愰g關(guān)系與繼承深度解析,感興趣的朋友跟隨小編一起看看吧
    2026-06-06
  • 直觀理解C語(yǔ)言中指向一位數(shù)組與二維數(shù)組的指針

    直觀理解C語(yǔ)言中指向一位數(shù)組與二維數(shù)組的指針

    這篇文章主要介紹了直觀理解C語(yǔ)言中指向一位數(shù)組與二維數(shù)組的指針,數(shù)組指針是C語(yǔ)言入門學(xué)習(xí)過(guò)程中的重點(diǎn)和難點(diǎn),需要的朋友可以參考下
    2016-05-05
  • Java C++算法題解leetcode1592重新排列單詞間的空格

    Java C++算法題解leetcode1592重新排列單詞間的空格

    這篇文章主要為大家介紹了Java C++算法題解leetcode1592重新排列單詞間的空格示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • C++中構(gòu)造函數(shù)的初始化順序說(shuō)明

    C++中構(gòu)造函數(shù)的初始化順序說(shuō)明

    C++構(gòu)造函數(shù)調(diào)用遵循基類→成員對(duì)象→派生類順序,虛函數(shù)在構(gòu)造中靜態(tài)綁定,完成后動(dòng)態(tài)綁定,拷貝構(gòu)造在初始化、賦值及容器操作時(shí)調(diào)用,RVO優(yōu)化可能避免拷貝,虛函數(shù)重寫自子類起生效,不追溯基類
    2025-07-07
  • C語(yǔ)言超詳細(xì)文件操作基礎(chǔ)下篇

    C語(yǔ)言超詳細(xì)文件操作基礎(chǔ)下篇

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的文件操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • C++中move的使用及說(shuō)明

    C++中move的使用及說(shuō)明

    這篇文章主要介紹了C++中move的使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語(yǔ)言編程大小端問(wèn)題示例詳解教程

    C語(yǔ)言編程大小端問(wèn)題示例詳解教程

    這篇文章主要為大家介紹了C語(yǔ)言編程大小端問(wèn)題解決的示例內(nèi)容詳解教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • C語(yǔ)言malloc分配問(wèn)題詳解

    C語(yǔ)言malloc分配問(wèn)題詳解

    這篇文章主要介紹了c語(yǔ)言 malloc函數(shù)的分配問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • VC實(shí)現(xiàn)屏幕截詞功能的方法詳解

    VC實(shí)現(xiàn)屏幕截詞功能的方法詳解

    這篇文章主要介紹了VC實(shí)現(xiàn)屏幕截詞功能的方法詳解,對(duì)于深入的理解windows程序運(yùn)行原理很有幫助,需要的朋友可以參考下
    2014-07-07
  • 一文掌握C++?中使用變量從定義到實(shí)踐

    一文掌握C++?中使用變量從定義到實(shí)踐

    變量是用于存儲(chǔ)數(shù)據(jù)值的容器,在?C++?中,有不同類型的變量(使用不同的關(guān)鍵字定義),這篇文章給大家介紹C++?中使用變量從定義到實(shí)踐記錄,感興趣的朋友跟隨小編一起看看吧
    2024-03-03

最新評(píng)論

广平县| 中卫市| 垫江县| 文安县| 墨竹工卡县| 嘉鱼县| 十堰市| 横山县| 陵水| 三亚市| 突泉县| 旅游| 福鼎市| 泗水县| 巢湖市| 黄梅县| 卢湾区| 焉耆| 三门峡市| 禄丰县| 青河县| 衡山县| 安徽省| 昌江| 惠州市| 封开县| 扎鲁特旗| 皋兰县| 麻栗坡县| 秦皇岛市| 雅江县| 盐山县| 沙雅县| 汤阴县| 靖江市| 饶河县| 巴中市| 曲周县| 修水县| 潮安县| 古浪县|