




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
喬林
計算機程序設(shè)計基礎(chǔ)
第五章程序組織與
軟件開發(fā)方法
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@
提綱
?5.1庫與接口
?5.2隨機數(shù)庫
?5.3作用域與生存期
?5.4宏
?5.5條件編譯
?5.6典型軟件開發(fā)流程
?本章小結(jié)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@2
5.15「族。
?庫與程序文件
-程序文件:源文件(*.c)、頭文件(*.h)、工程文件
-庫:源文件與頭文件
?接口
-通過接口使用庫:包括指定庫的頭文件與源文件
-優(yōu)勢:不需了解庫的實現(xiàn)細節(jié),只需了解庫的使用方法
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@3
標灌i/o4
?輸入輸出函數(shù)
?常用函數(shù)列表
-STRINGgets(STRINGbuffer);
-nitprintf(CSTRINGfmt,...);
-nitputs(CSTRINGstr);
-nitscanf(CSTRINGfmt,
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@4
?數(shù)學(xué)函數(shù)
?常用函數(shù)列表
-三角函數(shù)與反三角函數(shù)系列
?doubleacos(doublex);
?doublesin(doublex);
?
-幕函數(shù)與對數(shù)函數(shù)系列
?duoblelog(doublex);
?doublepow(doublex,doubley);
?......
-其他數(shù)學(xué)函數(shù)
?doublesqrt(doublex);
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@5
標灌輔防備皴庫
?工具與輔助函數(shù)
?常用函數(shù)列表
-voidexit(intstatus);
-voidfree(void*p);
-void*malloc(size_tsize);
-intrand();
-voidsrand(unsignedintseed);
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@6
殺女件的包含桌陪
?包含頭文件的格式
-尖括號:在C編譯器的標準目錄下查找該頭文件
-雙引號:首先在當前工程項目所在的目錄下查找,若不
存在,則查找標準目錄
-使用雙引號包含自己或其他編寫的非C標準庫
?頭文件的多次包含
-多個文件包含同一個頭文件
-例:“zyrandom.h”包含“zylib.h",“main.c”包
含“zyrandom.h”與“zylib.h",貝ij“main.c”不僅
主動包含了“zylib.h",還通過“zyrandom.h”被動
包含了“zylib.h"
-多次包含同一個頭文件可能會導(dǎo)致程序問題
清華大學(xué)計算機科學(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@8
5.2微機照庫
?隨機數(shù)的生成
?庫的設(shè)計原則
?隨機數(shù)庫接口
?隨機數(shù)庫實現(xiàn)
?隨機數(shù)庫測試
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@9
成機敏的金閾第一版
?編寫程序,調(diào)用rand函數(shù)生成五個隨機數(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@10
成機敏的金閾第二版
?編寫程序,調(diào)用rand函數(shù)生成五個隨機數(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@11
接口強針原則
?用途一致
-接口中所有函數(shù)都屬于同一類問題
?操作簡單
-函數(shù)調(diào)用方便,最大限度隱藏操作細節(jié)
?功能充足
-滿足不同潛在用戶的需要
?性能穩(wěn)定
-經(jīng)過嚴格測試,不存在程序缺陷
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@12
成機敏屋接。
?設(shè)計隨機數(shù)接口
#ifndef_ZYRANDOM_
#define_ZYRANDOM_
#ifndef_ZYLIB_
#include"zylib.h"
#endif
voidRandomize();
intGenerateRandomNumber(intlow,inthigh);
doubleGenerateRandomReal(doublelow,doublehigh);
#endif
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@13
成機敕庫實現(xiàn)
?實現(xiàn)隨機數(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@14
成機撤庫實現(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@15
?單獨測試庫的所有函數(shù)
-合法參數(shù)時返回結(jié)果是否正確
-非法參數(shù)時返回結(jié)果是否正確,即容錯功能是
否正常
?聯(lián)合測試
-多次運行程序,查看生成的數(shù)據(jù)是否隨機
-測試整數(shù)與浮點數(shù)隨機數(shù)是否均能正確工作
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@16
5.3作用城易金花期
?量的作用域與可見性
?量的存儲類與生存期
?函數(shù)的作用域與生存期
?聲明與定義
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@17
量的作用域鳥可見他
?作用域與可見性
-作用域:標識符的有效范圍
-可見性:程序中某個位置是否可以使用某個標識符
-標識符僅在其作用域內(nèi)可見
-位于作用域內(nèi)的標識符不一定可見
?局部數(shù)據(jù)對象
-定義于函數(shù)或復(fù)合語句塊內(nèi)部的數(shù)據(jù)對象(包括變量、
常量與函數(shù)形式參數(shù)等)
-局部數(shù)據(jù)對象具有塊作用域,僅在定義它的塊內(nèi)有效
-有效性從定義處開始直到該塊結(jié)束
-多個函數(shù)定義同名的數(shù)據(jù)對象是允許的,原因?
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@18
局部撤據(jù)對象的作用域
intfunc(intx,inty)
(
intt;
t=x+y;
/*單獨出現(xiàn)的花括號對用于引入嵌套塊*/
(
/*允許在塊中定義數(shù)據(jù)對象,作用域僅限本塊*/
intn=2;
printf("n=%dAnM,n);
)
returnt;
)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@19
量的作用域鳥可見他
?全局數(shù)據(jù)對象
-定義于函數(shù)或復(fù)合語句塊之外的數(shù)據(jù)對象
-全局數(shù)據(jù)對象具有文件(全局)作用域,有效性從定義
處開始直到本文件結(jié)束,其后函數(shù)都可直接使用
-若包含全局數(shù)據(jù)對象定義的文件被其他文件包含,則其
作用域擴展到宿主文件中,這可能會導(dǎo)致問題,為什么?
-不要在頭文件中定義全局數(shù)據(jù)對象!
?函數(shù)原型作用域
-定義在函數(shù)原型中的參數(shù)具有函數(shù)原型作用域,其有效
性僅延續(xù)到此函數(shù)原型結(jié)束
-函數(shù)原型中參數(shù)名稱可以與函數(shù)實現(xiàn)中的不同,也可以
省略
清華大學(xué)計算機科學(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@21
量的存儲類鳥皮腐期
?生存期:量在程序中存在的時間范圍
-C使用存儲類表示生存期
-作用域表達量的空間特性,存儲類表達量的時間特性
?靜態(tài)(全局)生存期
-全局數(shù)據(jù)對象具有靜態(tài)(全局)生存期
-生死僅與程序是否執(zhí)行有關(guān)
?自動(局部)生存期
-局部數(shù)據(jù)對象具有自動(局部)生存期
-生死僅與程序流程是否位于該塊中有關(guān)
-程序每次進入該塊時就為該對象分配內(nèi)存,退出該塊時
釋放內(nèi)存;兩次進入該塊時使用的不是同一個數(shù)據(jù)對象
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@22
static關(guān)仇劣
?修飾局部變量:靜態(tài)局部變量
-使局部變量具有靜態(tài)生存期
-程序退出該塊時局部變量仍存在,并且下次進入該塊時
使用上一次的數(shù)據(jù)值
-靜態(tài)局部變量必須進行初始化
-不改變量的作用域,仍具有塊作用域,即只能在該塊中
訪問,其他代碼段不可見
?修飾全局變量
-使其作用域僅限定于本文件內(nèi)部,其他文件不可見
清華大學(xué)計算機科學(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@24
備般的作用減名金腐期
?所有函數(shù)具有文件作用域與靜態(tài)生存期
-在程序每次執(zhí)行時都存在,并且可以在函數(shù)原型或函數(shù)
定義之后的任意位置調(diào)用
?內(nèi)部函數(shù)與外部函數(shù)
-外部函數(shù):可以被其他文件中的函數(shù)所調(diào)用
-內(nèi)部函數(shù):不可以被其他文件中的函數(shù)所調(diào)用
-函數(shù)缺省時均為外部函數(shù)
-內(nèi)部函數(shù)定義:使用static關(guān)鍵字
-內(nèi)部函數(shù)示例:staticintTransform(intx);
-內(nèi)部函數(shù)示例:staticintTransform(intx){...}
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@25
戶明鳥靈文
?聲明不是定義
-定義在程序產(chǎn)生一個新實體
-聲明僅僅在程序中引入一個實體
?函數(shù)的聲明與定義
-聲明是給出函數(shù)原型,定義是給出函數(shù)實現(xiàn)代碼
?類型的聲明與定義
-產(chǎn)生新類型就是定義
-類型定義示例:typedefenum_BOOL{FALSE,
TRUE}BOOL;
-不產(chǎn)生新類型就不是定義,而僅僅是聲明
-類型聲明示例:enum_BOOL;
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@26
全局變量的作用域獷展
?全局變量的定義不能出現(xiàn)在頭文件中,只有其聲
明才可以出現(xiàn)在頭文件中
?聲明格式:使用extern關(guān)鍵字
〃庫的頭文件7
〃此處僅引入變量a,其定義位于對應(yīng)源文件中7
externinta;〃變量a可導(dǎo)出,其他文件可用7
〃庫的源文件7
〃定義變量a7
inta;
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@27
5.4宏
?宏替換
?含參宏
?宏與函數(shù)的差異
?宏的特殊用法
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@28
成蓍換
?編譯前進行簡單文本替換
STRINGNAME="TheFundamentalsSTRINGNAME=“The…”;
#defineFALSE0/*宏定義前的標識符不被替換*/
#defineTRUE1/*宏定義本身已不再需要*/
#defineNAME"QiaoLin"
intmain()intmain()
(
/*宏定義后標識符全被替換*/
STRINGMY_NAME=NAME;STRINGMY_NAME="QiaoLin";
/*字符串本身不會被替換*/
STRINGs="NAME";STRINGs="NAME";
if(a==TRUE)if(a==1)
)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@29
宏替換的基中原剜
?宏定義占用單獨一個文本行
?宏替換時,被替換文字不能是標識符的一部分
?宏定義中宏名稱之后的全部內(nèi)容都是替換文本,
包括該文本行后面的操作符號或標點符號
-設(shè)宏定義:#defineADDa+b;
-c=ADD被替換為c=a+b;
?可以使用已定義宏定義新宏
-#definePI3.14
-#defineAREAPl*r*r;
-area=AREA;被替換為area=3.14*r*r;
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@30
宏替換的基中原剜
?宏替換只發(fā)生一次,不會嵌套替換
-#definePI3.14
-#defineDPI*D*D
-area=D;被替換為area=3.14*D*D;
?宏定義總是出現(xiàn)在函數(shù)聲明或定義之外,一般放
置在頭文件的函數(shù)原型開始之前
?宏定義的有效性從定義處開始直到文件結(jié)束
?如果要提前取消某個宏定義,使用#undef指令
-#undefNAME
?宏的目的:降低改變同樣文本時的工作量;為特
定文字起個有意義的名稱,取代魔數(shù)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@31
金永肉
?定義格式
-#define宏名稱(參數(shù)列表)替換文本
-替換時,使用參數(shù)列表中的實際參數(shù)逐一替換后面宏的
替換文本中的形式參數(shù)
?定義與替換示例:看起來像函數(shù)
-#defineADD(x,y)x+y
-c=ADD(a,b);被替換為c=a+b;
-形式參數(shù)x被實際參數(shù)a替換,y被b替換
?含參宏的替換是直接替換
-#defineADD(x,y)x+y
-c=ADD(a+b,c);被替換為c=a+b+c;
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@32
含永宏
?替換文本中的操作符優(yōu)先級問題
-#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;
?解決方案:使用括號
-#definePI3.14
-#defineADD(x,y)((x)+(y))
-#defineAREA(r)(PI*(r)*(r))
-c=AREA(ADD(a,b));
-被替換為c=(PI*(((a)+(b)))*(((a)+(b))));
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@33
金參青易備照的異同
?函數(shù)形式參數(shù)與實際參數(shù)具有固定類型,并且保持一致;
含參宏的參數(shù)沒有類型要求,甚至可以不是數(shù)據(jù)對象
-示例:#defineMax(x,y)(x)>(y)?(x):(y)
-可以使用上述宏判斷整數(shù)或浮點數(shù)等類型數(shù)據(jù)的大小關(guān)系,C語
言是不允許為不同數(shù)據(jù)類型編寫同名函數(shù)的!
?函數(shù)調(diào)用在程序執(zhí)行時處理,含參宏在編譯前處理
?函數(shù)形式參數(shù)會在執(zhí)行時分配存儲空間,含參宏的參數(shù)不
會分配存儲空間,不會發(fā)生參數(shù)傳遞,也沒有返回值
?函數(shù)調(diào)用占用程序執(zhí)行時間,含參宏替換不占用程序執(zhí)行
時間,僅占用編譯時間
?函數(shù)調(diào)用節(jié)省程序代碼空間(多次調(diào)用使用同樣代碼),
含參宏浪費程序代碼空間(多次替換會使得代碼膨脹)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@34
宏的精殊用收
?略
?感興趣的可以自學(xué)
?閱讀zylib庫代碼需要了解這部分內(nèi)容
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@35
5.5條件編件
?略
?基礎(chǔ)知識:見頭文件的包含策略
?復(fù)雜內(nèi)容:感興趣的可以自學(xué),開發(fā)大型程
序才需要了解
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@36
5.6善型收件開或流程
?軟件工程概要
?問題的提出
?需求分析
?概要設(shè)計
?詳細設(shè)計
?編碼實現(xiàn)
?系統(tǒng)測試
?經(jīng)驗總結(jié)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@37
役件工程橢要
?需求分析:確定軟件需要解決什么問題
-決定因素:人
-軟件開發(fā)人員需要與用戶深入交流,明確問題的輸入、
輸出以及其他附加信息
-不要輕視任何問題!
?方案設(shè)計:設(shè)計程序框架
-概要設(shè)計:設(shè)計總體方案,形成高層模塊劃分
-詳細設(shè)計:細化模塊,獲得各模塊的輸入、輸出與算法
?編碼實現(xiàn):實際編程
?系統(tǒng)測試:測試程序的正確性與穩(wěn)定性
?經(jīng)驗總結(jié)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@38
決件開或海程圖
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@39
我件外或同敗
?我猜!我猜!我猜猜猜!
-編程實現(xiàn)一個簡單的猜價格游戲
-假設(shè)有某物品,已知其最低價格與最高價格
-游戲參與者在給定次數(shù)內(nèi)猜測其價格具體值
-若游戲者成功猜出其價格,作為獎勵將得到該
物品
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@40
需靠臺布
?需求A:游戲運行前首先應(yīng)向游戲參與者介紹游戲功能
?需求B:首期工程不需要解決游戲難度問題,用戶迫切希
望程序能在最短時間內(nèi)運行起來,因此只考慮最簡單情形
?需求C:在每個游戲回合結(jié)束時允許用戶選擇是否重新開
始新游戲,這里游戲回合是指游戲參與者或者猜中價格或
者其猜測機會已用完,如果用戶沒有選擇退出,游戲應(yīng)無
休止地玩下去
?需求D:能夠記錄游戲參與者的游戲信息,目前僅統(tǒng)計用
戶玩了多少回合以及贏了多少回合
?需求E:在用戶退出游戲時,給出此次游戲勝率
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@41
?不明確的地方:什么是最簡單情形?與用戶再次
溝通……
-需求B1:設(shè)物品最低價格為100元,最高價格為200元
-需求B2:物品實際價格由系統(tǒng)運行時隨機生成
-需求B3:游戲參與者最多允許猜6次
-需求B4:若游戲參與者猜測價格比實際價格高,則程
序提示“高”;若猜測價格比實際價格低,提示“低”
?用戶補充需求
-需求F:需要定義游戲初始化過程,未來有可能通過它
調(diào)整游戲難度,程序必須為此提供接口
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@42
倒要強什
?響應(yīng)需求A、E、F
-將游戲劃分為四個模塊:歡迎信息顯示模塊、游戲初始
化模塊、游戲模塊、游戲結(jié)束模塊
-程序架構(gòu):主文件“main.c”,程序主體函數(shù)庫
“guess.h”與“guess.c";此外需要使用zylib與
zyrandom庫
?設(shè)計函數(shù)原型
-勝率信息需要從游戲模塊傳遞給游戲結(jié)束模塊
-voidPrintWelcomelnfo();
-voidInitializeGameQ;
-doublePlayGame();
-voidPrintGameOverlnfo(doubleprevailed_ratio);
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@43
guess.h
#ifndef_EG0507GUESS_
#define_EG0507GUESS_
voidPrintWelcomelnfo();
voidInitializeGameQ;
doublePlayGame();
voidPrintGameOverlnfo(doubleprevailed_ratio);
#endif
清華大學(xué)計算機科學(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é)計算機科學(xué)與技術(shù)系E-mail:qiaolin@45
倒要強什
?響應(yīng)需求C
-使用無限循環(huán)作為游戲模塊的主架構(gòu):初始化游戲回合,
進行游戲回合,判斷游戲參與者是否開始新游戲回合
?響應(yīng)需求B2
-每一回合需要隨機生成物品價格,應(yīng)在游戲回合初始化
階段完成
-抽象出單獨的游戲回合初始化函數(shù),返回值為初始化的
物品價格(整數(shù)類型)
-intlnitializeBout();
?響應(yīng)需求D
-游戲參與者的回合數(shù)與獲勝回合數(shù):使用整數(shù)類型保存,
游戲開始時初始化為0,并隨著游戲進程變化
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@46
橢要強針
?游戲回合活動分析
-將每一回合游戲抽象成函數(shù),函數(shù)返回值為BOOL,表示該游戲
回合游戲參與者是否獲勝
-BOOLPlayBout();
?判斷用戶是否進入下一回合
-BOOLAgain();
-Again函數(shù)負責在PlayGame函數(shù)中充當哨兵,在返回值為
FALSE時退出游戲
?響應(yīng)需求B1、B3:數(shù)據(jù)初始化工作
-constintlowest_price=100;
-constinthighest_price=200;
-constintguesstimate_count=6;
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@47
?響應(yīng)需求B4:細化PlayBout
-在給定猜測次數(shù)內(nèi)接受游戲參與者的輸入價格,判斷與
實際價格是否相同,如果不同則給出提示信息,如果相
同則恭喜游戲參與者獲勝
-但是……
?需求G:一旦游戲參與者給出了猜測價格,當該
價格或高或低時,提示游戲參與者的信息應(yīng)能夠
相應(yīng)縮小價格區(qū)間以反映此變化
?響應(yīng)需求G:修改PlayBout函數(shù),添加參數(shù)
-BOOLPlayBout(intactual_price,intlower_price,
inthigher_price,intchancesjeft);
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@48
?歡迎信息模塊設(shè)計
-要求:將游戲性質(zhì)與游戲方法告訴游戲參與者,
系統(tǒng)應(yīng)盡可能輸出詳細信息,例如物品最低價
格、最高價格與猜測次數(shù)都應(yīng)通知游戲參與者
?偽代碼
voidPrintWelcomelnfo()
(
輸出程序性質(zhì)信息
物品最低價格、最高價格與猜測次數(shù)一并輸出
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@49
?游戲初始化模塊設(shè)計
-要求:不知道
?偽代碼
voidlnitializeGame()
(
)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@50
?游戲結(jié)束模塊設(shè)計
-要求:如果能夠在游戲結(jié)束模塊不僅輸出游戲參與者勝率,還針
對其勝率高低輸出不同鼓勵信息就好了
?需求H:當游戲參與者勝率超過75%(含)時,輸出
“Youluckyyyyyyyyyyyyy!^^;當勝率低于75%但超過
50%(含)時,輸出“SogoooooooocL”;其他輸出
“Youcandoitbetter.Wishyouluck.”
?偽代碼
voidPrintGameOverlnfo(doubleprevailed_ratio)
(
輸出百分制勝率
根據(jù)勝率分別輸出不同信息
)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@51
?游戲模塊細化
?偽代碼
doublePlayGameQ
(
while(TRUE){
調(diào)用IrMtializeBout獲得實際價格
調(diào)用PgyBout啟動游戲回合
如果游戲回合結(jié)束后結(jié)果為TRUE,遞增獲勝回合數(shù)
遞增總回合數(shù)
調(diào)用[gain,若結(jié)果為FALSE,終止游戲,否則繼續(xù)
}
返回最終勝率
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@52
?游戲回合初始化與游戲初始化模塊細化
?偽代碼
intlnitializeBout()
(
調(diào)用GenerateRandomNumber函數(shù)
并返回其結(jié)果
}
voidlnitializeGame()
(
調(diào)用Randomize函數(shù)啟動隨機數(shù)發(fā)生器
)
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@53
?游戲回合模塊細化
?需求I:如果游戲參與者給出的猜測價格不在當時
價格范圍內(nèi),應(yīng)提醒用戶重新提供新價格,此次
操作不應(yīng)遞減用戶猜測次數(shù),以防止用戶輸入錯
誤,也就是說,需要檢查猜測價格的合法性
?需求J:當最后一次機會也未猜中價格時,不需
要再輸出提示價格高低信息,直接輸出用戶本回
合失敗信息,并將實際價格告訴用戶
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@54
BOOLPlayBoutfintactual_price,intlower_price,inthigher_price,intchancesjeft){
while(還有猜測機會){
獲得游戲參與者猜測價格,檢查游戲參與者猜測價格是否在給定范圍
遞減游戲參與者猜測機會
判斷猜測價格高低
switch(判斷結(jié)果){
case高了:
if(還有猜測機會){輸出價格高了信息,降低最高價格值,縮小猜測區(qū)間}
else{輸出失敗信息與物品實際價格,結(jié)束函數(shù),返回本回合失敗值FALSE}
break;
case低了:
if(還有猜測機會){輸出價格低了信息,增大最低價格值,縮小猜測區(qū)間}
else{輸出失敗信息與物品實際價格,結(jié)束函數(shù),返回本回合失敗值FALSE}
break;
default:
輸出游戲參與者獲勝信息,結(jié)束函數(shù),返回TRUE
}
}
程序流程至此,說明游戲參與者本回合已失敗,返回FALSE
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@55
?進一步細化游戲回合函數(shù)
-抽象三個輔助函數(shù)
-獲得游戲參與者猜測價格:int
GetGuesstimatePrice(intlower_price,int
higher_price,intchancesjeft);
-檢查游戲參與者猜測價格是否在給定范圍:int
CheckValidationOfGuesstimatePrice(int
lower_price,inthigher_price,int
guesstimate_price);
-判斷猜測價格高低:intJudgeGuesstimatePrice(int
actual_price,intguesstimate_price);
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@56
intGetGuesstimatePrice(intlower_price,inthigher_price,intchancesjeft)
(
輸出提示信息,包括最低價格,最高價格與剩余猜測次數(shù)
調(diào)用GetlntegerFromKeyboard獲取猜測價格并返回
}
intCheckValidationOfGuesstimatePrice(intlower_price,inthigher_price,int
guesstimate_price)
(
while(猜測價格小于最低價格或高于最高價格){
通知游戲參與者猜測價格超出范圍,提醒用戶重新輸入新價格
調(diào)用GetlntegerFromKeyboard獲取新猜測價格
}
返回新猜測價格
}
intJudgeGuesstimatePrice(intactuaLprice,intguesstimate_price)
(
獲得猜測價格與實際價格之差
if(差值大于0)return1;elseif(差值小于0)return-1;elsereturn0;
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@57
?細化Again函數(shù)
?Zylib庫的字符串比較函數(shù)
-BOOLlsStringEqual(STRINGs1,STRINGs2)
-BOOLIsStringEqualWithoutCasefSTRINGs1,STRINGs2)
?偽代碼
BOOLAgainQ
(
詢問游戲參與者是否開始新游戲
獲取游戲參與者的響應(yīng)
調(diào)用ilsStringEqualWithoutCase函數(shù),
判斷游戲參與者的響應(yīng)是否為“n”
如果真,返回FALSE,即將上述返回值取反返回
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@58
清華大學(xué)計算機科學(xué)與技術(shù)系E-mail:qiaolin@59
編居實猊
#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é)計算機科學(xué)與技術(shù)系Email:qiaolin@60
編居實猊
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é)計算機科學(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é)計算機科學(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é)計算機科學(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é)計算機科學(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é)計算機科學(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等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年防雷防爆及弱電工程設(shè)備項目合作計劃書
- 甘肅省武威市涼州區(qū)2024-2025學(xué)年高二下學(xué)期第一次質(zhì)量檢測英語試卷(原卷版+解析版)
- 勞務(wù)派遣勞動者法律權(quán)益保障的問題與改進策略研究
- 供應(yīng)鏈管理在DB化學(xué)公司的應(yīng)用研究
- 江蘇省大病保險助推精準扶貧的運行情況研究
- 維生素D對糖尿病小鼠腎臟并發(fā)癥保護作用的初步研究
- pe管道合同范本
- 2025屆高考思想政治二輪復(fù)習專題強化練八含解析
- 2025年基礎(chǔ)地質(zhì)勘查服務(wù)合作協(xié)議書
- ppp污水合同范例
- 基于STM32F103C8T6單片機的電動車智能充電樁計費系統(tǒng)設(shè)計
- 2024年4月自考02791家畜傳染病與寄生蟲病試題
- 2024年常德職業(yè)技術(shù)學(xué)院單招職業(yè)技能測試題庫及答案解析
- 模板工程風險辨識及防范措施
- 《紅樓夢第五回》課件2
- 縫紉工(技師)理論考試復(fù)習題庫(匯總)
- 2024年中國移動校園招聘高頻考題難、易錯點模擬試題(共500題)附帶答案詳解
- 《C語言從入門到精通》培訓(xùn)教程課件
- 羔羊胃提取物維B12膠囊治療慢性萎縮性胃炎伴腸化的臨床療效觀察
- 2023年陜西省高中學(xué)業(yè)水平考試樣卷歷史試卷試題(含答案詳解)
- 2024年鎮(zhèn)江市高等專科學(xué)校高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
評論
0/150
提交評論