C語言從猜數(shù)字游戲中理解數(shù)據(jù)結(jié)構(gòu)
1 猜數(shù)字游戲-問題描述
這個(gè)游戲一點(diǎn)都不陌生,猜價(jià)格是一度很火的綜藝節(jié)目。很多老師也用這個(gè)案例作為課堂案例。在這里,我想把重點(diǎn)放到“思維層面上”,即:為什么要這樣寫代碼,就實(shí)現(xiàn)了猜數(shù)字游戲的功能。
我們先來說真人版的猜數(shù)字游戲:
A:心里默默出一個(gè)數(shù)字(約定一個(gè)范圍,假設(shè)[1-100]之間),開始猜把
B猜:50
A: 大了
B猜:25
A:小了
B猜:150
A:你違規(guī)了
B猜:30
A:猜對(duì)了!正確答案就是30!是否繼續(xù)猜?
B:需要
…
2 問題分析
從前面的真人版,換成人機(jī)版:
| 現(xiàn)實(shí)世界 | 程序模擬 | 實(shí)現(xiàn)途徑 |
|---|---|---|
| A | 電腦 | |
| 心里默默出一個(gè)數(shù)字 | 一個(gè)變量的值 | 隨機(jī)數(shù)/手動(dòng)在程序里悄悄定義的變量值/其他(總之就是你解決:產(chǎn)生一個(gè)數(shù)的方法) |
| B猜 | B敲鍵盤 | scanf掃描鍵盤 |
| A說大了、小了、對(duì)了 | 計(jì)算機(jī)判斷并輸出判斷結(jié)果 | if判斷 |
| A和B之間的繼續(xù)猜 | 重復(fù)事件 | 循環(huán) |
所謂“天下大事必做于易,天下難事必做于細(xì)”,
有了一個(gè)對(duì)現(xiàn)實(shí)問題的一個(gè)分析,你還可以把一個(gè)問題進(jìn)行逐層簡(jiǎn)化,然后再逐層豐富其功能:
1)猜一次
2)直到猜到為止
3)限定猜的次數(shù),并顯示當(dāng)前是第幾次猜
4)處理特殊情況:如果你提前猜到了;如果你猜的數(shù)超出了范圍
5)猜更多的數(shù)
6)對(duì)游戲計(jì)時(shí)、一分鐘猜對(duì)得越多還可以設(shè)關(guān)卡
…
這樣,就會(huì)對(duì)一個(gè)較為綜合的問題,有了一個(gè)自己的方案,接下來就可以開始嘗試逐個(gè)擊破了。
3 問題解決
3.1 猜一次
用IPO的思維,繼續(xù)分析這種情況,其故事流程是不是這樣的:
// I:輸入
1)計(jì)算機(jī):出一個(gè)數(shù)
2)用戶: 鍵盤輸一個(gè)數(shù)(猜)
3)計(jì)算機(jī):獲得這個(gè)數(shù)
//處理并輸出
4)計(jì)算機(jī):判斷這個(gè)數(shù)和自己出的數(shù)的大小關(guān)系
5)計(jì)算機(jī):根據(jù)不同的關(guān)系,告訴你猜大了、小了、對(duì)了
6)計(jì)算機(jī):告訴你正確答案
根據(jù)輸入與輸出,確定要定義的變量:計(jì)算機(jī)出的數(shù)、用于猜的數(shù)
程序員要做的:就是把上面的故事流程,用一種編程語言描述出來。
而故事的流程就是:算法;
編程語言描述出來的就是:程序
那么,我們就可以得到以下程序了:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int guess,magic; //magic計(jì)算機(jī)想的數(shù)
srand(time(NULL)); //用時(shí)間做種子,產(chǎn)生一個(gè)隨機(jī)數(shù)
magic = rand()%100+1; //隨機(jī)數(shù)落到1-100之間
printf("guess a number:\n"); //用戶猜一個(gè)數(shù)
scanf("%d",&guess);
if(guess>magic) //計(jì)算機(jī)判斷,并告訴你猜的情況
printf("too big!\n");
else if(guess<magic)
printf("too small!\n");
else
printf("right!\n");
printf("the right number is %d\n",magic);
return 0;
}
3.2 直到猜到為止
接著上面的故事。
還要繼續(xù)猜:
1)計(jì)算機(jī)出的數(shù)是否應(yīng)該變化? ——顯然,不能變,變了就作弊了
2)用戶還要繼續(xù)猜 —— 那么就還要再敲鍵盤、計(jì)算機(jī)還要繼續(xù)獲得這個(gè)數(shù)(3.1節(jié)代碼:Line9-10)
3)計(jì)算機(jī)還要繼續(xù)判斷——還要判斷大小關(guān)系(3.1節(jié)代碼:Line11-16)
因此,3.1節(jié)代碼Line9-16就應(yīng)該反復(fù)做,循環(huán)體就確定了;
直到猜到為止: 循環(huán)條件則是magic!=guess
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int guess,magic;
srand(time(NULL));
magic = rand()%100+1;
do{ ///用戶和計(jì)算機(jī)判斷是循環(huán)體
printf("guess a number:\n");
scanf("%d",&guess);
if(guess>magic)
printf("too big!\n");
else if(guess<magic)
printf("too small!\n");
else
printf("right!\n");
}while(guess!=magic); //循環(huán)條件
printf("the right number is %d\n",magic);
return 0;
}
}
3.3 限定猜10次
循環(huán)結(jié)束條件就變?yōu)椋翰铝?0次結(jié)束
那么就需要一個(gè)計(jì)數(shù)器,每猜一次,計(jì)數(shù)器+1, 到10次,循環(huán)結(jié)束;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int guess,magic;
int count=0; //計(jì)數(shù)器,一次都還沒有猜,初始為0
srand(time(NULL));
magic = rand()%100+1;
do{
count++; //猜1次,計(jì)數(shù)器加1
printf("the %dth: guess a number:\n",count); //顯示第幾次猜
scanf("%d",&guess);
if(guess>magic)
printf("too big!\n");
else if(guess<magic)
printf("too small!\n");
else
printf("right!\n");
}while(count<=10); //判斷猜到10次了沒有
printf("the right number is %d\n",magic);
return 0;
}
3.4 處理特殊情況
情況1:如果用于猜的范圍超出[1,100],給出提示
顯然,從鍵盤獲得用戶猜的數(shù)(3.3節(jié)代碼Line13)后,就應(yīng)判斷:
—— a)是否超過了[1,100]的范圍,是,本次不判斷猜的情況,用戶重新猜下一次;
——b)否,則判斷用戶猜的情況。
情況2:如果不到10次就猜到了,提前結(jié)束循環(huán);
這就是代碼輸出“right!”的情況(3.3節(jié)代碼Line19),同時(shí)加上結(jié)束循環(huán)的語句break就ok。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int guess,magic;
int count=0;
srand(time(NULL));
magic = rand()%100+1;
do{
count++;
printf("the %dth: guess a number:\n",count);
scanf("%d",&guess);
if(guess>100 ||guess<1) //處理情況1
{
printf("You guess the number should be in the range [1,100]:\n");
continue; //跳過本次循環(huán)
}
if(guess>magic)
printf("too big!\n");
else if(guess<magic)
printf("too small!\n");
else
{
printf("right!\n");
break; //處理情況2
}
}while(count<=10);
printf("the right number is %d\n",magic);
return 0;
}
3.5 猜下一個(gè)數(shù)
分析:
1) 上一個(gè)數(shù)的猜,已經(jīng)結(jié)束;—— 3.4節(jié)代碼中的Line29
2) 詢問用戶,是否繼續(xù)進(jìn)行游戲; ——輸出一條詢問語句
3) 輸入用戶的意愿; —— scanf輸入
4) 如果是,則繼續(xù)做游戲;否則游戲結(jié)束 ——新的循環(huán)是否繼續(xù)的條件
5) 重新給10次猜的機(jī)會(huì) ——計(jì)數(shù)器清0
6) 計(jì)算機(jī)再重新想一個(gè)數(shù); ——3.4節(jié)代碼中的Line 8-9
7) 繼續(xù)猜; ——3.4節(jié)代碼中的Line 10-29
于是3.4節(jié)代碼的Line8-29是需要繼續(xù)作為新的循環(huán)的循環(huán)體。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int guess,magic;
int count;
int reply=0; //用戶是否繼續(xù)游戲
do{
count=0; //每猜一個(gè)新的數(shù),計(jì)數(shù)器清0
srand(time(NULL)); //重新產(chǎn)生一個(gè)新的數(shù)來猜
magic = rand()%100+1;
do{
count++; //猜1次,計(jì)數(shù)器加1
printf("the %dth: guess a number:\n",count);
scanf("%d",&guess);
if(guess>100 ||guess<1)
{
printf("You guess the number should be in the range [1,100]:\n");
continue;
}
if(guess>magic)
printf("too big!\n");
else if(guess<magic)
printf("too small!\n");
else
{
printf("right!\n");
break;
}
}while(count<=10);
printf("the right number is %d\n",magic);
printf("Is the game continue? 1(yes) or 0(no):\n"); //詢問是否繼續(xù)游戲
scanf("%d",&reply); //獲得用戶的意愿
}while(reply==1); //如果意愿是1,則繼續(xù)游戲;否則,整個(gè)程序結(jié)束
return 0;
}
小結(jié):
程序其實(shí)就是用計(jì)算機(jī)的語言,描述你要解決的問題。
所以,對(duì)初學(xué)者來說,學(xué)好程序有如下點(diǎn):
1)學(xué)會(huì)把現(xiàn)實(shí)問題和計(jì)算機(jī)世界做一個(gè)抽象,如上面的表格
2)把一個(gè)大的問題逐層簡(jiǎn)化
3)從小問題入手,層進(jìn)式解決問題
當(dāng)然,分析問題是整個(gè)過程的重點(diǎn),切勿拿著個(gè)問題,就想著代碼怎么寫,算法才是程序的靈魂。
同學(xué)們還可以在上面代碼的基礎(chǔ)上,讓這個(gè)游戲的功能更加豐富,繼續(xù)加油吧!
到此這篇關(guān)于C語言從猜數(shù)字游戲中理解數(shù)據(jù)結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)C語言 數(shù)據(jù)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡(jiǎn)單實(shí)例
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06
C++中賦值運(yùn)算符與逗號(hào)運(yùn)算符的用法詳解
這篇文章主要介紹了C++中賦值運(yùn)算符與逗號(hào)運(yùn)算符的用法詳解,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09
C語言安全編碼之?dāng)?shù)值中的sizeof操作符
這篇文章主要介紹了C語言安全編碼的數(shù)值中的sizeof操作符用法注意事項(xiàng),需要的朋友可以參考下2014-07-07
C++中用指向數(shù)組的指針作函數(shù)參數(shù)
多維數(shù)組名作為函數(shù)參數(shù)傳遞:在二維數(shù)組中,數(shù)組名a是指向首行a[0]的指針,也就是說a=&a[0]; a[0]是指向首元素a[0][0]的指針,也就是說a[0]=&a[0][0]2013-10-10
C語言中 int main(int argc,char *argv[])的兩個(gè)參數(shù)詳解
這篇文章主要介紹了C語言中 int main(int argc,char *argv[])的兩個(gè)參數(shù)詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03
VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法(注冊(cè)表修改)
這篇文章主要介紹了VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法,涉及VC++針對(duì)注冊(cè)表的相關(guān)操作技巧,需要的朋友可以參考下2016-08-08
VsCode搭建C語言運(yùn)行環(huán)境詳細(xì)過程及終端亂碼問題解決方案
這篇文章主要介紹了VsCode搭建C語言運(yùn)行環(huán)境以及終端亂碼問題解決,在VsCode中搭建C/C++運(yùn)行環(huán)境需要先安裝幾個(gè)插件,具體插件文中給大家詳細(xì)介紹,需要的朋友可以參考下2022-12-12
淺談C++高并發(fā)場(chǎng)景下讀多寫少的優(yōu)化方案
本文主要介紹了淺談C++高并發(fā)場(chǎng)景下讀多寫少的優(yōu)化方案,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

