1、2011年下半年软件水平考试(初级)程序员下午(应用技术)真题试卷及答案与解析 1 阅读以下说明和流程图,填补流程图中的空缺 (1) (5),将解答填入答题纸的对应栏内。 【说明】 下图所示的流程图用于检查数组 A1: n中的元素是否为自然数 1 n的一个排序 (含有 1 n个数 ),若是,则输出 OK,否则输出所缺的自然数及其个数 m。 为检查 Ai: n中是否含有 k,只要判断 P(k)=(A(1)-k)*(A(2)-k)*(A(n) -k)是否等于 0即可。【流程图】 2 阅读以下说明和 C程序代码,将解答写在 答题纸的对应栏内。 【说明】 下面是一个待修改的 C程序,其应该完成的功能是
2、:对于输入的一个整数num,计算其位数 k,然后将其各位数字逆序转换为字符串保存并输出。若 nun为负整数,则输出字符串应有前缀 “一 ”。例如,将该程序修改正确后,运行时若输入“14251”,则输出 “15241”;若输入 “一 6319870”,则输出 “一 0789136”。 下面给出的 C程序代码中有五处错误,请指出错误代码所在的行号并给出修改正确后的完整代码行。 【 C程序代码】 行号 代码 1 #include 2 #include 3 int main() 4 5 long num=0, t=0; char*pstr, i=0, k=0; 6 7 sancf(“ ld”, &nu
3、m); *输入一个整数,存入 num* 8 t=num; k: num!=0?0: 1; 9 while(t=0) *计算位数 * 10 t=t 10; 11 k+: 12 13 14 pstr=(char * )malloc(k+2)+sizeof(char); 15 If(pstr=0) return一 1; 16 17 i=0: 18 if(num 0) 19 num=一 num 20 pstr0=一 ; i=1; 21 22 for(; k0; k- -) *形成字符串 * 23 pstri+=num 10; 24 num=num 10: 25 26 pstrk= 0; *设置字符串结
4、尾 * 27 printf(“ s n”, pstr); 28 free(pstr); 29 return 0: 30 3 阅读以下说明和 C代码,填补 C代码中的空缺 (1) (5),将解答写在答题纸的对应栏内。 【说明】 某市在进行市长选举,该市共分为 M个选区 (1 M 6,从 1开始顺序编号 ),共有 N个候选者参选 (1 N 5,从 A开始顺序编号 )。经投票后,所得选票数据如下表所示。 现已将选票数据存入文本文件 data txt,该文件内容格式如下:共有 M行,每行N十 1个整数,第一个整数为选区编号,随后为 N个候选者在该选区所得票数。 下面的程序先从文件中读入选票数据存入二维
5、数组 data,然后完成下列功能: a计算并显示每个竞选者获得的选票数及占总选票数的百分比; b如果任一竞选者获得的选票数超过总票数的 50,则显示竞选者获胜; c如果没有竞选者获得总选票数的 50以上,则显示两位得票最高的竞选者需再进行决选。 在下 面的程序代码中,竞选者 A的编号为 1,竞选者 B的编号为 2,以此类推。【 C代码】#include#include#define M 5 *选区数 * #define N 4 *竞选者人数 * int main(int argc, char argv) FILE*fin; int dataM+1N+1; *data0存放选区编号,dataMJ
6、存放 J号竞选者得票总数 * int maxpl, cd1: *maxp1、 cd2存放得票最多者的票数和竞选者编号 * int maxp2, cd2; *maxp2、 cd2存放得票次数多者的票数和竞选者编号 * int i, j, totalP; *tatalp存放总票数 * fin=fopen(”data txt”, ”r”); Ii(!fin)return-1; i=0; j=0; While(!feof(fin) *从文件读入数据 * Fscanf(fin, ” d”, &dataij); (1) ; if(jN) j=0;i+; fclose(fin); totalP=0; max
7、pl=0; maxp2=0; cdl=0; cd2=0; for(j=1; jN+1; j+) dataMj= (2) ; *设置 j号竞选者的票总数初始值 * for(i=0; iM; i+) dataMj+=dataij: if(dataMj MAXP1) (3) ; cd2=cd1; MAXP1=dataMj; cd1=j; else if(dataMj MAXP2)MAXP2=dataMj;cd2=j; (4) ; *计算总票数 * for(j=1; j N+1; j+) printf(”candidatec: d ”, j+A一 1, dataMj); printf(” 21f n”
8、, (double)dataMjtotalP): printf(”n”): if( (5) 0 5) *判断得票数最多者的得票率 *printf(”winner: candidate- c n”, cdl+A 1); else printf(”result: candidate- c pk candidate- c n”, cd1 +A 1, cd2+A 1); system(”pause”); return 0: 4 阅读以下说明和 C函数,填补 C函数中的空缺 (1) (5),将解答写在答题纸的对应栏内。 【说明】 约瑟夫问题如下所述:有 n个人 (编号为 1 n)围成一圈,从第一个人开始
9、,按照顺时针方向从 1开始计数到 m(即数到第 m个人 ),让其出圈,然后再从其顺时针方向的下一个人开始,依次计数到 m并让其出圈,重复这个过程,直到所有人都出圈,试给出出圈者的顺序。 以 n=5, m=3为例,其中圈顺序为 3, 1, 5, 2, 4,过程如下图所示。 下面的函数Joseph()在单向循环链表表示的基础上输出出圈的过程 。 n为 5时的单向循环链表结构如下图所示。 链表的结合类型定义如下: Typedef struct Node int no; struct Node*next: node,*LinkList;函数 Joseph(LinkList tail, int n, i
10、nt m)的处理思路如下: (1)用 k计数,每次都从 0开始,当计数到 m一 1时结束本次计数; (2)通过指针 p查找出圈者所对应的结点,当 K的值等于 m一 1时, P应指向出圈者对应结点的前驱结点; (3)通过删除结点表示出圈处理; (4)当 m大于圈中剩余人数时,为了避免重复计 数,用模运算修改 m的值; (5)计数和删除操作完成后再恢复 m的原值。 【 C函数】 void Joseph(LinkList tail, int n, int m) LinkList p, q; int k, i, old_m=m; p=tail; for(i=n; i l; i- -) *i表示圈中剩余
11、人数 * m=m i; *避免重复计数 * if(0=m) m= (1) ; k=0; while(k (2) ) (3) ; k+; printf(” d n”, (4) ); *输出出圈者的编号 * q=p-next; (5) =q-next; *删除出圈者对应的结点 * free(q); M=old_m; printf(“ d n”, p-No); 5 阅读以下说明、图和 C+代码,填补 C+代码中的空缺 (1) (5),将解答写在答题纸的对应栏内。 【说明】 已知某公司主要有两大类耗电资产 (Asset):计算机(ComputerAsset)和建筑物 (BuildingAsset)。为
12、了节约 能源,通过控制各种电源,将可关闭的房灯、计算机显示器等在夜间关闭。 为了实现上述需求,设计了如下 图所示的类图,并用下面的 C+代码加以实现。 【 C+代码】 #include#includeusing namespace std; class Asset *通用资产,基类* public: virtual Asset(); ; class PowerSwitchable *抽象基类,可在夜间关闭电源的物体接口 * public: virtual void powerDown()=0; *powerDown()函数接口 * virtual void powerUP()=0; *powe
13、rUp()函数接口 * ; class computerAsset: public Asset *计算机资产 * protected: int deskNumber;public: computerAsset(int desNumber)this-deskNumber=deskNumber; ; class computerCPU (1) *计算机主机,永不关闭 * public: computerCPU(int desNumber): ComputerAsset(desNumber); class computerMonitor (2) *计算机显示器 * public: computerM
14、onitor(int roomNumber):omputerAsset(roomNumber), PowerSwitchable() computerMonitor()void powerDown() *关电源,代码省略 * void powerUp() *开电源,代码省略 * ; *BuildingAsset、 BuildingLight、 EmergencyLight和 RoomLiggts代码省略 * class BuldingManagementprivate: Asset*things24; int numltems;public: void goodnight() *值班员定时 “
15、关闭 ”时调用,关闭可关闭的电源 *for(int i=0; i numltems; i+) (3) ps=dynamic_cast(thingsi); if(ps!=0) ps-powerDown(); *goodMorning()与 goodNight()类似,依次调用 powerUp(),实现省略 * void add(Asset*thing) *为建筑添加资产 * yhings (4) =thing; ;int main()BuildingManagement*b1= (5) BuildingManagement(); b1-add(new RoomLights(101); 101房间
16、的控制灯 b1-add(new Emergencynight(i01); 101房间的应急灯 b1-add(new ComputerCPU(10104); 101房间 4号桌上的计算机 b1-add(new ComputerMonitor(10104); 101房间 4号桌上的计算机显示器 b1-goodNight(); Delete b1; 6 阅读以下说明、图和 Java代码,填补 Java代码中的空缺 (1) (5),将解答写在答题纸的对应栏内。 【说明】 已知某公司主要有两大类耗电资产 (Asset):计算机(ComputerAsset)和建筑物 (BuildingAsset)。为了节
17、约能源,通过控制各种电源,将可关闭的房灯、计算机显示器等在夜间关闭。 为了实现上述需求,设计了如下图所示的类 图,并用下面的 Java代码加以实现。 Java代码】 abstract class Asset *通用资产,基类 * interface PowerSwitchable *可在夜间关闭的电源的物体实现该接口 * public void void powerDown(); public void powerUP(); abstract class BuildingAsset extends Asset *建筑物资产 * protected int room; public Buildi
18、ngAsset(int room)this room=room; abstract class BuildingLight extends BuildingAsset 灯的通用信息: fluorescent incandescent等,略 BuildingLight(int room Number) super(roomNunaber); class Emergencynight (1) 应急灯,永不关闭 EmergrncyLight(int roomNumber) Super(roomNumber); 。 class RoomLights (2) RoomLights(int roomNur
19、ober)super(roomNumber); Public void powerDown() 关电源,代码省略 Public void powerUp() 开电源,代码省略 )*ComputerAsset、 ComputerCPU和 ComputerMonitor代码省略 * public class BuildingManagement Asset things=new Asset24; int numItems=0; public void goodnight() 值班员定时 “关闭 ”时调用,关闭可关闭的电源 for(int i=0: ithings length; i+) if(th
20、ingsiinstanceof (3) ) (powerSwitchable)thingsi) powerDown(); *goodMoming()与 goodNight()类似,依次调用 powetUp(),其实现细节此处省略 * public void add(Asset thing) *为建筑添加资产 * Things (4) =thing; public static void main(stringargs) BuildingManagement*b1= (5) BuildingManagement(); b1 add(new RoomLights(101); 101房间的控制灯 b
21、1 add(new EmergencyLight(101); 101房间的应急灯 b1 add(new ComputerCPU(10104); 101房间 4号桌上的计算机 b1 add(new ComputerMonitor(10104); 101房间 4号桌上的计算机显示器b1 goodNight(); delete b1; 2011年下半年软件水平考试(初级)程序员下午(应用技术)真题试卷答案与解析 1 【正确答案】 (1)0 (2)1 (3)P*(A(i)-k) (4)P=0 (5)m+1 【试题解析】 本题考查考生设计和阅读流程图的能力。从题目给出的流程图可以看出,首先需要对 m赋值
22、,然后对 k: 1, 2, , n进行循环,检查数组 A中是否包含 k。为此,在该循环中,需要嵌套内循环来计算 P(k),然后判断计 算结果 P的值是否为 0,以此来判断数组 A中是否包含 k。由于 m表示所缺的自然数,在初始时其值应为 0,因此, (1)处应填入 0。 为了对 i循环计算累乘的 P(k),需要先在 P中送初值 1。因此, (2)处应填入 1,然后在 (3)处进行累乘运算,并将结果送给 P, (3)处应填入 P*(A(i) k)。 (4)和 (5)处用以实现判断 P是否为 0,若是,则输出 OK,否则输出所缺的自然数及其个数 m。在内循环结束后, (4)处应实现判断 P是否为
23、0, P=0表示数组 A中含有 k,否则表示数组 A中缺少 k。因此, (4)处应填入 P=0。如果数据 A中缺少 k,则变量 m的值应加 1。因此, (5)处应填入 m+1。 循环 k结束后,应根据 m的值决定输出结果。 m为 0表示数组 A中包含全部自然数 1 n,即数组 A的元素为自然数 1 n的一个排列, m不为 0表示数组 A中缺少 m个自然数,可将其输出。 2 【正确答案】 行号 修改正确后的完整代码行 7 sancf(” ld”, &num) 9 while(t!=0)或 while(t) 15 if(pstr=0)或其等价形式 23 pstri+=num *9410+0或其等价
24、形式 26 pstri= 0或其等价形式 【试题解析】 本题考查考生对使用 C语言编程时常见错误的查找和排除。 程序的第 7行是使格式化输入函数 scanf()的调用,这是比较容易出错的地方。常见的错误是格式控制串与输入列表中的变量类型不匹配,或是丢失变量前的取地址运算符号 “ ”。本行的错误就是变量 num前丢失了地址运算符号 “ ”,应将其改为: sancf(” ld”, num)。 程序第 8 12行的功能是计算变量 num的位数并将其结果以变量 k显示。计算一个整数的算法是:将其循环除以 10,每次在丢掉其个位数字的同时,其计算位数的变量执行加 1操作,直到该整数的值被除到等于 0为止
25、。换句话说,只要该整数不为 0,就一直执行循环除 10操作。因此,第 9行的循环条件出错,应改为: while(t! =0)。 程序第 14 15行用于为要创建的字符串申请动态存储空间,并判断是否申请成功。第 15行存在一个在程序员考试中多次考查的错误,判断内存是否申请成功的条件应 改为: if(pstr=0)。 程序第 22 25行用于将整数 num转化为其逆序的字符串。此处的错误在第 23行,因为 *pstr中应存储的是字符而非数字字符,而 num 10为整数,应在其后加上字符 0。因此,第 23行的错误应修改为: pstri+=num 10+0。 程序第 26行用于设置字符串的结束标志。
26、由于 num的值可正可负,将字符串的结束标志设置在 k下标处在 num的值为负时会出错。修改的方法是用 i作为下标,使得 0正好跟在最后一个数字字符的后面。因此,第 26行的错误应修改为: pstri= 0。 3 【正确答案】 (1)j+或 +j或其等价表示 (2)0 (3)MAXP2=MAXP1 (4)totalP+=dataMj或其等价表示 (5)(double)MAXP1 totalP, (float)MAXP1 totalP或其等价表示 【试题解析】 本题考查考生综合运用 C语言的知识解决实际问题的能力。 根据题目描述和程序段的注释说明, (1)处实现从文件读入数据到数组 data中,
27、 i和 j分别为行号和列号。行号 i应在一行数据都 读入后增加 1,而列号 j则每读取一个数据就要增加 1。因此, (1)处应填入 j+或其等价表示形式。 由于 dataMi存放 i号竞争者的得票总数, dataM0存放的是选区编号,因此 dataM0不用。 (2)处用于设置 j号竞选者的票总数初始值,而在没有统计前其初始值应为 0。因此, (2)处应填入 0。 (3)处用于找出得票数最多的竞选者。此时,之前的最多得票 (MAXPl)将成为次多得票 (MAXP2)。 (3)处应填入 MAXP2=MAXP1。 (4)处用于计算总票数。根据题目的说 明,此处应填入 totalP+=dataMj或其
28、等价表示。 (5)处用于计算得票数最多者的得票率。根据题目的说明,应将 MAxP1除以totalP。但需要注意的是, MAXP1和 totalP都是整数且 MAXP1小于 totalP,因此应至少对其中的一个数值进行整数到实数的类型转换,否则其结果将为 0。因此, (5)处应填入 (dotable)MAXP1 totalP或其等价表示。 4 【正确答案】 (1)i (2)m1 (3)p=p-next (4)p-next-No (5)p-next 【试题解析】 本题考查数据结构中经典的约瑟夫问题。题目中涉及的考点主要有链表运算和程序逻辑,分析程序时首先要明确各个变量所其的作用和代表的含义,并按照
29、语句组分析各段代码的功能,从而完成空缺处的代码填写。 根据题目中 Joseph函数处理思路 (4)的描述, m=m i语句可避免计数过程重复。但这里需要考虑一种特殊情况,即 m为 0的情况。此时对应的情况应该是正好要数到目前所在位置的前一个人。由于单向循环链表的指针特点,还需要逐个结点进行遍历,则当罔中还剩下 i个人时,最多计数 到 i。因此, (1)处应填入 i。 程序段接下来的 while循环用于在单循环链表中扫描结点并完成计数。由于计数器 k从 0开始计数,冈此 while循环得循环条件应为 knext。 (4)处用于实现输出出圈者的编号。根据题目中 Jo-seph函数处理思路 (2)的
30、描述,当 k的值等于 m一 1时, p应指向出圈者对应结点的前驱结点。因此, p-next所指向的结 点是要被删除的结点,其编号为 p-next-No。因此, (4)处应填入 p-next-No。 (5)处用于实现删除出圈者对应的结点。删除 p所指结点的后继结点的处理思路为:使指针 q指向 p所指结点的后继结点,即 q=p-next,然后使 p所指结点的next指针指向 (1所指结点的后继结点,即 p-next=q-next,这是典型的在链表中删除结点的方法。因此, (5)处应填入 p-next。 5 【正确答案】 (1): public ComputerAsset (2): public C
31、omputerAsset, public PowerSwitchable (3)PowerSwitchable* (4)numItems+ (5)new 【试题解析】 本题考查考生使用 C+语言进行而向对象程序设计的能力。首先要看懂所给类图中类与类之间的关系,然后阅读程序以实现类图中表示的各个要素。 (1)处考查类 cornputerCPU。从类图中可以看出,类 computerCPU表示计算机主机,其继承了类 ComputerAs-set。 computerCPU是 CoreputerAsset的子类,并且在 com-puterCPU的构造函数中,调用了父类 ComputerAsset的构造
32、函数,因此继承的权限为 public。因此, (1)处应填入: public ConlputerAsset。 (2)处考查类 computerMonitor。从类图中可以看出,类 computerMonitor表示计算机显示器,其继承了类 Com-puterAsset。 computerCPU是 ComputerAsset的子类,而且均是可关闭的,具有开关电源的相同接口,均继承了类PowerSwitchable,并且在 computerCPU的构造函数中,调用了其父类的构造函数,因此继承的权限为 public。两个父类的继承格式为: public父类 1, public父类 2。因此, (2)
33、处应填入: public ComputerAsset, public POwerSwitchable。 系统中有各类资产,在类 BuldingManagement中使用 Asset通用资产类型数组,用 add函数依次为建筑添加资产。由于 add函数中对数组添加元素只有一条语句,需要在下标中完成指明当前添加资产元素的下标,并将下标后移。在goodNight函数中对可关闭的资产进行控制,需要判定其是否可关闭,也就是资产是否为类 PowerSwitchable的子类。通过动态类型转换进行判定,如果资产类型是PowerSwitchable的子类,则转换后的类型调用相应接口,并绑定到具体对象,执行对象的
34、关闭电源行为。 (3)处实现动态类型转换为抽象类,因此应填入 PowerSwitchable*。 (4)处指明当前添加资产元素的下标,并将下标后移,应填入 numltems十十。 类 BuldingManagement中没有定义构造函数,编 译器会自动生成一个默认的构造函数,采用 new关键字进行对象创建。在使用完之后,通过 delete进行释放。 (5)处补充通过使用编泽器生成的默认的构造函数进行对象创建,应填入 new。 6 【正确答案】 (1)extends BuildingLight (2)extends BuildingLight implements PowerSwitchable
35、 (3)PowerSwitchable (4)numltems+ (5)new 【试题解析】 本题考查考生使 用 Java语言进行面向对象程序设计的能力。首先要看懂所给类图中类与类之间的关系,然后阅读程序以实现类图中表示的各个要素。 (1)处考查类 EmergencyLight。从类图中可以看出,类 EmergencyLight表示应急灯,其继承了类 BuildingLight。 EmergencyLight是 BuildingLight的子类,并且在 EmergencyLight的构造方法中,调用了父类 BuildingLight的构造方法,采用 super(),而且调用父类的构造方法必须是
36、构造方法的第一条语句。在 Java语言中,继承父类用 extends父类来表示。因此, (1)处应填入 extends BuildingLight。 (2)处考查类 RoomLights。从类图中可以看出,类 RoomLights表示可在夜间关闭的房灯,其继承了类 BuildingLight。 RoomLights是 BuildingLight的子类,而且均是可关闭的,具有开关电源的相同接口,均继承了类 PowerS witchable,并且在 RoomLights的构造方法中,调用了其父类的构造方法。 Java语言中的继承是单根继承,即一个类只能有一个 父类,而接口可以实现多个,因此将Pow
37、erSwitchable定义为接口,使用 interface关键字。类 RoomLights和ComputerMonitor均实现 PowerSwitchable接口,使用 implements关键字。 (2)处用于添加继承和实现接口,应填入 extends BuildingLight implements PowerSwitchable。 系统中有各类资产,在类 BuldingManagement中使用 Asset通用资产类型数组,用 add函数依次为建筑添加资产。南于 add方 法中对数组添加元素只有一条语句需要在下标中完成指明当前添加资产元素的下标,并将下标后移。在goodNight方法
38、中对可关闭的资产进行控制,需要判定其是否可关闭,也就是资产是否为类 PowerSwitchable的实例。用 instanceof关键字,判断对象是否为实现通用接口 PowerSwitchable类型的实例。如果对象的类型是实现 PowerSwitchable接口的类型,则转换为 PowerSwitehable接口类型,并利用动态绑定机制,正确绑定到具体对象,执行对象的关闭电源行为。 (3)处将接 口作为一种引用类型,用 instanceof判断对象是否为接口类型,因此应填入 Pow-erSwitchable。 (4)处指明当前添加资产元素的下标,并将下标后移,应填入 numltems十十。 类 BuldingManagement中没有定义构造方法,编译器会自动生成一个默认的构造方法,采用 new关键字进行对象创建。在使用完之后,通过 delete进行释放。 (5)处补充通过使用编译器生成的默认的构造方法进行对象创建,应填入 new。