试题三1. 阅读下列说明和图,回答下面问题。
[说明] 本流程图描述了某子程序的处理流程,现要求用白盒测试法对其进行测试。

[问题]
根据判定覆盖、条件覆盖、判定/条件覆盖、多重条件覆盖(条件组合覆盖)、路径覆盖5种覆盖标准,从供选择的答案中分别找出满足相应覆盖标准的最小的测试数据组(用①~⑩回答)。供选择的答案:
判定覆盖 ⑤
条件覆盖 ④
判定/条件覆盖⑦
多重条件覆盖⑨
路径覆盖 ⑤
[解析] 本题考察的是测试用例的设计。软件测试的目的是希望以最少的人力和时间发现潜在的各种错误和缺陷。这样测试用例就显得尤为重要。
软件测试大体上可分为两大类:基于“白盒”的路径测试技术和基于“黑盒”的事务处理流程测试技术(又称功能测试)。白盒测试依据的是程序的逻辑结构,而黑盒测试技术依据的是软件行为的描述。
路径测试(PX):执行所有可能穿过程序的控制流程路径。在路径测试中,该策略是最强的,一般不可实现。
语句测试(PI):至少执行程序中所有语句一次。100%语句覆盖率用CI表达。语句覆盖是最弱的逻辑覆盖准则。
分支测试(P2):至少执行程序中每一分支一次。100%分支覆盖率用C2表达。
条件组合测试:使每个判定中的所有可能的条件取值组合至少执行一次。只要满足条件组合覆盖,就一定满足分支覆盖。
试题四1. 阅读下列函数说明、图和C代码,填入______处的字句。
[说明] 当一元多项式

中有许多系数为零时,可用一个单链表来存储,每个节点存储一个非零项的指数和对应系数。
为了便于进行运算,用带头节点的单链表存储,头节点中存储多项式中的非零项数,且各节点按指数递减顺序存储。例如:多项式8x
5-2x
2+7的存储结构为:

函数中使用的预定义符号如下:
#define EPSI le-6
struct Node { /*多项式中的一项*/
double c; /*系数*/
int e; /*指数*/
struct Node *next;
};
typedef struct { /*多项式头节点*/
int n; /*多项式不为零的项数*/
struct Node *head;
} POLY;
[函数] void Del (POLY *C, struct Node *P)
/*若P是空指针则删除头节点,否则删除p节点的后继*/
{
struct Node *t;
/*C是空指针或C没有节点*/
if (C==NULL || C->head==NULL) return;
if(______) {/*删除头节点*/
t=C->head;
C->head=t->next;
return;
}/*if*/
t=P->next;
P->next=t->next;
};/*Del*/
void Insert (POLY *C, struct Node *pC)
/*将pC节点按指数降序插入到多项式C中*/
/*若C中存在pC对应的指数项,则将系数相加:若其结果为零,则删除该节点*/
{
struct Node *t, *tp;
/*pC为空指针或其系数近似为零*/
if (pC==NULL || fabs (pC->c) <EPSI) return;
if(C->head==NULL) {/*若C为空,作为头节点插入*/
C->head=pC;
pC->next=NULL;
C->n++;
return;
}/*if*/
/*若pC的指数比头节点的还大,插入到头节点之前*/
if (pC->e>C->head->e) {
______;
C->head=pC;
C->n++;
return;
}/*if*/
______;
t=C->head;
while (t!=NULL) {
if (t->e>pC->e) {
tp=t;
t=t->next;
}
else if(t->e==pC->e) {/*C中已经存在该幂次项*/
t->c+=pC->c; /*系数相加*/
if(fabs(t->c) <EPSI) {/*系数之和为零*/
______; /*删除对应节点*/
C->n--;
______;
}
else t=NULL; /*C中已经不存在该幂次项*/
} /*while*/
if (t==NULL) {/*适当位置插入*/
pC->next=tp->next;
tp->next=pC;
C->n++;
} /*if*/
}; /*Insert*/
p==NULL
pC->next=C->head->next
tp=NULL
Del(C,tp)
break
[解析] 根据注释,Del函数当p是空指针时,删除头节点,因此易知第一个空应填p==NULL。
第二个空是插入头节点的特殊情况,应填pC->next=C->head->next。
由注释可知第四个空是删除操作,需调用Del函数,进一步确定实参。此处需要删除节点t,结合Del函数的说明,实参p需要空指针(NULL)或t节点的前驱指针,由if(t->e>pC->e){tp=t;t=t->next;}可知,tp正是t节点的前驱指针。因此应填Del(C,tp)。由此也可以确定第三个空,当需要删除头节点时,tp应是空指针,因此第三个空应填tp=NULL。
至于第五个空,应填break。此时,节点p已正确处理完毕,应该结束while循环,而且必须终止,否则while循环结束后t值为NULL,将会错误的执行插入操作。
试题五1. 阅读下列函数说明和C++代码,填入______处的字句。
[说明] 对多个元素的聚合进行遍历访问时,需要依次推移元素,例如对数组通过递增下标的方式,数组下标功能抽象化、一般化的结果就称为迭代器(Iterator)。模式以下程序模拟将书籍(Book)放到书架(BookShelf)上并依次输出书名。这样就要涉及遍历整个书架的过程。使用迭代器Iterator实现。下图中显示了各个类间的关系。以下是C++语言实现,能够正确编译通过。
[C++代码] template<class ______>
class Iterator {
public:
virtual bool hasNext( )=0;
______ Object* next( )=0;
};
class Book {
//省略具体方法和属性
};
class BookShelf {
private:
vector<Book>books;
public:
BookShelf( ) {
}
Book* getBookAt(int index) {
return &books [index];
}
int getLength( ) {
return books.size( );
}
};
template<class Object>
class BookShelfIterator: public ______ {
private:
BookShelf *bookShelf;
int index;
public:
BookShelflterator(BookShelf *bookShelf) {
this->bookShelf=bookShelf;
index=0;
}
bool hasNext( ) {//判断是否还有下一个元素
if(index <bookShelf->getLength( )) {
return true;
} else {
return false;
}
}
Objeot* next( ) {//取得下一个元素
return bookShelf->getBookAt(index++);
}
};
int main( )
{
BookShelf bookShelf;
//将书籍上架,省略代码
Book *book;
Iterator<Book> *it=new BookShelfIterator<Book>(______);
while(______) {//遍历书架,输出书名
book=(Book*)it->next( );
/*访问元素*/
}
return 0;
}
Object
virtual
Iterator<Object>
&bookShelf
it->hasNext( )
[解析] Iterator是模板类,第一个空应该填某个类名,其方法next( )的返回类型是Object,而Object没有定义,故空应填Object。
从next( )方法末尾的“=0”可知,该方法为纯虚函数,故第二个空应填virtual。
BookShelfIterator类继承自Iterator类,要注意的是模板类基类的写法,第三个空应填Iterator<Object>。
根据构造函数Bookshemterator(Bookshelf *bookShelf)可得,第四个空应填&bookShelf,注意地址符,因形参是BookShelf指针。
while循环是遍历书架,输出书名,循环条件是“还有下一记录(书)”,故第五个空应填it->hasNext( )。注意指针写法。
2. 阅读以下说明和Java代码,填入______处的字句。
[说明] 对多个元素的聚合进行遍历访问时,需要依次推移元素,例如对数组通过递增下标的方式,数组下标功能抽象化、一般化的结果就称为迭代器(Iterator)。模式以下程序模拟将书籍(Book)放到书架(BookShelf)上并依次输出书名。这样就要涉及遍历整个书架的过程。使用迭代器Iterator实现。下图中显示了各个类间的关系。以下是JAVA语言实现,能够正确编译通过。
[Java代码] //Iterator.java文件
public interface Iterator {
public abstract boolean hasNext( );
public abstract Object next( );
}
//Aggregate.java文件
public interface Aggregate {
public abstract Iterator iterator( );
}
//Book.Java
public class Book {
//省略具体方法和属性
}
//BookshelfIterator.java文件
public class BookShelfIterator ______ Iterator {
private BookShelf bookShelf;
private int index;
public BookShelfIterator (BookShelf bookShelf) {
this.bookShelf=bookShelf;
this.index=0;
}
public boolean hasNext( ) {//判断是否还有下一个元素
if(index <bookShelf.getLength( )) {
return true;
} else {
return false;
}
}
public Object next( ) {//取得下一个元素
Book book=bookShelf.getBookAt (index);
index++;
return book;
}
}
//BookShelf.java
import java.util.Vector;
public class BookShelf {
private Vector books;
public BookShelf(int initialsize) {
this.books=new Vector(initialsize);
}
public Book getBookAt (int index) {
return (Book)books.get(index);
}
public int getLength( ) {
return books.size( );
}
public Iterator iterator( ) {
return new BookShelfIterator(______);
}
//Main.java文件
public class Main {
public static void main (String[ ]args) {
BookShelf bookShelf=new BookShelf ______;
//将书籍上架,省略代码
Iterator it=bookShelf.______;
while(______) {//遍历书架,输出书名
Book book=(Book)it.______;
System.out.println(""+book.getName( ));
}
}
}
implements
this
iterator( )
it.hasNext( )
next( )
[解析] Iterator是接口类,第一个空应该填implements。
根据构造函数BookShelflterator(BookShelfbookShelf)可得,第二个空应填this,即自身引用。
第三个空是取得迭代器实例,Bookshel璞中方法iterator( )是返回Iterator接口,故应填iterator( )。
while循环是遍历书架,输出书名,循环条件是“还有下一记录(书)”,故第四个空应填it.hasNext( )。注意指针写法。
第五个空是取得书实例,BookShelf类中方法next( )是返回Object类实例,取得下一本书,故应填next( )。
3. 阅读以下函数说明和C代码,填入______处的字句。
[说明] 对多个元素的聚合进行遍历访问时,需要依次推移元素,例如对数组通过递增下标的方式,数组下标功能抽象化、一般化的结果就称为迭代器(Iterator)。模式以下程序模拟将书籍(Book)放到书架(BookShelf)上并依次输出书名。这样就要涉及遍历整个书架的过程。使用迭代器Iterator实现。下图中显示了各个类间的关系。以下是JAvA语言实现,能够正确编译通过。
[C代码] typedef bool (*funl) ( );
typedef ______ (*fun2) ( );
const int BOOK MAX=10;//最大书本数
Struct Book {
char name[30];
};
struct BookShelf {//书架
struct Book books[BOOK_MAX];
int index;//书架上最后一本书的下标加1,即下一本书的下标,如0表示有0本书
};
Struct Book* getBookAt (Struct BookShelf *BS, int index)
//从书架BS上取得下标为index的书
//只有当下标大于等于0且不大于当前书架上的最后一本书对应的下标,才取书成功:
//否则失败,返回NULL
{
if (index >=0 && ______) {
return &BS->books[index];
}
return NULL;
}
bool appendBook (struct BookShelf *BS, Struct Book book)
{
if (BS->index <BOOK MAX) {
BS->books[BS->index++]=book;
return true;
}
return false;
}
int getLength (struct BookShelf *bookShelf)
{
return bookShelf->index;
}
struct Iterator {//迭代器
funl hasNext;//判断是否还有下一个元素
fun2 next;//取得下一个元素
};
struct BookShelfIterator {//书架迭代器
int index;
struct BookShelf* bookShelf;
}bookShelfIterator={0, NULL};
bool BShasNext( )//判断是否还有下一本书
{
if(bookShelfIterator.index
<getLength(bookShelfIterator.bookShelf)) {
return true;
} else {
return false;
}
}
struct Book* BSnext( )//取得下一本书,并将index加1,以便下一次正确访问
{
return getBookAt (bookShelfIterator.bookShelf,
______ );
}
void main( )
{
Struct BookShelf bookShelf;
bookShelf.index=0;
//将书籍上架,省略代码
//将bookShelf与bookshelfIterator相关联
bookShelfIterator.bookShelf= ______;
struct Iterator iterator;
iterator.hasNext=BShasNext;
iterator.next=BSnext;
struct Book*b;
while(______) {//遍历书架,输出书名
b=iterator.next( );
printf("%s\n", b->name);
}
}
structBook*
index<BS->index
bookShelfIterator.index++
&bookShelf
itemtor.hasNext( )
[解析] 第一个空是某个函数类型定义,先看第二个空,根据注释,此处应填下标index“不大于当前书架上的最后一本书对应的下标”,而结构体BookShelf中的字段index是表示“书架上最后一本书的下标加1,即下一本书的下标,如0表示有0本书”,故第二个空应填:index<BS->index。
继续看第三个空,根据注释函数BSnext( )的功能是“取得下一本书,并将index加1,以便下一次正确访问”,而函数getBookAt(BS,index)是“从书架BS上取得下标为index的书”,因此第三个空应填欲取书的下标,应为bookShelfIterator.index,故应填bookShelfIterator.index++。
书架迭代器Bookshemterator中的字段bookShelf是structBookShelf*类型的,因此第四个空应填&bookshelf,注意取地址符&。
while循环是遍历书架,输出书名,循环条件是“还有下一记录(书)”,故第五个空应填iterator.hasNext( )。
现在再来看第一个空,由迭代器Iterator中字段next的定义:fun2 next;及赋值语句iterator.next=BSnext;可得,fun2应该定义了与BSnext函数同参数的函数指针,函数指针的定义原型为:函数返回类型函数指针变量名(参数列表),又知函数BSnext的定义为struct Book*BSnext( ),故第一个空应填struct Book*。