《软件工程导论第6版》--张海藩 牟永敏 课后答案及其详解 第5章 总体设计

第1题

1.为每种类型的模块耦合举一个具体例子。
耦合式对一个软件结构内不同模块之间互联程度的度量。耦合强弱取决于接口的复杂度,进入或访问某一模块的点,以及通过接口的数据。一般模块之间的可能的连接方式有七种,构成耦合的七种类型,它们的关系为:
在这里插入图片描述
下面举例说明以上耦合:
A.非直接耦合:两个模块没有直接的关系(模块1和模块2),独立性最强
在这里插入图片描述
B.数据耦合:即一个模块访问另一个模块的时候,彼此之间是通过数据参数来交换输入、输出信息的,这种耦合为数据耦合。这种耦合较为松散,模块间独立性较强。
在这里插入图片描述
C.特征耦合:即一组模块通过参数传递记录信息,用户情况是个数据结构,图中模块都与此有关,"计算水费"和"计算电费"本没有关系,由于引用了此数据结构产生了依赖关系。
在这里插入图片描述
D.控制耦合:即如果一个模块通过传递开关、标志、名字等控制信息,明显地控制选择另一模块的功能,就是控制耦合
在这里插入图片描述
E.外部耦合:一组模块都访问同一全局数据结构,而且不是通过参数表传递该分局变量的信息,则称之为外部耦合。
在这里插入图片描述
F.公共耦合:若一组模块都访问同一个公共数据环境,则它们之间的耦合就称为公共耦合。
在这里插入图片描述
G.内容耦合:如果出现以下情况之子,两个模块就发生了内容耦合。
①一个模块访问另一个模块的内部数据。
②一个模块不通过正常入口儿转到另一个模块的内部。
③两个模块有一部分程序代码重叠(只可能发生在汇编程序中)
④一个模块有多个入口(这意味着一个模块有几种功能)
Sub AA(…)


Goto L

End sub
Sub BB(…)


L:…

End sub

第2题

2.为每种类型的模块内聚集一个具体例子。
答:内聚标志着一个模块内各个元素之间彼此结合的紧密程度,它是信息隐藏和局部化概念的自然扩展。
低内聚:
A. 偶然内聚:如果一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散的。这就叫做偶然内聚。
偶然内聚的例子: 在模块T 中有A,B,C三条语句,至少从表面上看来这三条语句没什么联系,只是因为D,E,F,G中都这三条语句,为了节省空间才把这三条语句作为一个模板放在一起。
B. 逻辑内聚:如果一个模块完成的任务在逻辑上属于相同或相似的一类( 例如一个模块产生各种类型的全部输出),称为逻辑内聚
逻辑内聚的例子:某一个模块将打印,年,月,日,具体打印什么,将由传入的控制标志所决定。
C.时间内聚:一个模块包含的任务必须在同一段时间内执行(例如,模块完成各种初始化工作),称为时间内聚
时间内聚的例子:将多个变量的初始化放在同一个模块中实现。

中内聚
A.过程内聚:如果一个模块内的处理元素是相关的,而且必须以特定次序执行,称为过程内聚
过程内聚的例子:一个子程序,将开始读取学生的学号,然后是姓名,最后将读取分数,是由于特定的顺序而将这些操作组合在一起的
B.通讯内聚:如果模块中所有的元素都使用同一个输入数据和(或)产生同一个输出数据,则称为通讯内聚
通讯内聚的例子:有一个子程序,它将打印实验报告,并且在完成后重新初始化传进来的实验数据。这个程序具有通讯内聚性。因为这两个操作由于使用同一个数据源联系在了一起。

高内聚:
A.顺序内聚:如果一个模块内的处理元素和同一个功能密切相关,而且这些处理必须顺序执行(通常一个处理元素的输出数据作为下一个处理元素的输入数据),则称为顺序内聚。
顺序内聚的例子:有一个子程序,通过给出的生日,先计算出年龄。再根据年龄算出退休的时间,则这个程序具有顺序内聚性。
B.功能内聚:如果模块内所有的元素属于一个整体完成一个单一的功能,则成为功能内聚。
功能内聚的例子:一个程序中所有的操作都是为了算出一个人的年龄

第3题

3.用面向数据流的方法设计下列系统的软件结构。
(1)储蓄系统(参见习题2第2题)
(2)机票预订系统(参见习题2第3题)
(3)患者监护系统(参见习题2第4题)
储蓄系统
在这里插入图片描述
机票预订系统
在这里插入图片描述
患者监护系统
在这里插入图片描述

第4题

4.美国某大学有 200 名教师,校方与教师工会刚刚签订一项协议。按照协议,所有年工资超过$26000(含$26000 )的教师工资将保持不变,年工资少于$26000 的教师将增加工资,所增加工资数额按下述方法计算:给每位教师所赡养的人(包括教师本人)每年补助$100,此外,教师有一年工龄每年再多补助¥50,但是,增加后的年工资总额不能多于$26000。
教师工资档案存储在行政办公室的磁带上,档案中有目前的年工资、赡养的人数、雇佣日期等信息。需要写一个程序计算并印出每名教师的原工资和调整后的新工资。
要求:(1)画出此系统的数据流图;
(2)写出需求说明;
(3)设计上述的工资调整程序(要求用 HIPO 图描绘设计结果),设计时分别采用两种算法,并比较两种算法的优缺点:
(a)搜索工资档案数据,找出年工资少于$26000 的人,计算新工资,校核是否超过$26000,存储新工资,印出新旧工资对照表;
(b)把工资档案数据按工资从最低到最高的次序排序,当工资数额超过$26000 时即停止排序,计算新工资,校核是否超过限额,存储新工资,印出结果。
(4)你所画出的数据流图适应用那种算法?
答:
(1)数据流图:
在这里插入图片描述
分解后:
在这里插入图片描述
(2)需求说明:
1.功能需求:可以输入调资的标准,输入教师档案,经调资给出新的教师档案,需要存储档案
2.性能需求:软件的响应时间小于0.5s,更新处理要快
3.灵活需求:当需求发生某些变化时,该软件应该能够适应这些变化
4.故障处理要求:出现错误时,应给予警告或提示
(3)
A.
在这里插入图片描述
B.
在这里插入图片描述
(a)比较耗时,因为它要检索所有的档案
(b)从速度上看比较块,但是(b)需要排序算法
比较复杂,(a)对于设计来讲比较简单
(4)画出的数据流图比较适合(A)的算法

第5题

5.下面将给出两个人玩的扑克牌游戏的一种玩法,试设计一个模拟程序,它的基本功能是:
(1)发两手牌(利用随机数产生器)。
(2)确定赢者和赢牌的类型。
(3)模拟N次游戏,计算每种类型牌赢或平局的概率。要求用HIPO图描绘设计结果并且画出高层控制流程图。
扑克牌游戏规则如下:
(1)有两个人玩分别为A和B。
(2)一副扑克牌有52张牌,4种花色(黑桃、红桃、梅花、方块),每种花色的牌的点数按升序排列有2,3,4,…,10,J,Q,K,A等13种。
(3)给每个人发三张牌,牌面向上,赢者立即可以确定。
(4)最高等级的一手牌成为同花,即3张牌均为同一种花色,最大的同花是同一种花色的Q,K,A。
(5)第二等级的牌称为顺子,即点数连续的3张牌,最大的顺子是花色不同的Q,K,A。
(6)第三等级的牌是同点,即点数相同的三张牌,最大的同点是AAA。
(7)第四等级的牌是对子,即3张牌中有两张点数相同,最大的对子是A,A,K。
(8)第五等级的牌是杂牌,即除去上列4等之外的任何一手牌,最大的杂牌是不同花色的A.K,J。
(9)若两个人的牌类型不同,则等级高者胜;若等级相同,则点数高者胜;若点数也相同,则为平局。
答:
程序:

#include "stdio.h"
int rabl(int a,int b,int *r)
{
    
    
int l,k,m,i,p;
k=b-a+1;
l=2;
while(i<=1)
{
    
    
k=k+k+k+k+k;
k=k%m;
l=k/4+a;
if(l<=b) {
    
    p=l;i=i+1;}
}
*r=k;
return(p);
}
int max(int T[10] [10])
{
    
    
int t=0;
if(T[0] [0]>T[1] [0])
t=T[0] [0];
else t=T[1][0];
if(t<T[2] [0]
t=T[2][0];
return t;
}
int E1(int T[10][10])
{
    
    
if(T[0][1]==T[1][1]&&T[1][1]==T[2][1])
return 1;
else return 0;
}
int E2(int T[10][10])
{
    
    
int q=0;
if(((max(T[10][10])-1)==T[0][0]||(max(T[10][10])-1)==T[1][0]||(max(T[10][10])
-1)==T[2][0])&&((max(T[10][10])-2)==T[0][0]||(max(T[10][10])-2)==T[1][0] ||
(max(T[10][10])-2)==T[2][0])) // if(q=max(T[][10]))
return 1;
else
return 0;
}
int E3(int T[10][10])
{
    
    
if(T[0][0]==T[1][0]==T[2][0])
return 1;
else return 0;
}
int E4(int T[10][10])
{
    
    
if(T[0][0]==T[1][0]&&T[0][0]!=T[2][0])

return 1;
else if(T[0][0]==T[2][0]&&T[0][0]!=T[1][0])
return 1;
else if(T[1][0]==T[2][0]&&T[1][0]!=T[0][0])
return 1;
else return 0;
}
void main()
{
    
    
int times=0,e1=0,e2=0,e3=0,e4=0,e5=0;
int A[10][10],B[10][10];
int r1=2,r2=3;
printf("请输入游戏的次数\n");
scanf("%d",&times);
for(int j=0;j<times;j++)
{
    
    
for(int i=0;i<3;i++)
{
    
    
A[i][0]=rabl(1,13,&r1);
A[i][1]=rabl(14,17,&r2);
B[i][0]=rabl(1,13,&r1);
B[i][1]=rabl(14,17,&r2);
}
if(E1(A[][10])>E1(B[][10])){
    
    
e1++;
printf("A赢,同花顺\n");
}

else if(E1(A[][10])<E1(B[ ][10])
{
    
    
e1++;
printf("B赢,同花顺\n");
}
else if(E1(A[ ][10])==E1(B[][10])&&E1(B[][10])==1) {
    
    
e1++;
if(max(A[][10])>max(B[][10]))
printf("A赢,同花顺\n");
else
printf("B赢,同花顺\n");
}
else if(E2(A[ ][10])>E2(B[ ][10]))
{
    
    
e2++;
printf("A赢,顺子\n");
}
else if(E2(A[][10])<E2(B[ ][10])
{
    
    
e2++;
printf("B赢,顺子\n");
}
else if(E2(A[][10])==E2(B[][10])&&E2(B[][10])==1) {
    
    
e2++;
if(max(A[][10])>max(B[][10]))
printf("A赢,顺子\n");
else
printf("B赢,顺子\n");
}
else if(E3(A[][10])>E3(B[][10]))
{
    
    
e3++;
printf("A赢,同点\n");
}
else if(E3(A[][10])<E3(B[ ][10])
{
    
    
e3++;
printf("B赢,同点\n");
}
else if(E3(A[][10])==E3(B[][10])&&E3(B[][10])==1) {
    
    
e3++;
if(max(A[][10])>max(B[][10]))
printf("A赢,同点\n");
else
printf("B赢,同点\n");
}
else if(E4(A[][10])>E4(B[][10])) {
    
    
e4++;
printf("A赢,对子\n");
}

else if(E4(A[][10])>E4(B[][10]))
{
    
    
e4++;
printf("B赢,对子\n");
}
else if(E4(A[][10])==E4(B[][10])&&E4(B[][10])==1) ;
{
    
    
e4++;
if(max(A[][10])>max(B[][10]))
printf("A赢,对子\n");
else
printf("B赢,对子\n");
}
else
{
    
    
if(max(A[][10])>max(B[][10]))
printf("A赢,杂牌\n");
else
printf("B赢,杂牌\n");
}
}
printf("同花顺赢牌概率为%d,顺子赢牌概率为%d,同点赢牌概率为%d,对子赢牌概率为%d,杂牌赢牌概率为%d",e1/times,e2/times,e3/times,e4/times,e5/times);
}

控制流程图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hypertext123/article/details/109575260