版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
喬林
計(jì)算機(jī)程序設(shè)計(jì)基礎(chǔ)
第五章程序組織與
軟件開發(fā)方法
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@
提綱
?5.1庫與接口
?5.2隨機(jī)數(shù)庫
?5.3作用域與生存期
?5.4宏
?5.5條件編譯
?5.6典型軟件開發(fā)流程
?本章小結(jié)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@2
5.15「族。
?庫與程序文件
-程序文件:源文件(*.c)、頭文件(*.h)、工程文件
-庫:源文件與頭文件
?接口
-通過接口使用庫:包括指定庫的頭文件與源文件
-優(yōu)勢:不需了解庫的實(shí)現(xiàn)細(xì)節(jié),只需了解庫的使用方法
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@3
標(biāo)灌i/o4
?輸入輸出函數(shù)
?常用函數(shù)列表
-STRINGgets(STRINGbuffer);
-nitprintf(CSTRINGfmt,...);
-nitputs(CSTRINGstr);
-nitscanf(CSTRINGfmt,
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@4
?數(shù)學(xué)函數(shù)
?常用函數(shù)列表
-三角函數(shù)與反三角函數(shù)系列
?doubleacos(doublex);
?doublesin(doublex);
?
-幕函數(shù)與對(duì)數(shù)函數(shù)系列
?duoblelog(doublex);
?doublepow(doublex,doubley);
?......
-其他數(shù)學(xué)函數(shù)
?doublesqrt(doublex);
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@5
標(biāo)灌輔防備皴庫
?工具與輔助函數(shù)
?常用函數(shù)列表
-voidexit(intstatus);
-voidfree(void*p);
-void*malloc(size_tsize);
-intrand();
-voidsrand(unsignedintseed);
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@6
殺女件的包含桌陪
?包含頭文件的格式
-尖括號(hào):在C編譯器的標(biāo)準(zhǔn)目錄下查找該頭文件
-雙引號(hào):首先在當(dāng)前工程項(xiàng)目所在的目錄下查找,若不
存在,則查找標(biāo)準(zhǔn)目錄
-使用雙引號(hào)包含自己或其他編寫的非C標(biāo)準(zhǔn)庫
?頭文件的多次包含
-多個(gè)文件包含同一個(gè)頭文件
-例:“zyrandom.h”包含“zylib.h",“main.c”包
含“zyrandom.h”與“zylib.h",貝ij“main.c”不僅
主動(dòng)包含了“zylib.h",還通過“zyrandom.h”被動(dòng)
包含了“zylib.h"
-多次包含同一個(gè)頭文件可能會(huì)導(dǎo)致程序問題
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@7
決文件的包含象畸
?解決方法
-使用條件編譯指令#ifndef(條件判斷,若未定義)、#define
(定義)與#?門山£(結(jié)束條件判斷)
?被包含的頭文件
-#ifndef_ZYLIB_
-#define_ZYLIB_
-頭文件的具體內(nèi)容在此
-#endif
?源文件或包含文件
-#ifndef_ZYLIB_
-#include"zylib.h"
-#endif
-源文件或包含文件的具體內(nèi)容在此
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@8
5.2微機(jī)照庫
?隨機(jī)數(shù)的生成
?庫的設(shè)計(jì)原則
?隨機(jī)數(shù)庫接口
?隨機(jī)數(shù)庫實(shí)現(xiàn)
?隨機(jī)數(shù)庫測試
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@9
成機(jī)敏的金閾第一版
?編寫程序,調(diào)用rand函數(shù)生成五個(gè)隨機(jī)數(shù)
#include<stdio.h>
#include<stdlib.h>
intmain()
(
inti;
printf("Onthiscomputer,theRAND_MAXis%d.\nH,RAND.MAX);
printf("Fivenumberstherandfunctiongeneratesasfollows:\n");
for(i=0;i<5;i++)
printf("%d;rand());
printf("\n");
return0;
}
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@10
成機(jī)敏的金閾第二版
?編寫程序,調(diào)用rand函數(shù)生成五個(gè)隨機(jī)數(shù)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
intmain()
(
inti;
printf("Onthiscomputer,theRAND_MAXis%d.\nH,RAND.MAX);
printf("Fivenumberstherandfunctiongeneratesasfollows:\n");
srand((int)time(O));
for(i=0;i<5;i++)printf("%d;",rand());
printf("\n");
return0;
}
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@11
接口強(qiáng)針原則
?用途一致
-接口中所有函數(shù)都屬于同一類問題
?操作簡單
-函數(shù)調(diào)用方便,最大限度隱藏操作細(xì)節(jié)
?功能充足
-滿足不同潛在用戶的需要
?性能穩(wěn)定
-經(jīng)過嚴(yán)格測試,不存在程序缺陷
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@12
成機(jī)敏屋接。
?設(shè)計(jì)隨機(jī)數(shù)接口
#ifndef_ZYRANDOM_
#define_ZYRANDOM_
#ifndef_ZYLIB_
#include"zylib.h"
#endif
voidRandomize();
intGenerateRandomNumber(intlow,inthigh);
doubleGenerateRandomReal(doublelow,doublehigh);
#endif
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@13
成機(jī)敕庫實(shí)現(xiàn)
?實(shí)現(xiàn)隨機(jī)數(shù)庫
#include<stdlib.h>
#include<time.h>
#ifndef_ZYRANDOM_
#include"zyrandom.h"
#endif
#ifndef_ZYLIB_
#include"zylib.h"
#endif
voidRandomize()
(
srand((int)time(NULL));
}
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@14
成機(jī)撤庫實(shí)現(xiàn)
intGenerateRandomNumber(intlow,inthigh)
(
double_d;
if(low>high)
PrintErrorMessage(FALSE,
"GenerateRandomNumber:Makesurelow<=high.\n");
_d=(double)rand()/((double)RAND_MAX+1.0);
return(low+(int)(_d*(high-low+1)));
)
doubleGenerateRandomReal(doublelow,doublehigh)
(
double_d;
if(low>high)
PrintErrorMessage(FALSE,
"GenerateRandomReal:Makesurelow<=highAn");
_d=(double)rand()/((double)RAND_MAX+1.0);
return(low+_d*(high-low));
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@15
?單獨(dú)測試庫的所有函數(shù)
-合法參數(shù)時(shí)返回結(jié)果是否正確
-非法參數(shù)時(shí)返回結(jié)果是否正確,即容錯(cuò)功能是
否正常
?聯(lián)合測試
-多次運(yùn)行程序,查看生成的數(shù)據(jù)是否隨機(jī)
-測試整數(shù)與浮點(diǎn)數(shù)隨機(jī)數(shù)是否均能正確工作
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@16
5.3作用城易金花期
?量的作用域與可見性
?量的存儲(chǔ)類與生存期
?函數(shù)的作用域與生存期
?聲明與定義
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@17
量的作用域鳥可見他
?作用域與可見性
-作用域:標(biāo)識(shí)符的有效范圍
-可見性:程序中某個(gè)位置是否可以使用某個(gè)標(biāo)識(shí)符
-標(biāo)識(shí)符僅在其作用域內(nèi)可見
-位于作用域內(nèi)的標(biāo)識(shí)符不一定可見
?局部數(shù)據(jù)對(duì)象
-定義于函數(shù)或復(fù)合語句塊內(nèi)部的數(shù)據(jù)對(duì)象(包括變量、
常量與函數(shù)形式參數(shù)等)
-局部數(shù)據(jù)對(duì)象具有塊作用域,僅在定義它的塊內(nèi)有效
-有效性從定義處開始直到該塊結(jié)束
-多個(gè)函數(shù)定義同名的數(shù)據(jù)對(duì)象是允許的,原因?
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@18
局部撤據(jù)對(duì)象的作用域
intfunc(intx,inty)
(
intt;
t=x+y;
/*單獨(dú)出現(xiàn)的花括號(hào)對(duì)用于引入嵌套塊*/
(
/*允許在塊中定義數(shù)據(jù)對(duì)象,作用域僅限本塊*/
intn=2;
printf("n=%dAnM,n);
)
returnt;
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@19
量的作用域鳥可見他
?全局?jǐn)?shù)據(jù)對(duì)象
-定義于函數(shù)或復(fù)合語句塊之外的數(shù)據(jù)對(duì)象
-全局?jǐn)?shù)據(jù)對(duì)象具有文件(全局)作用域,有效性從定義
處開始直到本文件結(jié)束,其后函數(shù)都可直接使用
-若包含全局?jǐn)?shù)據(jù)對(duì)象定義的文件被其他文件包含,則其
作用域擴(kuò)展到宿主文件中,這可能會(huì)導(dǎo)致問題,為什么?
-不要在頭文件中定義全局?jǐn)?shù)據(jù)對(duì)象!
?函數(shù)原型作用域
-定義在函數(shù)原型中的參數(shù)具有函數(shù)原型作用域,其有效
性僅延續(xù)到此函數(shù)原型結(jié)束
-函數(shù)原型中參數(shù)名稱可以與函數(shù)實(shí)現(xiàn)中的不同,也可以
省略
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@20
作用域鳥可見植示例
1inti;/*全局變量i作用域開始,可見*/
2intmain()
3
4intn;/*局部變量n作用域開始,可見*/
5i=10;/*全局變量i有效且可見*/
6printf("i=%2d;n=%2d\n",i,n);
7n=func(i);
8printf("i=%2d;n=%2d\n",i,n);
9)/*局部變量n作用域結(jié)束,不再可見*/
10intn;/*全局變量n作用域開始,可見7
11intfunc(intx)/*形式參數(shù)x作用域開始,可見*/
12
13i=0;/*全局變量i有效且可見*/
14printf("i=%2d;n=%2d\n",i,n);
15n=20;/*全局變量n有效且可見*/
16{/*嵌套塊開始*/
17inti=n+x;/*局部變量i、x有效可見;全局變量n有效可見;全局變量i有效不可見*/
18printf("i=%2d;n=%2d\n",i,n);
19}/*局部變量i作用域結(jié)束,全局變量i有效且可見*/
20return++i;
21)/*局部變量x作用域結(jié)束,不再可見*/
22/*文件結(jié)束,全局變量i、n作用域結(jié)束*/
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@21
量的存儲(chǔ)類鳥皮腐期
?生存期:量在程序中存在的時(shí)間范圍
-C使用存儲(chǔ)類表示生存期
-作用域表達(dá)量的空間特性,存儲(chǔ)類表達(dá)量的時(shí)間特性
?靜態(tài)(全局)生存期
-全局?jǐn)?shù)據(jù)對(duì)象具有靜態(tài)(全局)生存期
-生死僅與程序是否執(zhí)行有關(guān)
?自動(dòng)(局部)生存期
-局部數(shù)據(jù)對(duì)象具有自動(dòng)(局部)生存期
-生死僅與程序流程是否位于該塊中有關(guān)
-程序每次進(jìn)入該塊時(shí)就為該對(duì)象分配內(nèi)存,退出該塊時(shí)
釋放內(nèi)存;兩次進(jìn)入該塊時(shí)使用的不是同一個(gè)數(shù)據(jù)對(duì)象
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@22
static關(guān)仇劣
?修飾局部變量:靜態(tài)局部變量
-使局部變量具有靜態(tài)生存期
-程序退出該塊時(shí)局部變量仍存在,并且下次進(jìn)入該塊時(shí)
使用上一次的數(shù)據(jù)值
-靜態(tài)局部變量必須進(jìn)行初始化
-不改變量的作用域,仍具有塊作用域,即只能在該塊中
訪問,其他代碼段不可見
?修飾全局變量
-使其作用域僅限定于本文件內(nèi)部,其他文件不可見
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@23
精態(tài)周部變量爾例
?檢查下述程序的輸出結(jié)果
#include<stdio.h>
intfunc(intx);
intmain()
(
inti;
for(i=1;i<4;i++)
printf("Invokefunc%dtime(s):Return%d.\n",i,func(i));
return0;
)
intfunc(intx)
(
staticintcount=0;/*定義靜態(tài)局部變量count,函數(shù)結(jié)束后仍存在*/
printf("x=%d.\n",x);
return++count;
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@24
備般的作用減名金腐期
?所有函數(shù)具有文件作用域與靜態(tài)生存期
-在程序每次執(zhí)行時(shí)都存在,并且可以在函數(shù)原型或函數(shù)
定義之后的任意位置調(diào)用
?內(nèi)部函數(shù)與外部函數(shù)
-外部函數(shù):可以被其他文件中的函數(shù)所調(diào)用
-內(nèi)部函數(shù):不可以被其他文件中的函數(shù)所調(diào)用
-函數(shù)缺省時(shí)均為外部函數(shù)
-內(nèi)部函數(shù)定義:使用static關(guān)鍵字
-內(nèi)部函數(shù)示例:staticintTransform(intx);
-內(nèi)部函數(shù)示例:staticintTransform(intx){...}
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@25
戶明鳥靈文
?聲明不是定義
-定義在程序產(chǎn)生一個(gè)新實(shí)體
-聲明僅僅在程序中引入一個(gè)實(shí)體
?函數(shù)的聲明與定義
-聲明是給出函數(shù)原型,定義是給出函數(shù)實(shí)現(xiàn)代碼
?類型的聲明與定義
-產(chǎn)生新類型就是定義
-類型定義示例:typedefenum_BOOL{FALSE,
TRUE}BOOL;
-不產(chǎn)生新類型就不是定義,而僅僅是聲明
-類型聲明示例:enum_BOOL;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@26
全局變量的作用域獷展
?全局變量的定義不能出現(xiàn)在頭文件中,只有其聲
明才可以出現(xiàn)在頭文件中
?聲明格式:使用extern關(guān)鍵字
〃庫的頭文件7
〃此處僅引入變量a,其定義位于對(duì)應(yīng)源文件中7
externinta;〃變量a可導(dǎo)出,其他文件可用7
〃庫的源文件7
〃定義變量a7
inta;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@27
5.4宏
?宏替換
?含參宏
?宏與函數(shù)的差異
?宏的特殊用法
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@28
成蓍換
?編譯前進(jìn)行簡單文本替換
STRINGNAME="TheFundamentalsSTRINGNAME=“The…”;
#defineFALSE0/*宏定義前的標(biāo)識(shí)符不被替換*/
#defineTRUE1/*宏定義本身已不再需要*/
#defineNAME"QiaoLin"
intmain()intmain()
(
/*宏定義后標(biāo)識(shí)符全被替換*/
STRINGMY_NAME=NAME;STRINGMY_NAME="QiaoLin";
/*字符串本身不會(huì)被替換*/
STRINGs="NAME";STRINGs="NAME";
if(a==TRUE)if(a==1)
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@29
宏替換的基中原剜
?宏定義占用單獨(dú)一個(gè)文本行
?宏替換時(shí),被替換文字不能是標(biāo)識(shí)符的一部分
?宏定義中宏名稱之后的全部內(nèi)容都是替換文本,
包括該文本行后面的操作符號(hào)或標(biāo)點(diǎn)符號(hào)
-設(shè)宏定義:#defineADDa+b;
-c=ADD被替換為c=a+b;
?可以使用已定義宏定義新宏
-#definePI3.14
-#defineAREAPl*r*r;
-area=AREA;被替換為area=3.14*r*r;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@30
宏替換的基中原剜
?宏替換只發(fā)生一次,不會(huì)嵌套替換
-#definePI3.14
-#defineDPI*D*D
-area=D;被替換為area=3.14*D*D;
?宏定義總是出現(xiàn)在函數(shù)聲明或定義之外,一般放
置在頭文件的函數(shù)原型開始之前
?宏定義的有效性從定義處開始直到文件結(jié)束
?如果要提前取消某個(gè)宏定義,使用#undef指令
-#undefNAME
?宏的目的:降低改變同樣文本時(shí)的工作量;為特
定文字起個(gè)有意義的名稱,取代魔數(shù)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@31
金永肉
?定義格式
-#define宏名稱(參數(shù)列表)替換文本
-替換時(shí),使用參數(shù)列表中的實(shí)際參數(shù)逐一替換后面宏的
替換文本中的形式參數(shù)
?定義與替換示例:看起來像函數(shù)
-#defineADD(x,y)x+y
-c=ADD(a,b);被替換為c=a+b;
-形式參數(shù)x被實(shí)際參數(shù)a替換,y被b替換
?含參宏的替換是直接替換
-#defineADD(x,y)x+y
-c=ADD(a+b,c);被替換為c=a+b+c;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@32
含永宏
?替換文本中的操作符優(yōu)先級(jí)問題
-#definePI3.14
-#defineADD(x,y)x+y
-#defineAREA(r)Pl*r*r
-c=AREA(ADD(a,b));
-首先被替換為c=PI*ADD(a,b)*ADD(a,b);
-然后被替換為c=PI*a+b*a+b;
?解決方案:使用括號(hào)
-#definePI3.14
-#defineADD(x,y)((x)+(y))
-#defineAREA(r)(PI*(r)*(r))
-c=AREA(ADD(a,b));
-被替換為c=(PI*(((a)+(b)))*(((a)+(b))));
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@33
金參青易備照的異同
?函數(shù)形式參數(shù)與實(shí)際參數(shù)具有固定類型,并且保持一致;
含參宏的參數(shù)沒有類型要求,甚至可以不是數(shù)據(jù)對(duì)象
-示例:#defineMax(x,y)(x)>(y)?(x):(y)
-可以使用上述宏判斷整數(shù)或浮點(diǎn)數(shù)等類型數(shù)據(jù)的大小關(guān)系,C語
言是不允許為不同數(shù)據(jù)類型編寫同名函數(shù)的!
?函數(shù)調(diào)用在程序執(zhí)行時(shí)處理,含參宏在編譯前處理
?函數(shù)形式參數(shù)會(huì)在執(zhí)行時(shí)分配存儲(chǔ)空間,含參宏的參數(shù)不
會(huì)分配存儲(chǔ)空間,不會(huì)發(fā)生參數(shù)傳遞,也沒有返回值
?函數(shù)調(diào)用占用程序執(zhí)行時(shí)間,含參宏替換不占用程序執(zhí)行
時(shí)間,僅占用編譯時(shí)間
?函數(shù)調(diào)用節(jié)省程序代碼空間(多次調(diào)用使用同樣代碼),
含參宏浪費(fèi)程序代碼空間(多次替換會(huì)使得代碼膨脹)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@34
宏的精殊用收
?略
?感興趣的可以自學(xué)
?閱讀zylib庫代碼需要了解這部分內(nèi)容
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@35
5.5條件編件
?略
?基礎(chǔ)知識(shí):見頭文件的包含策略
?復(fù)雜內(nèi)容:感興趣的可以自學(xué),開發(fā)大型程
序才需要了解
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@36
5.6善型收件開或流程
?軟件工程概要
?問題的提出
?需求分析
?概要設(shè)計(jì)
?詳細(xì)設(shè)計(jì)
?編碼實(shí)現(xiàn)
?系統(tǒng)測試
?經(jīng)驗(yàn)總結(jié)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@37
役件工程橢要
?需求分析:確定軟件需要解決什么問題
-決定因素:人
-軟件開發(fā)人員需要與用戶深入交流,明確問題的輸入、
輸出以及其他附加信息
-不要輕視任何問題!
?方案設(shè)計(jì):設(shè)計(jì)程序框架
-概要設(shè)計(jì):設(shè)計(jì)總體方案,形成高層模塊劃分
-詳細(xì)設(shè)計(jì):細(xì)化模塊,獲得各模塊的輸入、輸出與算法
?編碼實(shí)現(xiàn):實(shí)際編程
?系統(tǒng)測試:測試程序的正確性與穩(wěn)定性
?經(jīng)驗(yàn)總結(jié)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@38
決件開或海程圖
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@39
我件外或同敗
?我猜!我猜!我猜猜猜!
-編程實(shí)現(xiàn)一個(gè)簡單的猜價(jià)格游戲
-假設(shè)有某物品,已知其最低價(jià)格與最高價(jià)格
-游戲參與者在給定次數(shù)內(nèi)猜測其價(jià)格具體值
-若游戲者成功猜出其價(jià)格,作為獎(jiǎng)勵(lì)將得到該
物品
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@40
需靠臺(tái)布
?需求A:游戲運(yùn)行前首先應(yīng)向游戲參與者介紹游戲功能
?需求B:首期工程不需要解決游戲難度問題,用戶迫切希
望程序能在最短時(shí)間內(nèi)運(yùn)行起來,因此只考慮最簡單情形
?需求C:在每個(gè)游戲回合結(jié)束時(shí)允許用戶選擇是否重新開
始新游戲,這里游戲回合是指游戲參與者或者猜中價(jià)格或
者其猜測機(jī)會(huì)已用完,如果用戶沒有選擇退出,游戲應(yīng)無
休止地玩下去
?需求D:能夠記錄游戲參與者的游戲信息,目前僅統(tǒng)計(jì)用
戶玩了多少回合以及贏了多少回合
?需求E:在用戶退出游戲時(shí),給出此次游戲勝率
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@41
?不明確的地方:什么是最簡單情形?與用戶再次
溝通……
-需求B1:設(shè)物品最低價(jià)格為100元,最高價(jià)格為200元
-需求B2:物品實(shí)際價(jià)格由系統(tǒng)運(yùn)行時(shí)隨機(jī)生成
-需求B3:游戲參與者最多允許猜6次
-需求B4:若游戲參與者猜測價(jià)格比實(shí)際價(jià)格高,則程
序提示“高”;若猜測價(jià)格比實(shí)際價(jià)格低,提示“低”
?用戶補(bǔ)充需求
-需求F:需要定義游戲初始化過程,未來有可能通過它
調(diào)整游戲難度,程序必須為此提供接口
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@42
倒要強(qiáng)什
?響應(yīng)需求A、E、F
-將游戲劃分為四個(gè)模塊:歡迎信息顯示模塊、游戲初始
化模塊、游戲模塊、游戲結(jié)束模塊
-程序架構(gòu):主文件“main.c”,程序主體函數(shù)庫
“guess.h”與“guess.c";此外需要使用zylib與
zyrandom庫
?設(shè)計(jì)函數(shù)原型
-勝率信息需要從游戲模塊傳遞給游戲結(jié)束模塊
-voidPrintWelcomelnfo();
-voidInitializeGameQ;
-doublePlayGame();
-voidPrintGameOverlnfo(doubleprevailed_ratio);
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@43
guess.h
#ifndef_EG0507GUESS_
#define_EG0507GUESS_
voidPrintWelcomelnfo();
voidInitializeGameQ;
doublePlayGame();
voidPrintGameOverlnfo(doubleprevailed_ratio);
#endif
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@44
main.c
#ifndef_EG0507GUESS_
#include"guess.h"
#endif
intmain()
(
doubleprevailed_ratio;
PrintWelcomelnfo();
lnitializeGame();
prevailed_ratio=PlayGame();
PrintGameOverlnfo(prevailed_ratio);
return0;
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@45
倒要強(qiáng)什
?響應(yīng)需求C
-使用無限循環(huán)作為游戲模塊的主架構(gòu):初始化游戲回合,
進(jìn)行游戲回合,判斷游戲參與者是否開始新游戲回合
?響應(yīng)需求B2
-每一回合需要隨機(jī)生成物品價(jià)格,應(yīng)在游戲回合初始化
階段完成
-抽象出單獨(dú)的游戲回合初始化函數(shù),返回值為初始化的
物品價(jià)格(整數(shù)類型)
-intlnitializeBout();
?響應(yīng)需求D
-游戲參與者的回合數(shù)與獲勝回合數(shù):使用整數(shù)類型保存,
游戲開始時(shí)初始化為0,并隨著游戲進(jìn)程變化
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@46
橢要強(qiáng)針
?游戲回合活動(dòng)分析
-將每一回合游戲抽象成函數(shù),函數(shù)返回值為BOOL,表示該游戲
回合游戲參與者是否獲勝
-BOOLPlayBout();
?判斷用戶是否進(jìn)入下一回合
-BOOLAgain();
-Again函數(shù)負(fù)責(zé)在PlayGame函數(shù)中充當(dāng)哨兵,在返回值為
FALSE時(shí)退出游戲
?響應(yīng)需求B1、B3:數(shù)據(jù)初始化工作
-constintlowest_price=100;
-constinthighest_price=200;
-constintguesstimate_count=6;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@47
?響應(yīng)需求B4:細(xì)化PlayBout
-在給定猜測次數(shù)內(nèi)接受游戲參與者的輸入價(jià)格,判斷與
實(shí)際價(jià)格是否相同,如果不同則給出提示信息,如果相
同則恭喜游戲參與者獲勝
-但是……
?需求G:一旦游戲參與者給出了猜測價(jià)格,當(dāng)該
價(jià)格或高或低時(shí),提示游戲參與者的信息應(yīng)能夠
相應(yīng)縮小價(jià)格區(qū)間以反映此變化
?響應(yīng)需求G:修改PlayBout函數(shù),添加參數(shù)
-BOOLPlayBout(intactual_price,intlower_price,
inthigher_price,intchancesjeft);
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@48
?歡迎信息模塊設(shè)計(jì)
-要求:將游戲性質(zhì)與游戲方法告訴游戲參與者,
系統(tǒng)應(yīng)盡可能輸出詳細(xì)信息,例如物品最低價(jià)
格、最高價(jià)格與猜測次數(shù)都應(yīng)通知游戲參與者
?偽代碼
voidPrintWelcomelnfo()
(
輸出程序性質(zhì)信息
物品最低價(jià)格、最高價(jià)格與猜測次數(shù)一并輸出
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@49
?游戲初始化模塊設(shè)計(jì)
-要求:不知道
?偽代碼
voidlnitializeGame()
(
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@50
?游戲結(jié)束模塊設(shè)計(jì)
-要求:如果能夠在游戲結(jié)束模塊不僅輸出游戲參與者勝率,還針
對(duì)其勝率高低輸出不同鼓勵(lì)信息就好了
?需求H:當(dāng)游戲參與者勝率超過75%(含)時(shí),輸出
“Youluckyyyyyyyyyyyyy!^^;當(dāng)勝率低于75%但超過
50%(含)時(shí),輸出“SogoooooooocL”;其他輸出
“Youcandoitbetter.Wishyouluck.”
?偽代碼
voidPrintGameOverlnfo(doubleprevailed_ratio)
(
輸出百分制勝率
根據(jù)勝率分別輸出不同信息
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@51
?游戲模塊細(xì)化
?偽代碼
doublePlayGameQ
(
while(TRUE){
調(diào)用IrMtializeBout獲得實(shí)際價(jià)格
調(diào)用PgyBout啟動(dòng)游戲回合
如果游戲回合結(jié)束后結(jié)果為TRUE,遞增獲勝回合數(shù)
遞增總回合數(shù)
調(diào)用[gain,若結(jié)果為FALSE,終止游戲,否則繼續(xù)
}
返回最終勝率
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@52
?游戲回合初始化與游戲初始化模塊細(xì)化
?偽代碼
intlnitializeBout()
(
調(diào)用GenerateRandomNumber函數(shù)
并返回其結(jié)果
}
voidlnitializeGame()
(
調(diào)用Randomize函數(shù)啟動(dòng)隨機(jī)數(shù)發(fā)生器
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@53
?游戲回合模塊細(xì)化
?需求I:如果游戲參與者給出的猜測價(jià)格不在當(dāng)時(shí)
價(jià)格范圍內(nèi),應(yīng)提醒用戶重新提供新價(jià)格,此次
操作不應(yīng)遞減用戶猜測次數(shù),以防止用戶輸入錯(cuò)
誤,也就是說,需要檢查猜測價(jià)格的合法性
?需求J:當(dāng)最后一次機(jī)會(huì)也未猜中價(jià)格時(shí),不需
要再輸出提示價(jià)格高低信息,直接輸出用戶本回
合失敗信息,并將實(shí)際價(jià)格告訴用戶
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@54
BOOLPlayBoutfintactual_price,intlower_price,inthigher_price,intchancesjeft){
while(還有猜測機(jī)會(huì)){
獲得游戲參與者猜測價(jià)格,檢查游戲參與者猜測價(jià)格是否在給定范圍
遞減游戲參與者猜測機(jī)會(huì)
判斷猜測價(jià)格高低
switch(判斷結(jié)果){
case高了:
if(還有猜測機(jī)會(huì)){輸出價(jià)格高了信息,降低最高價(jià)格值,縮小猜測區(qū)間}
else{輸出失敗信息與物品實(shí)際價(jià)格,結(jié)束函數(shù),返回本回合失敗值FALSE}
break;
case低了:
if(還有猜測機(jī)會(huì)){輸出價(jià)格低了信息,增大最低價(jià)格值,縮小猜測區(qū)間}
else{輸出失敗信息與物品實(shí)際價(jià)格,結(jié)束函數(shù),返回本回合失敗值FALSE}
break;
default:
輸出游戲參與者獲勝信息,結(jié)束函數(shù),返回TRUE
}
}
程序流程至此,說明游戲參與者本回合已失敗,返回FALSE
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@55
?進(jìn)一步細(xì)化游戲回合函數(shù)
-抽象三個(gè)輔助函數(shù)
-獲得游戲參與者猜測價(jià)格:int
GetGuesstimatePrice(intlower_price,int
higher_price,intchancesjeft);
-檢查游戲參與者猜測價(jià)格是否在給定范圍:int
CheckValidationOfGuesstimatePrice(int
lower_price,inthigher_price,int
guesstimate_price);
-判斷猜測價(jià)格高低:intJudgeGuesstimatePrice(int
actual_price,intguesstimate_price);
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@56
intGetGuesstimatePrice(intlower_price,inthigher_price,intchancesjeft)
(
輸出提示信息,包括最低價(jià)格,最高價(jià)格與剩余猜測次數(shù)
調(diào)用GetlntegerFromKeyboard獲取猜測價(jià)格并返回
}
intCheckValidationOfGuesstimatePrice(intlower_price,inthigher_price,int
guesstimate_price)
(
while(猜測價(jià)格小于最低價(jià)格或高于最高價(jià)格){
通知游戲參與者猜測價(jià)格超出范圍,提醒用戶重新輸入新價(jià)格
調(diào)用GetlntegerFromKeyboard獲取新猜測價(jià)格
}
返回新猜測價(jià)格
}
intJudgeGuesstimatePrice(intactuaLprice,intguesstimate_price)
(
獲得猜測價(jià)格與實(shí)際價(jià)格之差
if(差值大于0)return1;elseif(差值小于0)return-1;elsereturn0;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@57
?細(xì)化Again函數(shù)
?Zylib庫的字符串比較函數(shù)
-BOOLlsStringEqual(STRINGs1,STRINGs2)
-BOOLIsStringEqualWithoutCasefSTRINGs1,STRINGs2)
?偽代碼
BOOLAgainQ
(
詢問游戲參與者是否開始新游戲
獲取游戲參與者的響應(yīng)
調(diào)用ilsStringEqualWithoutCase函數(shù),
判斷游戲參與者的響應(yīng)是否為“n”
如果真,返回FALSE,即將上述返回值取反返回
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@58
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@59
編居實(shí)猊
#include<stdio.h>
#ifndef_ZYLIB_
#include"zylib.h"
#endif
#ifndef_ZYRANDOM_
#include"zyrandom.h"
#endif
#ifndef_EG0507GUESS_
#include"guess.h"
#endif
constintlowest_price=100;
constinthighest_price=200;
constintguesstimate_count=6
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系Email:qiaolin@60
編居實(shí)猊
staticintlnitializeBout();
staticBOOLPlayBout(intactuaLprice,intlower_price,int
higher_price,intchancesjeft);
staticBOOLAgainQ;
staticintGetGuesstimatePrice(intlower_price5inthigher_price,int
chancesjeft);
staticintCheckValidationOfGuesstimatePrice(intlower_price,int
higher_price,intguesstimate_price);
staticintJudgeGuesstimatePrice(intactuaLprice,int
guesstimate_price);
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@61
voidPrintWelcomelnfo()
(
printf("Theprogramlistsaproductwithpricebetween%dand"
"%d(RMBYuan).\n",lowest_price,highest_price);
printf("Yougiveaguesstimateprice.Ifthepriceyougiveis"
"correct,youwin.\n");
printf("Youhave%dchancesAn",guesstimate_count);
printf("Risetothechallengetowinyourbonus...\nH);
)
voidlnitializeGame()
(
inti,n;
Randomize();
}
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@62
doublePlayGameQ
(
intactuaLprice,lower_price=lowest_price,higher_price=highest_price;
intchancesjeft=guesstimate_count;
intbout_count=0,prevailed_bout_count=0;
while(TRUE)
(
printf("\n");
actual_price=lnitializeBout();
if(PlayBout(actual_price,lower_price,higher_price,chancesjeft))
prevailed_bout_count++;
bout_count++;
if(!Again())
break;
)
return(double)prevailed_bout_count/(double)bout_count;
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@63
voidPrintGameOverlnfo(doubleprevailed_ratio)
(
printf("\nprevailedratio:%.2lf%%.\n",prevailed_ratio*100);
if(prevailed_ratio>=0.75)
printf("Youluckyyyyyyyyyyyyy!\n\n");
elseif(prevailed_ratio>=0.50)
printf("Sogooooooood.\n\n");
else
printf("Youcandoitbetter.Wishyouluck.\n\n");
)
staticintInitializeBoutQ
(
returnGenerateRandomNumber(lowest_price,highest_price);
)
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@64
staticBOOLPlayBout(intactual_price,intlower_price,inthigher_price,intchancesjeft)
{
intguesstimate_price;
intjudge_result;
while(chances_left>0){
guesstimate_price=GetGuesstimatePrice(lower_price,higher_price,chancesjeft);
guesstimate_price=CheckValidationOfGuesstimatePrice(lower_price,higher_price,guesstimate_price);
chancesjeft-;
judge_result=JudgeGuesstimatePrice(actual_price,guesstimate_price);
switch(judge_result){
case1:
if(chances_left>0){printfC^nHigherAn");higher_price=guesstimate_price-1;}
else{printf("\nYoulosethisbout.Theactualpriceis%d.\n",actuaLprice);returnFALSE;}
break;
case-1:
if(chances_left>0){printfC^nLowerAn");lower_price=guesstimate_price+1;}
else{printf("\nYoulosethisbout.Theactualpriceis%d.\n",actuaLprice);returnFALSE;}
break;
default:printf("\nYouwinnnnnnnnnnnnnnnnhn");returnTRUE;
)
)
returnFALSE;
清華大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)系E-mail:qiaolin@65
staticBOOLAgainQ
(
printf("\nPlayanewgame(\"n\"tostop,otherwordstoplayagain)?");
return!lsStringEqualWithoutCase(GetStringFromKeyboard(),"n");
)
staticintGetGuesstimatePrice(intlower_price,inthigher_price,intchancesjeft)
(
printf("Theactualpric
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 關(guān)于節(jié)約糧食主題國旗下講話稿范文(13篇)
- 新型風(fēng)電軸承材料研究-洞察分析
- 填料對(duì)混凝土耐久性的影響-洞察分析
- 土壤水勢時(shí)空演變-洞察分析
- 虛擬仿真技術(shù)在職業(yè)教育中的應(yīng)用-洞察分析
- 心理健康與生活質(zhì)量-第1篇-洞察分析
- 物聯(lián)網(wǎng)數(shù)據(jù)質(zhì)量評(píng)估與治理-洞察分析
- 碳捕集與氣候變化應(yīng)對(duì)-洞察分析
- 水資源跨區(qū)域調(diào)配與協(xié)同管理-洞察分析
- 醫(yī)院醫(yī)生調(diào)換科室申請(qǐng)書(8篇)
- 高中詞匯3500亂序版
- NY 5051-2001無公害食品淡水養(yǎng)殖用水水質(zhì)
- GB/T 24176-2009金屬材料疲勞試驗(yàn)數(shù)據(jù)統(tǒng)計(jì)方案與分析方法
- 2023年初一學(xué)生綜合素質(zhì)自我陳述報(bào)告3篇(范文)
- 四年級(jí)數(shù)學(xué)期末考試質(zhì)量分析
- 多發(fā)性骨髓瘤的療效評(píng)估
- 題型二次函數(shù)壓軸題課件
- 中建二局“大商務(wù)”管理實(shí)施方案20200713(終稿)
- 燃?xì)獍踩^續(xù)教育考試題及答案
- 班前安全教育手冊(cè)(適用于全公司房屋建筑工程、市政基礎(chǔ)設(shè)施工程、公路工程施工的作業(yè)人員)
評(píng)論
0/150
提交評(píng)論