1、2007年下半年软件水平考试(初级)程序员下午(应用技术)试题真题试卷及答案与解析 1 阅读以下说明和流程图,填补流程图中的空缺 (1) (5)。 【说明】 某单位动态收集的数据中常包含重复的数据,所以需要进行处理,使得重复的数据仅出现一次。下面流程图的功能是:在 n(n1)个数据 D1、 D2、 、 Dn中,选出其中所有不重复的 k个数据,置于原来前 k个数据的位置上。 该流程图的算法如下:第 1个数据必然被选出,然后从第 2个数据开始,逐个考查其余的数据。假设 D1、D2、 、 Dm(m1)是已经选出的、不重复的数据, 则对于数据 Di(m in),将其依次与 DmDm-1、 、 D1进行
2、比较,若没有发现与之相同者,则 Di被选出并置于 Dm+1的位置上;否则对 Di不做处理。 例如,如下 10个数据: 5, 2, 2, 7,4, 4, 7, 1, 9, 1 (n=10) 经过上述算法处理后的结果为: 5, 2, 7, 4, 1, 9 (k=m=6) 【流程图】 注:循环开始的说明按照 “循环变量名:循环初值,循环终值,增量 ”格式描述。 2 阅读以下说明和 C语言函数,将应填入 (n)处。 【说明】 已知 1900年 1月 1日是星期一,下面 的函数 count_5_13(int year)用于计算给定的年份 year中有几个 “黑色星期五 ”。 “黑色星期五 ”指既是 13
3、日又是星期五的日期。 函数 count_5_13(int year)首先算出年份 year的 1月 13日是星期几,然后依次计算每个月的 13日是星期几,若是星期五,则计数。 程序中使用了函数 isLeapYear(int year),其功能是判断给定年份是否为闰年,返回值为 1(或 0)表示 year是 (或不是 )闰年。 【 C语言函数】 int count_5_13(int year) int date; /*date为 0表示星期日,为 1 6分别表示星期一至星期六 */ long days=0; /*days记录天数 */ int m, y, c=0; /*c用于表示黑色星期五的个数
4、 */ if (year 1900) return-1; /*计算从 1900年 1月 1日起至给定年份 year的 1月 13日间隔的天数 */ days=12; for (y= 1900; y year; y+) days +=365; if (isLeapYear(y)(1); date=(days%7) +1) %7; /*算出给定年份 year的 1月 13日是星期几 */ c=(2) ?1: 0; for(m=1; (3); m+) switch (m) case 1: case 3: case 5: case 7: case 8: case 10: case 12: days=3
5、1; break; case 4: case 6: case 9: case 11: days=30; break; case 2: days=28; if(4) days=29; break; /*end of switch*/ date=(days%7)+ (5) )%7; if (date=5) c+; /*end of for*/ return c; 3 阅读以下说明和 C语言程序,将应填入 (n)。 【说明】 某电信公司记录了每个用户的详细通话情况 (每次通话数据记录在一行 ),现将某用户某月的通话数据存入一个文本文件 dial.txt,其数据格式如下: 拨入或拨出标记通话开始时间通
6、话结束时间对方号码 注 1:数据字段以一个空格作为分隔符。 注 2:拨入和拨出标记均为小写字母。拨入标记为 i,表示其他用户呼叫本机,本机用户不需付费:拨出标记为 o,表示本机呼叫其他用户,此时本机用户需要付费。 注 3:通话开始和结束时间的格式均为 HH: MM: SS。其中 HH表示小时,取值00 23; MM表示分钟,取值 00 59; SS表示秒,取值 00 59。从通话开始到结束这段时间称为通话时间,假定每次通话时间以秒为单位,最短为 1秒,最长不超过 24小时。 注 4:跨月的通话记录计入下个月的通话数据文件。 例如 “o23: 01: 1200: 12: 15” 表示本次通话是本
7、机呼叫其他用户,时间从 23时 01分 12秒至次日的 0时 12分 15秒,通话时间为 71分 03秒。 下面程序的功能是计算并输出该用户本月电话费 (单位:元 )。 通话计费规则为: 1月通话费按每次通话费累加; 2每次的通话费按通话时间每分钟 0.08元计算,不足 1分钟时按 1分钟计费。 对于每次的拨出通话,程序中先分别计算出通话开始和结束时间相对于当日 0点0分 0秒的时间长度 (以秒为单位 ),然后算出本次通话时间和通话费。 例如,若输入 文件 dial.txt的数据如下所示,则输出 fee=7.44。 o 14: 05: 23 14: 11: 25 82346789 i 15:
8、10: 00 16: 01: 15 13890000000 o 10: 53: 12 11: 07: 05 63000123 o 23: 01: 12 00: 12: 15 13356789001 【 C程序代码】 #include stdio.h FILE *fin; Int main() char str80; int h1, h2, m1, m2, s1, s2; long t_start, t_end, interval; int c; double fee=0; fin=fopen(“dial.txt“, “r“); if (!fin) return-1; while (!feof(
9、fin) if (!fgets(str, 80, fin) break; if ( (1) ) continue; h1= (str2 -48) *10+str3 -48; m1= (str5 -48) *10+str6 -48; s1= (str8 -48) *10+str9 -48; h2= (str11 -48) *10+str12 -48; m2= (str14 -48) *10+str15 -48; s2=(str17-48)*10+str18-48; t_start=h1*60*60+m1*60+s1; /*通话开始时间 */ t_end=h2*60*60+m2.60+s2; /*
10、通话结束时间 */ if( (2) ) /*若通话开始和结束时间跨日 */ interval; (3)-t_start+t_end; else interval=t_end-t_start; c= (4) ; /*计算完整分钟数表示的通话时间 */ if (interval % 60) (5); fee+=c*0.08; fclose(fin); printf(“fee=%.2lfn“, fee); return 0; 4 阅读以下说明和 C语言函数,将应填入 (n)。【说明】 已知包含头结点 (不存储元素 )的单链表的元素已经按照非递减方式排序,函数 compress(NODE*head)的
11、功能是去掉其中重复的元素,使得链表中的元素互不相同。 处理过程中,当元素重复出现时,保留元素第一次出现所在的结点。 图 2-1(a)、 (b)是经函数 compress()处理前后的链表结构示例图。 链表的结点类型定义如下: typedef struct Node int data; struct Node *next; NODE; 【 C语言函数】 void compress(NODE *head) NODE *ptr, *q; ptr= (1); /*取得第一个元素结点的指针 */ while( (2)& ptr- next) q=ptr- next; while(q&(3) /*处理重复
12、元素 */ (4)q- next; free(q); q=ptr- next; (5) ptr- next; /*end of while */ /*end of compress*/ 5 阅读以下应用说明以及 Visual Basic程序代码,将应填入 (n)。 【应用说明】 某电视台拟开发应用程序来显示戏曲大赛中 1 4号四位选手决赛的现场投票情况。该程序从现场观众中 (不超过 2000人 )每 0.5秒收集一次对这四位选手的支持票数,并在屏幕上动态显示这四位选手的票柱 (以高度反映票数 )与累计得票数,如图 2-3所示。投票过程限时 30秒 ,每名观众最多为 1名选手投票。投票结束后系统
13、通过比较各位选手的累计得票数,显示决赛结果: “*号胜出 ”(如有单个冠军 )或 “继续进行PK”(如有多人获得相同的最高票数 )。 在开发该程序的过程中创建的主要控件及其初始属性值说明如下: 该程序中设置公共变量 T动态记录投票时间。四个形状 ShpM(1 to 4)动态增长的底线固定。 【 Visual Basic程序代码】 Dim T As Integer 声明全局变量 Private Sub Form_Load() For i=1 To 4 ShpM(i).Top=2000 : ShpM(i).Height=0 初始票柱高度为 0 TxtM(i).Text=0 Next i Timl.
14、Enabled=False : Timl.Interval=500 : T=0 End Sub Private Sub CmdStart Click() Timl.Enabled=True 开始投票 CmdStart.Enabled=False End Sub Private Sub Timl Timer() Dim n(1 To 4) As Integer n(1 to 4)为每次收集的票数 Dim i As Integer, j As Integer Dim G As Integer G用于计算最高票数 Dim ng As Integer ng用于计算冠军个数 For i=1 To 4 n
15、(i)=. 收集 i号选手的票数,此处省略 TxtM(i).Text=TxtM(i).Text+n(i) 累计票 (VB能进行自动转换 ) ShpM(i).Top=ShpM(i).Top-n(i) ShpM(i).Height=ShpM(i).Height+(1) 算出票柱高度 Next i T=T+1 计时 If T=60 Then 投票时间到 (2) 停止数据收集处理 ng = 1 G=TxtM(1).Text For i=2 To 4 If G TxtM(i).Text Then G=TxtM(i).Text ng=(3) j = i Else If G=TxtM(i).Text The
16、n ng=(4) 计算冠军个数 End If Next i If ng=1 Then txtResult. Text=(5) 单个冠军结果 Else txtResult. Text=“继续进行 PK“ End If End If End Sub 6 阅读下列说明、图和 C+代码,回答问题 1至问题 3。 【说明】 已知四个类之间的关系如图 2-2所示,分别对每个类的方法进行编号,例如 Shape的 perimeter()方法为 1号,表示为 1: perimeter(), Rectangle类的 perimeter()为 2号,表示为 2:perimeter(),依此类推,其中,每个类的 pe
17、rimeter方法都为虚函数且方法签名相同。 【 C+代码】 Triangle *tr=new Triangle(); Square *sq=new Square(); Shape *sh =tr; 6 关于上述 C+代码中 sh和 tr的以下叙述中,哪两个是正确的 (写出编号 )。 sh和 tr分别引用同一个对象; sh和 tr分别引用同一类型的不同的对象: sh和 tr分别引用不同类型的不同对象; sh和 tr分别 引用同一个对象的不同备份: sh和 tr所引用的内存空间是相同的。 7 写出下面消息对应的方法编号 (如果该消息错误或者没有对应的方法调用,请填写 “无 ”)。 tr- hei
18、ght() (1) sh- perimeter() (2) sq- height() (3) sq- perimeter() (4) sh- height() (5) tr- perimeter() (6) 8 不考虑内存释放问题,下列赋值 语句中哪两个是合法的 (写出合法赋值语句的编号 )。 sq=sh; sh=tr; tr=sq; sq=tr; sh=sq; 9 阅读下列说明、图和 Java代码,回答问题 1至问题 3。 【说明】 已知四个类之间的关系如图 2-4所示,分别对每个类的方法进行编号,例如 Shape的 perimeter()为 1号,表示为 1: perimeter(), R
19、ectangle类的 perimeter()为 2号,表示为 2:perimeter(),依此类推,其中,每个类的 perimeter方法签名相同。 【 Java代码】 Triangle tr=new Triangle(); Square sq=new Square(); Shape sh=tr; 9 关于上述 Java代码中 sh和 tr的以下叙述中,哪两个是正确的 (写出编号 )。 sh和 tr分别引用同一个对象; sh和 tr分别引用同一类型的不同的对象: sh和 tr分别引用不同类型的不同对象: sh和 tr分别引用同一个对象的不同拷贝; sh和 tr所引用的内存空间是相同的。 10
20、写出下面消息对应的方法编号 (如果该消息错误 或者没有对应的方法调用,请填写 “无 ”)。 tr.height() (1) sh.perimeter() (2) sq.height() (3) sq.perimeter() (4) sh.height() (5) tr.perimeter() (6) 11 下列赋值语句中哪两个是合法的 (写出合法赋值语句的编号 )。 sq=sh; sh=tr; tr=sq; sq=tr; sh=sq; 2007年下半年软件水 平考试(初级)程序员下午(应用技术)试题真题试卷答案与解析 1 【正确答案】 (1)1(2)2(3)m(4)Dm+1(5)mm+1 ,或
21、其等价表示 【试题解析】 本题涉及信息处理工作中常用的算法。动态收集得到的一批记录中,常包含有某些重复的记录。在做进一步处理前,应当删除这些重复记录。所谓重复记录,通常是指那些具有相同关键词的记录。注意,从经验上看,重复记录往往出现在比较临近的记录中。为了删除重复记录,可以采用本题中的算法思想。 对于题中给出的例子,该算法执行的动态情况如下表: 具体做法如下: 逐个考查 D1, D2, , D10的内容。 首先,保留 D1中的内容 5,将其作为已经选出的不重复数据,此时 m应是 1。 考查 D2时,将其与 D1 进行比较,发现不同,所以保留,形成不重复数据 D1、 D2,此时 m=2。 考查
22、D3时,分别将其与 D2、 D1 进行比较,发现有重复,不做处理。 考查 D4时,分别将其与 D2、 D1进行比较,发现不同,将 D4 的内容放到 D3中,形成不重复数据 D1、D2、 D3,此时 m=3。 考查 D5时,分别将其与 D3 D1进行比较,发现不同,将 D5的内容放到 D4中,形成不重复数据 D1 D4,此时 m=4。 考查 D6时,分别将其与 D4 D1 进行比较,发现有重复,不做处理。 考查 D7时,分别将其与 D4 D1 进行比较,发现有重复,不做处理: 考查 D8时,分别将其与 D4 D1进行比较,发现不同,将 D8 的内容放到 D5中,形成不重复数据 D1D5,此时 m
23、=5。 考查 D9时,分别将其与 D5 D1进行比较,发现不同,将D9的内容放到 D6 中,形成不重复数据 D1 D6,此时 m=6。 考查 D10时,分别将其与 D6 D1进行比较,发现有重复,不做处理。 考查结束,形成不重复数据 D1 D6,此时 m=6。 对于一 般的情况,就要逐个考查 D1,D2, , Dn 的内容。 首先 保留 D1 中的内容,作为已选出的不重复数据,此时设置 m=1。 对于已经选出的不重复数据 D1, D2, , Dm,考查 Di(min),将其与 Dm, Dm-1, , D1逐一比较。若发现有重复,则不做处理;发现完全不同时,应将 Di 的内容放入 Dm+1,然后
24、,将 m增加 1。 注意,在考查Di 时,由于重复数据离它更近些,将其与 Dm, Dm-1, , D1 逐一比较可以节省时间;若与 D1, D2, , Dm逐个比较,发现重复的时间会比较长一些。对于程序员来说,能在细节处适当考虑程序的效率也是好的。 因此,在本题的流程图中, (1)处应填 1,表示初始时设置 m=1。 对于 /2个数据 (n 1)而言,接着应逐个考查 D2, , Dn的内容,因此循环应对 i=2, n, 1进行,所以 (2)处应填2。 考查 Di时,需要将其分别与 Dm, Dm-1, , D1逐一比较,所以循环应对, j=m, 1, -1进行,从而 (3)处应填 m。 若在比较
25、过程中发现重复,则直接返回主程序 (不做处理 );若始终没有发现重复数据,则应将 Di存入Dm+1,所以 (4)处应填 Dm+1。然后,应将重复数据数目加 1,所以 (5)处应填mm+1( 或 m+1 m)。 2 【正确答案】 (1)days+, days+=1, days=days+1,或其等价表示 (2)date=5,或其等价表示 (3)m 12,或其等价表示 (4)isLeapYear(year),或 year%4=0 & year%100!=0|year%400=0,或其等价表示 (5)date 【试题解析】 本题考查基本程序设计能力。 题中程序用于计算给定年份中 “黑色星期五 ”(既
26、是 13日又是星期五的日期 )的数目。 基本的常识为平年每年 365天、闰年 366天。若今天是星 期三 (date),则 7天后的那天也是星期三,依此类推,可算出 m天后为星期几 (date+m)%7,为 0表示星期日 )。 题目中给出了 1900年 1月 1日是星期一,因此,对于给定的日期,首先需要算出其距离 1900.1.1的天数,然后用上式计算该日期对应星期几。 要计算给定年份中有几个 “黑色星期五 ”,可先计算出该年份的 1月 13日是星期几,然后计算该年内每月的 13日是星期几。所以,程序中首先计算出 1900年 1月 1日至给定年份的 1月 13日共有多少天 (days)。 在计
27、算给定日期段的天数时,需要考虑大、 小月,对于 2月份,则需要考虑当前年号是否为闰年。期间若跨年度,则按每年 365天 (闰年 366天 )累加天数。对于以下代码段: for (y = 1900; y year; y+) days+=365; if(isLeapYear(y) (1) ; 显然,程序中空 (1)处应填入 days+或其等价表示形式。 根据程序中的注释,经语句 date=(days%7)+1)%7;处理后, date表示给定年份的 1月 13日是星期几,而 c用于表示 “黑色星期五 ”的个数,因此空 (2)处应填入 date=5。 在下面的代码中,计算给定年份 2月份之后每个月的
28、 13日星期几 (计算天数时需要考虑大、小月, 2月份要考虑是否为闰年 ),其中 m表示月号。 for(m=1; (3) ; m+) switch (m) case 1: case 3: case 5: case 7: case 8: case 10: case 12: days=31; break; case 4: case 6: case 9: case 11: days=30; break; case 2: days=28; if( (4) ) days=29; break; /*end of switch*/ 由于 1月 13日已经考虑过,因此需要考虑的日期为 2月至 12月的每个 1
29、3日,当月份 m为 12时,再计算出的日 期就是下一年度的 1月 13日了,因此空 (3)处应填入 m 12,空 (4)处显然是判断当前年号是否为闰年,因此应填入isLeapYear(year)或 isLeapYear(y)。 对于代码 date (days%7)+ (5) %7;,之前已用 date表示上个月 13日是星期几, days表示间隔的天数,因此空 (5)处应填入 date。 3 【正确答案】 (1)str0=i,或 *str=i,或其等价表示 (2)t end t start,或其等价表示 (3)24*60*60,或 86400,或其等价表示 (4)interval/60 (5)
30、c+, c+=1, c=c+1,或其等价表示 【试题解析】 本题考查基本程序设计能力。 对于读入的每一条通话记录,首先判断其是 i还是 o,若是 i(拨入 ),则不计费,然后读入下一条通话记录,因此空 (1)处应填入 str0=i(或 *str=i)。 根据通话开始时间和结束时间的计算方式 (相对于当日 0点 0 分 0秒的时间长度 ),一般情况下,若通话的开始时间和结束时间在同一天内,则结束时间应大于开始时间。但是若通话从 0点前卉始而结束于 0点之 后,则会出现开始通话时间大于结束通话时间的情况,因此 0点之前到 0点整的通话长度就是全天的秒数减去以秒为单位的开始时间,即 24*60*60
31、-t start。因此空, (2)处填入 t end t start,而空 (3)处填入 24*60*60或 86400。 从程序中可知, interval 是以秒为单位的通话长度,而话费是以分钟为单位计算的,所以空 (4)处填入 interval/60,剩余时间则按一分钟计费,因此空 (5)处填入c+。 4 【正确答案】 (1)head- next (2)ptr (3)q- data = ptr- data 或 ptr- next- data=ptr- data,或其等价表示 (4)ptr- next (5)ptr 【试题解析】 本题考查基本程序设计能力。 链表上的查找、插入和删除运算是常见
32、的考点。本题要求去掉链表中的重复元素,使得链表中的元素互不相同,显然是对链表进行查找和删除操作。 对于元素已经按照非递减方式排序的单链表,删除其中重复的元素,可以采用两种思路。 1顺序地遍历链表,对于逻辑上相邻的两个元素,比较它们是否相同,若相同,则删除后一个元 素的结点,直到表尾。代码如下: ptr=head- next; /*取得第一个元素结点的指针 */ while (ptr & ptr- next) /*指针 ptr指示出重复序列的第一个元素结点 */ q=ptr- next; while(q & ptr- data=q- data) /*处理重复元素 */ ptr- next=q-
33、next; /*将结点从链表中删除 */ free(q); q=ptr- next; /*继续扫描后继元素 */ ptr=ptr- next; 2对于每一组重复元素,先找到其中的第一个结点,然后向后查找,直到出现一个相异元素时为止,此时保留重复元素的第一个结点,其余结点则从链表中删除。 ptr=head- next; /*取得第一个元素结点的指针 */ while (ptr & ptr- next) /*指针 ptr指示出重复序列的第一个元素结点 */ q=ptr- next; while(q & ptr- data=q- data) /*查找重复元素 */ q=q- next; s=ptr-
34、 next; /*需要删除的第一个结点 */ ptr- next=q; /*保留重复序列的第一个结点,将其余结点从链表中删除 */ while (s & s!=q /*逐个释放被删除结点的空间 */ t = s- next; free(s); s = t; ptr=ptr- next; 题目中采用的是第一种思路。 5 【正确答案】 (1)n(i)(2)Timl.Enabled=False(3)1 (4)ng+1(5)Str$(j)+“号胜出 ”,或 Str(j)+“号胜出 ” 【试题解析】 本题是 VB 应用程序设计题,涉及到文本框、命令按钮、定时器、形状和控件数组的设计方法。 同一控件数组中
35、的各个控件,具有相同的名、不同的下标。采用控件数组有利于在程序中进行循环处理。在开发时,只要设计了一个控件,再 用复制的方法就能形成控件数组。 在本题的程序代码中,一开始就设置 T为整数类型的全局变量,用于定时计数(以半秒为单位 )。因为初始加载主窗口的过程 Form Load 时需要为它赋初始值 0,而每次进入定时过程 Timl Timer时需要增 1,退出该过程后需要保留其值。 主窗口的过程 Form Load 在每次启动应用程序时都会自动加载并执行,因此在该过程中需要设置 4个票柱形状的初始位置,还需要设置 4个得票数文本框的初始内容及定时器的初始参数。 4个票柱形状 ShpM(1) S
36、hpM(4)在开发时就已设置成 矩形 (属性 Shape=0)、实心(属性 Fillstyle=0)、高度为 0(属性 Height=0)。而在每次程序运行时,这几个形状的顶部位置 (属性 Top值 )及高度 (属性 Height值 )都会有变化,所以在过程Form_Load 中,应该设置初始值,起到恢复作用。这是编程时应该养成的良好习惯。 该过程中, 4个票柱形状的顶部位置都设置成像素 2000,而且高度为 0,所以,初始时 4个票柱都呈现在同一水平线上。 该过程中,各个得票数文本框 TxtM(i)内容均设置为 0(系统会自动进行数值与字符的转换 )。定时器的初 始参数设置包括属性 Enab
37、le=False(关闭 )、属性Interval=5000(时间间隔设置为 500ms,即半秒 )。 在命令按钮 “开始投票 ”(CmdStart)的单击过程 (CmdStart Click)中,需要将定时器设置成打开可用状态 (Timl.Enable=Tree)。这时,定时器将按时间间隔属性所确定的时间发出中断,触发 Timl Timer过程。在该过程中,还需要将 “开始投票 ”命令按钮颜色变灰 (CmdStart.Enable=False),使其暂时不允许用户使用。这也是程序员应养成的良好习惯 。 本题的重点是定时器的触发过程 Timl Timer。 在该过程中,首先需要定义本过程内部使用
38、的整数类型的局部变量,包括动态收集的 4个选手的票数 n(1) n(4),这几个数中的最大值 G,票数等于 G的人数ng,以及过程内部临时用的变量 i与 j。 接着,对 4位选手进行循环计票处理:先收集在此时间间隔内第 i位选手得到的票数 n(i),再在得票数文本框中进行累计 (注意, VB能自动将数值类型转换成字符串类型 ),并动态显示出来,同时需要调整该选手的票柱形状。 形状 ShpM(i)的顶部位置在屏幕上应往 上升,而 top属性值则应减少 (因为属性Top 值是与屏幕顶部的距离,以像素为单位 )。本应用设计时考虑到现场最多 2000人,票数还会分散给 4人。程序中 Top的初始值设置
39、为 2000,并动态地每次减去得票数 n(i)作为新的票柱顶部位置。为维持票柱底部不变,该票柱形状的高度显然也应该增加 n(i)。因此, (1)处应填写 n(i)。 接着,对时间计数变量 T 增 1。 由于规定投票限时为 30s,而且每半秒动态收集票数 1次 (T 增 1),所以当 T=60时,应关闭定时器 timl,结束投票,并进行投票结果的处理。在 T 60时, 上述定时过程就不需要这些处理了,这时就可以退出该过程了。 因此在 If T=60 Then语句后,在 (2)处应填写 Timl.Enable=False,关闭定时器。 随后,还需要比较谁是冠军。如有多个并列冠军,则还需要继续进行
40、PK。 因此,需要在 TxtM(1) TxtM(4)之间寻找最大值,并求出其中达到最大值的个数。 在比较之前,应设置冠军个数的初始值 ng=1及最大值 G的初始值。由于后面有对选手 2 4的循环,所以 G的初始值设置成 TxtM(1)的内容。 对选手 2 4的循环比较中,当 某个选手的票数不超过 G时,不需要做处理;当某个选手的票数等于 G时,应将冠军个数 ng 增 1,因此 (4)处应填写 ng+1。当某个选手的票数超过 G时,应将选手号码保留在 j中,并用该票数更新 G,同时需要再次设置冠军个数 ng=1。再次设置冠军数非常重要,因为在此之前,冠军数 ng可能已经大于 1。当出现新的冠军时
41、, ng必须调整为 1,因此 (3)处应填写 1。这是程序员最容易犯错误的地方,也是本题最难之处。 最后,如果比赛的结果只有 1个冠军,则显示决赛结果 “j号胜出 ”。其中的 j应显示其具体的值。在程序中应该用 str(j)或 str$(j)表示。所以 (5)处应填 str(j)+“号胜出 ”,或 str$(j)+“号胜出 ”。 当出现多个冠军时,屏幕显示 “继续进行 PK”。 6 【正确答案】 7 【正确答案】 (1)3(2)5(3)无 (4)4(5)无 (6)5 8 【正确答案】 【试题解析】 根据 C+代码: Triangle *tr=new Triangle(); Square *sq
42、=new Square(); Shape *sh=tr; 可以得出下面的结论: tr指向一个 Triangle对象, sq指向一个 Square对象, sh和 tr指向同一个 Triangle对象。下面对问题 1给出的论断进行判断, 、 正确,由于 sh和 tr指向同一个对象,因此其引用的内存空间也是相同的,不存在不同的备份。 、 和 错误。 根据题目的描述,我们知道 perimeter是虚拟函数,所以所有通过 sh 调用的perimeter都将实际调用 Triangle类的 perimeter方法。 .tr- height():因为 tr 指向一个 Triangle对象,所以调用 Trian
43、gle 类的 height方法 。 .sh- perimeter():因为 sh 指向的是一个 Trangle对象,所以调用 Triangle类的 perimeter方法。 .sq- height():因为 sq 指向的是 Square对象,但 Square类并没有 height方法,所以未对应任何方法调用。 .sq- perimeter():因为 sq 指向的是 Square对象,所以调用 Square类的perimeter方法。 .sh- height():虽然 sh 指向的是一个 Trangle对象, sh中并未定义 height方法,所以此调 用错误。 .tr- perimeter()
44、:因为 tr指向一个 Triangle对象,所以调用 Triangle类的perimeter方法。 问题 3主要考虑类型问题,我们只能够将子类类型的实例或引用赋值给父类类型的变量或引用。因此,赋值运算的左边一定是右边的父类或同一类型。正确的只有 和 。 9 【正确答案】 10 【正确答案】 (1)3(2)5(3)无 (4)4(5)无 (6)5 11 【正确答案】 【试题解析】 根据 Java代码: Triangle tr=new Triangle(); Square sq=new Square(); Shape sh=tr; 可以得出下面的结论: tr引用一个 Triangle对象, sq引用
45、一个 Square对象, sh和 tr引用同一个 Triangle对象。因此,对问题 1给出的论断, sh和 tr引用同一个对象,其引用的内存空间也是相同的, 和 正确。对于论断 ,由于 sh 和 tr引用同一类型的同一个对象,因此不存在不同的备份。 根据题目的描述,我们知道 perimeter是虚拟函数,所以所有通过 sh 调用的perimeter都将实际调用 Triangle类的 perimeter方法。 .tr- height():因为订引用一个 Triangle对象,所以调用 Triangle 类的 height方法。 .sh- perimeter():因为 sh 引用的是一个 Tra
46、ngle对象,所以调用 Triangle类的 perimeter方法。 .sq- height():因为 sq 引用的是 Square对象,但 Square类并没有 height方法,所以未对应任何方法调用。 .sq- perimeter():因为 sq 引用的是 Square对象,所以调用 Square类的perimeter方法。 .sh- height():虽然 sh 引用的是一个 Trangle对象, sh中并未定义 height方法,所以此调用错误。 .tr- perimeter():因为 tr引用一个 Triangle对象,所以调用 Triangle类的perimeter方法。 问题 3主要考虑类型的问题,我们只能够将子类类型的实例或引用赋值给父类类型的变量或引用。因此,赋值运算的左边一定是右边的父类或同一类型。正确的只有 和 。