C++程序设计:第8-9章_第1页
C++程序设计:第8-9章_第2页
C++程序设计:第8-9章_第3页
C++程序设计:第8-9章_第4页
C++程序设计:第8-9章_第5页
已阅读5页,还剩127页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C++程序设计

第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体的概念打印学生成绩单,格式如下:学号姓名语文成绩数学成绩英语成绩.00001张三96948800003李四89707600004王五908778如何在程序中表示这组学生信息?可选方案用二维的数组来表示该方案不可行,因为这些信息有不同的类型每一列用一个一维数组来表示,这种方法称为并联数组。要保证每位学生信息的完整性和正确性很难为什么要使用记录当我们考虑怎么逻辑地组织数据时,应该将一个人的所有信息项放在一起,即保持相关性。学号姓名语文成绩数学成绩英语成绩.00001张三96948800003李四89707600004王五908778我

构学生一00001张三969488学生二00003李四897076学生三00004王五908778记录在C++中称为结构体结构体类型作用结构体类型允许程序员把一些分量聚合成一个整体,用一个变量表示。一个结构体的各个分量都有名字,把这些分量称为成员(member)。由于结构体的成员可以是各种类型的,程序员能创建适合于问题的数据聚合。结构体的使用定义一个新的结构体类型定义新类型的变量访问结构体变量第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体类型的定义定义结构体类型中包括哪些分量格式:struct

结构体类型名{字段声明;};如:struct

studentT{charno[10];charname[10];

int

chinese;

intmath;

int

english;};注意字段名可与程序中的变量名相同在不同的结构体中可以有相同的字段名结构体成员的类型可以是任意类型,当然也可以是结构体类型struct

dateT{ intmonth;

intday;

intyear;};struct

studentT{ ...

dateTbirthday;};

第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间结构体变量的定义结构体变量的定义和普通的变量定义一样。如定义了结构体类型studentT,就可以定义结构体变量:

studentTstudent1;一旦定义了一个结构体类型的变量,系统在分配内存时就会分配一块连续的空间,依次存放它的每一个分量。这块空间总的名字就是结构体变量的名字。内部还有各自的名字

englishmathchinesenamenostudent1结构体变量的初始化studentTstudent1={“00001”,“张三”,87,90,77};

定义结构体类型的同时定义变量struct

结构体类型名{

字段声明;}结构体变量;struct

结构体类型名{

字段声明;};结构体类型名结构体变量;struct

studentT{charno[10];…}student1;struct

studentT{charno[10];…};studentTstudent1;studentTstudent2,student3;定义结构体类型的同时定义变量(cont.)struct

结构体类型名{

字段声明;}结构体变量;struct{

字段声明;}结构体变量;struct

studentT{charno[10];…}student1;studentTstudent2,student3;不能继续定义变量struct{charno[10];…}student1;结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间结构体变量的访问成员的表示:

结构变量名.成员名

如:

如结构中还有结构,则一级一级用”.”分开,如如:student1.birthday.year对结构体类型变量的引用一般为引用他的成员结构变量的赋值结构体变量的赋值通常是通过对它的每一个成员的赋值而实现。如:输入student1的内容可用:cin>>student1.no>>>>student1.chinese>>student1.math>>student1.english>>student1.birthday.year>>student1.birthday.month>>student1.birthday.day;同类型的结构变量之间可以相互赋值,如student1=student2;将student2的成员对应赋给student1的成员结构变量的赋值(cont.)同类型的结构变量之间可以相互赋值,如

student1=student2;将student2的成员对应赋给student1的成员student1.no=student2.no;=;student1.chinese=student2.chinese;…结构变量的输出结构体变量的输出通常是通过输出它的每一个成员而实现。如:输出student1的内容可用:cout<<student1.no<<<<student1.chinese<<student1.math<<student1.english<<student1.birthday.year<<student1.birthday.month<<student1.birthday.day;结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间指向记录的指针直接定义指针变量

studentT*sp;也可以在定义结构体类型的同时定义指向结构体的指针struct

结构体类型名{

字段声明;}*结构体指针;通过指针操作记录给结构体指针赋值,如:

sp=&student1;(*指针).成员

如:(*sp).name

指针->成员如:sp->namestudent1.成员

->是所有运算符中优先级最高的

通常程序员习惯使用第二种方法结构体指针的引用:结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间动态分配结构体的空间指向结构体指针的另一种用法是存储动态申请到的内存的首地址。用法和申请普通的动态变量一样。如:

studentT*sp;sp=newstudentT;第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表

结构体数组用于描述个体的集合定义格式:

studentT

studentArray[SIZE];结构体数组的引用引用数组的某一成员的成员

studentArray[3].name数组成员之间相互赋值

studentArray[4]=studentArray[2]结构数组的初始化

studentTstudentArray[5]={{“00001”,张三“,80,90,98},{…},{…},{…}};统计候选人得票。设有三个候选人,每次输入一个得票的候选人编号(1-3),要求最后输出各人得票结果。

struct

personT{intid;

intcount;}leader[3]={1,0,2,0,3,0};

intmain(){inti,j,inputID;for(i=1;i<=10;++i){cin>>inputID;if(inputID<1||inputID>3){cout<<“废票”;continue;}leader[inputID-1].count+=1;}

cout<<endl;for(i=0;i<3;++i)

cout<<leader[i].id<<““<<leader[i].count);return0;}

例:输出通讯录

#include<iostream>#include<iomanip>usingnamespacestd;struct

personT{charname[10];charsex;charaddr[30];

int

phonenum;};constintMAX=100;intmain(){personT

p[MAX];

inti,num=0;

cout<<"姓名性别地址电话(@表示结束):\n";while(num<100){

cin>>p[num].name;if(p[num].name[0]=='@')break;

cin>>p[num].sex>>p[num].addr>>p[num].phonenum;

++num;}cout<<"Name"<<"Sex\t\t"<<"Addr\t\t\t"<<"PhoneNum\n";

cout<<setiosflags(ios::left);for(i=0;i<num;++i)

cout<<setw(10)<<p[i].name<<p[i].sex<<'\t‘<<setw(30)<<p[i].addr<<'\t'<<p[i].phonenum<<endl;return0;}指针与结构体数组与普通的指针一样,指向结构体的指针也能够用来指向一个结构体数组。此时,对指针加1就是加了该结构体的大小。第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表voidswap2(int*a,int*b){

inttemp;temp=*a;*a=*b;*b=temp;}voidswap1(inta,intb){

inttemp;temp=a;a=b;b=temp;}intmain(){intx=4,y=6;

swap1(x,y);

cout<<“x=“<<x<<“y=“<<y<<endl;}swap2(&x,&y);swap3(x,y);voidswap3(int&a,int&b){

inttemp;temp=a;a=b;b=temp;}结构体作为参数传递尽管结构体和数组一样也有许多分量组成,但结构体的传递和普通内置类型是一样的。它是将实际参数中的每个分量复制到形式参数的每个分量中。结构体的传递voidPrintPerson(PersonTp)指向结构体的指针作为参数因为结构体是值传递,当希望把函数内部对结构体的修改返回给主调函数时,可以用指针传递或引用传递由于结构体一般占用的内存量都比较大,值传递既浪费空间又浪费时间。因此可用指针传递或引用传递指针传递形式比较繁琐,所以C++通常用引用传递引用传递的问题是函数中可以修改实际参数,要控制函数中不能修改实际参数,可以加const限定指向结构体的指针作为参数和普通的指针传递一样,函数中可以通过指针访问主调函数的记录减少函数调用时的数据传递量voidPrintPerson(personT&p);voidPrintPerson(const

personT&p);结构体传递的实例设计一函数,打印学生信息设计一:值传递voidPrintStudent(studentTs){cout<<s.no<<‘\t’<<<<‘\t’<<s.chinese<<‘\t’<<s.math<<‘\t’<<s.english<<endl;}缺点:浪费时间空间设计二:指针传递或引用传递voidPrintStudent(studentT*s){cout<<s->no<<‘\t’<<s->name<<‘\t’<<s->chinese<<‘\t’<<s->math<<‘\t’<<s->english<<endl;}voidPrintStudent(studentT&s){cout<<s.no<<‘\t’<<<<‘\t’<<s.chinese<<‘\t’<<s.math<<‘\t’<<s.english<<endl;}缺点:不安全设计三:C++的常规做法voidPrintStudent(const

studentT&s){cout<<s.no<<‘\t’<<<<‘\t’<<s.chinese<<‘\t’<<s.math<<‘\t’<<s.english<<endl;}特点:节约内存,提高函数调用速度,可靠返回结构体类型的函数一个函数返回一个结构体。如:personT

GetPersonData(){personTperson;…….return(person);}返回的是一个结构体的复制。在主调函数中必须有这样的程序段:voidmain(){personTp1,p2;p1=GetPersonData();}返回结构体引用的函数函数返回一个结构体的引用。如:personT&GetPersonData(void){personT*person=newpersonT;…….return(*person);}本质上返回的是结构体的地址。在主调函数中可以有这样的程序段:main(){personT&p1=GetPersonData();…}

函数中返回的结构体不能是局部变量第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表单链表链表的概念链表的存储链表的操作链表的应用循环链表单链表nilhead只指出后继关系的链表…单链表nilhead头结点只指出后继关系的链表…双链表

head循环链表

head同时存储前趋和后继……单链表链表的概念链表的存储链表的操作链表的应用循环链表单链表的存储struct

linkRec{

datatypedata;

linkRec*next;};单链表链表的概念链表的存储链表的操作链表的应用循环链表单链表操作—插入申请空间输入数据放入申请到的空间链入p后在结点p后插入一个结点

headptmp…tmp=newlinkRec;//创建一个新节点tmp->data=x;//把x放入新节点的数据成员中tmp->next=p->next;//把新节点和p的下一成员相连p->next=tmp;//把p和新节点连接起来

单链表操作—删除把结点p后的结点删除headpdelPtrdelPtr=p->next;p->next=delPtr->next;deletedelPtr;

单链表操作--建立定义头指针:linkRec*head;建立头结点申请空间设为头结点head单链表操作--建立(续)逐个从键盘输入数据,存入链表

接受输入申请空间输入数据放入申请到的空间链入链表尾置链表结束标志headabcd^head=newlinkRec;rear=head;cin>>in_data;while(输入未结束){p=newlinkRec;p->data=in_data;rear->next=p;rear=p;

cin>>in_data;}rear->next=NULL;

单链表操作—输出headabcd^p=head->next;while(p!=NULL){cout<<p->data;p=p->next;}

创建并访问一个带头结点的、存储整型数据的单链表,数据从键盘输入,0为输入结束标志。#include<iostream>usingnamespacestd;

struct

linkRec{

intdata;

linkRec*next;};intmain(){intx;//存放输入的值

linkRec*head,*p,*rear;

head=rear=newlinkRec;

while(true){//创建链表的其他结点

cin>>x;if(x==0)break;p=newlinkRec; p->data=x;rear->next=p;rear=p; }

rear->next=NULL; //设置rear为表尾,其后没有结点了

//读链表

cout<<"链表的内容为:\n";p=head->next;while(p!=NULL){cout<<p->data<<'\t';p=p->next;}

cout<<endl;

return0;}单链表链表的概念链表的存储链表的操作链表的应用循环链表链表的应用合并二个有序链表

A1356274B981C187654329struct

lk{intdata;

lk*next;};

struct

lk*merge(struct

lk*a,struct

lk*b){struct

lk*c,*p;if(a->data<b->data){c=a;a=a->next;}else{c=b;b=b->next;}p=c;while(a!=NULL&&b!=NULL){if(a->data<b->data){p->next=a;a=a->next;}else{p->next=b;b=b->next;}p=p->next;}if(a==NULL)p->next=b;elsep->next=a;return(c);}

单链表链表的概念链表的存储链表的操作链表的应用循环链表例:n个人围成一圈,从第一个人开始报数1、2、3。凡报到

3者退出圈子。找出最后留在圈子中的人的序号。

解。用循环链表

01243head当n=5时,其删除的节点的顺序为2,0,4,1,最后剩下的节点为3。

循环链表的应用—约瑟夫环structnode{intdata;node*next;};intmain(){node*head,*p,*q;//head为链表头

intn,i;//输入n

cout<<"\ninputn:";cin>>n;//建立链表

head=p=newnode;p->data=0;//p指向表尾

for(i=1;i<n;++i){q=newnode;//q为当前正在创建的节点

q->data=i;p->next=q;p=q;//将q链入表尾

}p->next=head;//头尾相连

//删除过程

q=head;while(q->next!=q)//只要表非空

{for(i=0;i<2;++i)//报数,

{p=q;q=p->next;}p->next=q->next;//绕过节点q

cout<<q->data<<'\t';//显示被删者的编号

deleteq; //回收被删者的空间

q=p->next;//让q指向报1的节点

}//打印结果

cout<<"\n最后剩下:"<<q->data<<endl;return0;}

链表总结实现较复杂插入、删除效率高,但查找第i个元素效率低无表满的问题适合于动态表总结本章介绍了结构体作用:处理更复杂的数据使用:定义类型定义变量链表选择题链表结点的结构类型为。

struct

linkRec{intdata;linkRec*next;};如果指针rear指向尾结点,将节点p链入表尾,并将p作为新的表尾可用语句()

A、rear->next=p->next;rear=p;B、rear->next=p;rear=p;C、rear->next=rear;p->next=p;D、(*rear).next=rear;(*p).next=p;选择题对结构体变量stu1中成员age的非法引用是()struct

studentT{

intnum;floatage;};studentTstu1,*p;p=&stu1;A.stu1.ageB.studentT.age

C.p->ageD.(*p).age

第9章模块化开发自顶向下的分解模块划分库的设计与实现库的应用猜硬币的游戏功能:提供游戏指南;计算机随机产生正反面,让用户猜,报告对错结果。重复此过程,直到用户不想玩了为止。这是一个猜硬币正反面的游戏。我会扔一个硬币,你来猜。如果猜对了,你赢,否则我赢。输入你的选择(0表示正面,1表示反面):1我赢了继续玩吗(Y或y)?y输入你的选择(0表示正面,1表示反面):6输入你的选择(0表示正面,1表示反面):1你赢了继续玩吗(Y或y)?nPressanykeytocontinue运行实例顶层分解程序要做两件事:显示程序指南;模拟玩游戏的过程。main(){

显示游戏介绍;玩游戏;}主程序的两个步骤是相互独立的两个,没有什么联系,因此可设计成两个函数:voidprn_instruction()voidplay()intmain(){

prn_instruction();play();return0;}prn_instruction的实现prn_instruction函数的实现非常简单,只要一系列的输出语句把程序指南显示一下就可以了voidprn_instruction(){cout<<"这是一个猜硬币正反面的游戏.\n";

cout<<"我会扔一个硬币,你来猜.\n";

cout<<"如果猜对了,你赢,否则我赢。\n";}play函数的实现play函数随机产生正反面,让用户猜,报告对错结果,然后询问是否要继续玩voidplay(){charflag=‘y’;while(flag==‘Y’||flag==‘y’)

{coin=生成正反面;

输入用户的猜测;

if(用户猜测==coin)报告本次猜测结果正确;

else报告本次猜测结果错误;

}}play函数的细化生成正反面:如果用0表示正面,1表示反面,那么生成正反面就是随机生成0和1两个数。输入用户的猜测。如果不考虑程序的鲁棒性,这个问题也可以直接用一个输入语句即可。但想让程序做得好一点,就必须考虑得全面一些。比如,用户可以不守规则,既不输入0也不输入1,而是输入一个其他值,程序该怎么办?因此这个任务还可以进一步细化,所以再把它抽象成一个函数get_call_from_user。voidplay(){intcoin;charflag='Y';

srand(time(NULL));//设置随机数种子

while(flag=='Y'||flag=='y'){coin=rand()%2;//生成扔硬币的结果

if(get_call_from_user()==coin)cout<<"你赢了";elsecout<<"我赢了";

cout<<"\n继续玩吗(Y或y)?";

cin>>flag;}}get_call_from_user的实现该函数接收用户输入的一个整型数。如果输入的数不是0或1,则重新输入,否则返回输入的值int

get_call_from_user(){intguess;//0=head,1=taildo{cout<<"\n输入你的选择(0表示正面,1表示反面):";

cin>>guess;}while(guess!=0&&guess!=1);returnguess;}第9章模块化开发自顶向下的分解模块划分库的设计与实现库的应用模块划分当程序变得更长的时候,要在一个单独的源文件中处理如此众多的函数会变得困难把程序再分成几个小的源文件。每个源文件都包含一组相关的函数。一个源文件被称为一个模块。模块划分标准:块内联系尽可能大,块间联系尽可能小

石头、剪刀、布游戏游戏规则布覆盖石头石头砸坏剪刀剪刀剪碎布游戏的过程为:游戏者选择出石头、剪子或布,计算机也随机选择一个,输出结果,继续游戏,直到游戏者选择结束为止。在此过程中,游戏者也可以阅读游戏指南或看看当前战况。第一层的分解while(用户输入!=quit){switch(用户的选择)

{casepaper,rock,scissor:机器选择;评判结果;报告结果;

casegame:显示目前的战况;

casehelp:显示帮助信息;

default:报告错误;

}}显示战况;函数抽取获取用户输入selection_by_player获取机器输入selection_by_machine评判结果compare报告结果并记录结果信息report显示目前战况prn_game_status显示帮助信息prn_help六个函数枚举类型的定义为了提高程序的可读性,我们定义两个枚举类型:

enum

p_r_s{paper,rock,scissor,game,help,quit};

enumoutcome{win,lose,tie,error};模块划分分成四个模块:主模块:main函数获取选择的模块:selection_by_player和

selection_by_machine比较模块:compare输出模块:report、prn_game_status和

prn_help函数select模块的设计selection_by_player从键盘接收用户的输入并返回此输入值。因此,原型为

p_r_s

selection_by_player();selection_by_machine函数由机器产生一个石头、剪子、布的值,并返回。因此,原型为

p_r_s

selection_by_machine();compare模块的设计compare函数比较用户输入的值和机器产生的值,确定输赢。它要有两个参数,都是p_r_s类型的,它也应该有一个返回值,就是判断的结果。原型为:outcomecompare(p_r_s,p_r_s);

print模块的设计prn_help显示一个用户输入的指南,告诉用户如何输入他的选择。因此,它没有参数也没有返回值。report函数报告输赢结果,并记录输赢的次数。因此它必须有四个参数:输赢结果、输的次数、赢的次数和平局的次数,但没有返回值。prn_game_status函数报告至今为止的战况,因此需要三个参数:输的次数、赢的次数和平的次数,但没有返回值。print模块的进一步考虑输的次数、赢的次数和平局的次数在report和prn_game_status两个函数中都出现。report函数修改这些变量的值,prn_game_status函数显示这些变量的值。这三个函数的原型和用户期望的原型不一致,用户不希望原型中有参数。输的次数、赢的次数和平局的次数和其他模块的函数无任何关系,因此可作为该模块的内部状态。内部状态可以作为该模块的全局变量这样report和prn_game_status函数中都不需要这三个参数了。头文件的设计为方便起见,我们把所有的符号常量定义、类型定义和函数原型声明写在一个头文件中,让每个模块都include这个头文件。那么,每个模块就不必要再写那些函数的原型声明了但这样做又会引起另一个问题,当把这些模块连接起来时,编译器会发现这些类型定义、符号常量和函数原型的声明在程序中反复出现多次。解决方法:需要用到一个新的编译预处理命令:#ifndef

标识符…#endif

头文件的格式#ifndef

_name_h#define_name_h

头文件真正需要写的内容#endif石头、剪子、布游戏的头文件//文件:p_r_s.h//本文件定义了两个枚举类型,声明了本程序包括的所有函数原型#ifndefP_R_S#defineP_R_S

#include<iostream>#include<cstdlib>#include<ctime>usingnamespacestd;

enum

p_r_s{paper,rock,scissor,game,help,quit};

enumoutcome{win,lose,tie,error};

outcomecompare(p_r_s

player_choice,p_r_s

machine_choice);voidprn_final_status();voidprn_game_status();voidprn_help();voidreport(outcomeresult);

p_r_s

selection_by_machine();

p_r_s

selection_by_player();#endif主模块的实现//文件:main.cpp//石头、剪子、布游戏的主模块#include"p_r_s.h"int

main(void){outcomeresult;

p_r_s

player_choice,machine_choice;//seedtherandomnumbergenerator

srand(time(NULL));

while((player_choice=selection_by_player())!=quit)

switch(player_choice){casepaper:caserock:casescissor:

machine_choice=selection_by_machine();result=compare(player_choice,

machine_choice);

report(result);break;casegame:prn_game_status();break;casehelp:prn_help();break;default:

cout<<"PROGRAMMERERROR!\n\n";exit(1);}

prn_game_status();return0;}select模块的实现//文件:select.cpp//包括机器选择selection_by_machine和//玩家选择selection_by_player函数的实现#include"p_r_s.h"p_r_s

selection_by_machine(){intselect=rand()%3;

cout<<"Iam";

switch(select){case0:cout<<"paper.";break;case1:cout<<"rock.";break;case2:cout<<"scissor.";break;

}return((p_r_s)select);}p_r_s

selection_by_player(){charc;

p_r_s

player_choice;

prn_help();//显示输入提示

cout<<"pleaseselect:";cin>>c;

switch(c){case'p':player_choice=paper;cout<<"youarepaper.";break;case'r':player_choice=rock;cout<<"youarerock.";break;case's':player_choice=scissor;cout<<"youarescissor.";break;case'g':player_choice=game;break;case'q':player_choice=quit;break;default:player_choice=help;break;

}returnplayer_choice;}compare模块的实现//文件:compare.cpp

//包括compare函数的实现#include"p_r_s.h"outcomecompare(p_r_s

player_choice,p_r_s

machine_choice){outcomeresult;if(player_choice==machine_choice)returntie;

switch(player_choice){casepaper:result=(machine_choice==rock)?win:lose;break;caserock:result=(machine_choice==scissor)?win:lose;break;casescissor:result=(machine_choice==paper)?win:lose;break;default:cout<<"PROGRAMMERERROR:Unexpectedchoice!\n\n";

exit(1);}returnresult;}Print模块的实现//文件:print.cpp//包括所有与输出有关的模块。//有prn_game_status,prn_help和report函数#include"p_r_s.h"int

win_cnt=0,lose_cnt=0,tie_cnt=0;//模块的内部状态voidreport(outcomeresult){switch(result){casewin:++win_cnt;

cout<<"Youwin.\n";break;caselose:++lose_cnt;

cout<<"Youlose.\n";break;

casetie:++tie_cnt;cout<<"Atie.\n";break;

default:

cout<<"PROGRAMMERERROR!\n\n";

exit(1);}}voidprn_game_status(){cout<<endl;

cout<<"GAMESTATUS:"<<endl;

cout<<"win:"<<win_cnt<<endl;

cout<<"Lose:"<<lose_cnt<<endl;cout<<"tie:"<<tie_cnt<<endl;

cout<<"Total:"<<win_cnt+lose_cnt+tie_cnt<<endl;}voidprn_help(){cout<<endl<<"Thefollowingcharacterscanbeused:\n"

<<"pforpaper\n"<<"rforrock\n"

<<"sforscissors\n"<<"gprintthegamestatus\n"<<"hhelp,printthislist\n"<<"qquitthegame\n";}第9章模块化开发自顶向下的分解模块划分库的设计与实现库的应用设计自己的库如果你的工作经常要用到一些特殊的工具,你可以设计自己的库。一个库应该有一个主题。一个库中的函数都应该是处理同一类问题。如标准库iostream包含输入输出功能,cmath包含数学运算函数。我们自己设计的库也要有一个主题。设计一个库还要考虑到它的通用性。库中的功能应来源于某一应用,但不局限于该应用,而且要高于该应用。在某一应用程序中提取库内容时应尽量考虑到兼容更多的应用,使其他应用程序也能共享这个库。库的设计和实现设计库的接口:库的用户必须了解的内容,包括库中函数的原型、这些函数用到的符号常量和自定义类型接口表现为一个头文件设计库中的函数的实现:表现为一个源文件库的这种实现方法称为信息隐藏随机函数库的设计库的功能在9.1中,用到了随机生成0和1在9.2中,用到了随机生成0和2在自动出题中,用到了随机生成0和3及随机生成0到9用一个函数概括:生成low到high之间的随机数

intRandomInteger(intlow,inthigh)

初始化函数RandomInit()实现设置随机数种子的功能在9.1节中,设计了一个掷硬币的程序。该程序用到了随机数的一些特性。如果我们的工作经常需要用到随机数,我们可以把随机数的应用写成一个库。接口文件头文件的格式:与石头、剪子、布游戏中的头文件格式一样。头文件中,每个函数声明前应该有一段注释,告诉用户如何使用这些函数。库接口的设计//文件:Random.h//随机函数库的头文件#ifndef_random_h#define_random_h//函数:RandomInit//用法:RandomInit()//作用:此函数初始化随机数种子voidRandomInit();//函数:RandomInteger//用法:n=RandomInteger(low,high)//作用:此函数返回一个low到high之间的随机数,包括low和highint

RandomInteger(intlow,inthigh);#endif库的实现库的实现文件和头文件的名字是相同的。如头文件为Random.h,则实现文件为Random.cpp。实现文件的格式:注释:这一部分简单介绍库的功能。include此cpp文件所需的头文件。每个实现要包含自己的头文件,以便编译器能检查函数定义和函数原型声明的一致性。每个函数的实现代码。在每个函数实现的前面也必须有一段注释。//文件:Random.cpp//该文件实现了Random库#include<cstdlib>#include<ctime>#include"Random.h"//函数:RandomInit//该函数取当前系统时间作为随机数发生器的种子voidRandomInit(){

srand(time(NULL));}//函数:RandomInteger

intRandomInteger(intlow,inthigh){return(low+rand()/(high–low+1));}第9章模块化开发自顶向下的分解模块划分库的设计与实现库的应用库的应用--龟兔赛跑动物跑动类型占用时间跑动量乌龟快走50%向前走3点后滑20%向后退6点慢走30%向前走一点兔子睡觉20%不动大后滑20%向后退9点快走10%向前走14点小步跳30%向前走3点慢后滑20%向后退2点龟兔赛跑解题思路分别用变量tortoise和hare代表乌龟和兔子的当前位置时

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论