打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
初级程序员2007下半年下午试题
第2章  程序员下午试题[分析]与解答
试题一
阅读以下说明和流程图,填补流程图中的空缺(1)~(5)。
【说明】
某单位动态收集的数据中常包含重复的数据,所以需要进行处理,使得重复的数据仅出现一次。下面流程图的功能是:在n(n≥1)个数据D1、D2、…、Dn中,选出其中所有不重复的k个数据,置于原来前k个数据的位置上。
该流程图的算法如下:第1个数据必然被选出,然后从第2个数据开始,逐个考查其余的数据。假设D1、D2、…、Dm(m≥1)是已经选出的、不重复的数据,则对于数据Di(m<i≤n),将其依次与Dm\Dm-1、…、D1进行比较,若没有发现与之相同者,则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)
【流程图】
注:循环开始的说明按照“循环变量名:循环初值,循环终值,增量”格式描述。
答案
(1)1  (2)2  (3)m  (4)D[m+1]
(5)m←m+1,或其等价表示
试题一[分析]
本题涉及信息处理工作中常用的算法。动态收集得到的一批记录中,常包含有某些重复的记录。在做进一步处理前,应当删除这些重复记录。所谓重复记录,通常是指那些具有相同关键词的记录。注意,从经验上看,重复记录往往出现在比较临近的记录中。为了删除重复记录,可以采用本题中的算法思想。
对于题中给出的例子,该算法执行的动态情况如下表:
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
5
2
2
7
4
4
7
1
9
1
5
2
7
4
1
9
具体做法如下:
逐个考查D1,D2,…,D10的内容。
首先,保留D1中的内容5,将其作为已经选出的不重复数据,此时m应是1。
考查D2时,将其与D1进行比较,发现不同,所以保留,形成不重复数据D1、D2,此时m=2。
考查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中,形成不重复数据D1~D5,此时m=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(m<i≤n),将其与Dm,Dm-1,…, D1逐一比较。若发现有重复,则不做处理;发现完全不同时,应将Di的内容放入Dm+1,然后,将m增加1。
注意,在考查Di时,由于重复数据离它更近些,将其与Dm,Dm-1,…,D1逐一比较可以节省时间;若与D1,D2,…,Dm逐个比较,发现重复的时间会比较长一些。对于程序员来说,能在细节处适当考虑程序的效率也是好的。
因此,在本题的流程图中,(1)处应填1,表示初始时设置m=1。
对于/2个数据(n>1)而言,接着应逐个考查D[2],…,D[n]的内容,因此循环应对i=2,n,1进行,所以(2)处应填2。
考查D[i]时,需要将其分别与D[m],D[m-1],…,D[1]逐一比较,所以循环应对,j=m, 1,-1进行,从而(3)处应填m。
若在比较过程中发现重复,则直接返回主程序(不做处理);若始终没有发现重复数据,则应将D[i]存入D[m+1],所以(4)处应填D[m+1]。然后,应将重复数据数目加 1,所以(5)处应填m←m+1(或m+1→m)。
试题二
阅读以下说明和C语言函数,将应填入  (n)  处。
【说明】
已知1900年1月1日是星期一,下面的函数count_5_13(int year)用于计算给定的年份year中有几个“黑色星期五”。“黑色星期五”指既是13日又是星期五的日期。
函数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用于表示黑色星期五的个数*/
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=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*/
date=((days%7)+   (5)  )%7;
if  (date==5)  c++;
}  /*end of for*/
return  c;
}
答案
(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
试题二[分析]
本题考查基本程序设计能力。
题中程序用于计算给定年份中“黑色星期五”(既是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)。
在计算给定日期段的天数时,需要考虑大、小月,对于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月份之后每个月的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月的每个13日,当月份m为12时,再计算出的日期就是下一年度的1月13日了,因此空(3)处应填入 m<12,空(4)处显然是判断当前年号是否为闰年,因此应填入isLeapYear(year)或 isLeapYear(y)。
对于代码date=((days%7)+  (5)  %7;,之前已用date表示上个月13日是星期几,days表示间隔的天数,因此空(5)处应填入date。
试题三
阅读以下说明和C语言程序,将应填入  (n)  。
【说明】
某电信公司记录了每个用户的详细通话情况(每次通话数据记录在一行),现将某用户某月的通话数据存入一个文本文件dial.txt,其数据格式如下:
拨入或拨出标记通话开始时间通话结束时间对方号码    注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…”表示本次通话是本机呼叫其他用户,时间从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: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 str[80];
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(fin))  {
if  (!fgets(str,80,fin))  break;
if  (  (1)  )    continue;
h1=  (str[2]  -48)  *10+str[3]  -48;
m1=  (str[5]  -48)  *10+str[6]  -48;
s1=  (str[8]   -48)  *10+str[9]  -48;
h2=  (str[11]  -48)  *10+str[12] -48;
m2=  (str[14]  -48)  *10+str[15] -48;
s2=(str[17]-48)*10+str[18]-48;
t_start=h1*60*60+m1*60+s1;  /*通话开始时间*/
t_end=h2*60*60+m2.60+s2;    /*通话结束时间*/
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=%.2lf\n",fee);
return 0;
}
答案
(1)str[0]=='i',或*str=='i',或其等价表示
(2)t end<t start,或其等价表示
(3)24*60*60,或86400,或其等价表示
(4)interval/60
(5)c++,c+=1,c=c+1,或其等价表示
试题三[分析]
本题考查基本程序设计能力。
对于读入的每一条通话记录,首先判断其是i还是o,若是i(拨入),则不计费,然后读入下一条通话记录,因此空(1)处应填入str[0]=='i'(或*str=='i')。
根据通话开始时间和结束时间的计算方式(相对于当日0点0分0秒的时间长度),一般情况下,若通话的开始时间和结束时间在同一天内,则结束时间应大于开始时间。但是若通话从0点前卉始而结束于0点之后,则会出现开始通话时间大于结束通话时间的情况,因此0点之前到0点整的通话长度就是全天的秒数减去以秒为单位的开始时间,即24*60*60-t start。因此空,(2)处填入t end<t start,而空(3)处填入24*60*60或86400。
从程序中可知,interval是以秒为单位的通话长度,而话费是以分钟为单位计算的,所以空(4)处填入interval/60,剩余时间则按一分钟计费,因此空(5)处填入c++。
试题四
阅读以下说明和C语言函数,将应填入  (n)  。
【说明】
已知包含头结点(不存储元素)的单链表的元素已经按照非递减方式排序,函数 compress(NODE*head)的功能是去掉其中重复的元素,使得链表中的元素互不相同。
处理过程中,当元素重复出现时,保留元素第一次出现所在的结点。
图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)  )  {  /*处理重复元素*/
(4)  q->next;
free(q);
q=ptr->next;
}
(5)  ptr->next;
}/*end of while */
}/*end of compress*/
答案
(1)head->next
(2)ptr
(3)q->data == ptr->data
或ptr->next->data==ptr->data,或其等价表示
(4)ptr->next
(5)ptr
试题四[分析]
本题考查基本程序设计能力。
链表上的查找、插入和删除运算是常见的考点。本题要求去掉链表中的重复元素,使得链表中的元素互不相同,显然是对链表进行查找和删除操作。
对于元素已经按照非递减方式排序的单链表,删除其中重复的元素,可以采用两种思路。
1.顺序地遍历链表,对于逻辑上相邻的两个元素,比较它们是否相同,若相同,则删除后一个元素的结点,直到表尾。代码如下:
ptr=head->next;                            /*取得第一个元素结点的指针*/
while  (ptr && ptr->next){               /*指针ptr指示出重复序列的第一个元素结点*/
q=ptr->next;
while(q && ptr->data==q->data)  {    /*处理重复元素*/
ptr->next=q->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->next;                                       /*需要删除的第一个结点*/
ptr->next=q;                                       /*保留重复序列的第一个结点,将其余结点从链表中删除*/
while  (s && s!=q}  {                                /*逐个释放被删除结点的空间*/
t = s->next;    free(s);    s = t;
}
ptr=ptr->next;
}
题目中采用的是第一种思路。
试题五
阅读下列说明、图和C++代码,回答问题1至问题3。
【说明】
已知四个类之间的关系如图2-2所示,分别对每个类的方法进行编号,例如Shape的perimeter()方法为1号,表示为1:perimeter(),Rectangle类的perimeter()为2号,表示为2:perimeter(),依此类推,其中,每个类的perimeter方法都为虚函数且方法签名相同。
【C++代码】
Triangle *tr=new Triangle();
Square *sq=new Square();
Shape *sh =tr;
【问题1】  关于上述C++代码中sh和tr的以下叙述中,哪两个是正确的(写出编号)。
①sh和tr分别引用同一个对象;
②sh和tr分别引用同一类型的不同的对象:
③sh和tr分别引用不同类型的不同对象;
④sh和tr分别引用同一个对象的不同备份:
⑤sh和tr所引用的内存空间是相同的。
【问题2】  写出下面消息对应的方法编号(如果该消息错误或者没有对应的方法调用,请填写“无”)。
tr->height()       (1)
sh->perimeter()    (2)
sq->height()       (3)
sq->perimeter()    (4)
sh->height()       (5)
tr->perimeter()    (6)
【问题3】  不考虑内存释放问题,下列赋值语句中哪两个是合法的(写出合法赋值语句的编号)。
①sq=sh;  ②sh=tr;  ③tr=sq;  ④sq=tr;  ⑤sh=sq;
答案
[问题1]
①  ⑤
[问题2]
(1)3  (2)5  (3)无  (4)4  (5)无  (6)5
[问题3]
②  ⑤
试题五[分析]
根据C++代码:
Triangle *tr=new Triangle();
Square *sq=new Square();
Shape *sh=tr;
可以得出下面的结论:tr指向一个Triangle对象,sq指向一个Square对象,sh和tr指向同一个Triangle对象。下面对问题1给出的论断进行判断,①、⑤正确,由于sh和 tr指向同一个对象,因此其引用的内存空间也是相同的,不存在不同的备份。②、③和④错误。
根据题目的描述,我们知道perimeter是虚拟函数,所以所有通过sh调用的perimeter都将实际调用Triangle类的perimeter方法。
·tr->height():因为tr指向一个Triangle对象,所以调用Triangle类的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():因为tr指向一个Triangle对象,所以调用Triangle类的perimeter方法。
问题3主要考虑类型问题,我们只能够将子类类型的实例或引用赋值给父类类型的变量或引用。因此,赋值运算的左边一定是右边的父类或同一类型。正确的只有②和⑤。
试题六
阅读以下应用说明以及Visual Basic程序代码,将应填入  (n)  。
【应用说明】
某电视台拟开发应用程序来显示戏曲大赛中1~4号四位选手决赛的现场投票情况。该程序从现场观众中(不超过2000人)每0.5秒收集一次对这四位选手的支持票数,并在屏幕上动态显示这四位选手的票柱(以高度反映票数)与累计得票数,如图2-3所示。投票过程限时30秒,每名观众最多为1名选手投票。投票结束后系统通过比较各位选手的累计得票数,显示决赛结果:“*号胜出”(如有单个冠军)或“继续进行PK”(如有多人获得相同的最高票数)。
在开发该程序的过程中创建的主要控件及其初始属性值说明如下:
控件名
类型
用途
初始属性设置
ShpM(1to4)
形状数组
显示各选手得票情况
矩形,实心,高度0
txtM(1to4)
文本框数组
显示各选手得票数
0
cmdStatr
命令按钮
启动计票
标题:开始投票
txtResult
文本框
显示决赛结果
Timl
计时器
每半秒收集处理一次
间隔时间0.5秒,关闭状态
该程序中设置公共变量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.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(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  Then  ng=  (4)             '计算冠军个数
End  If
Next  i
If ng=1 Then
txtResult. Text=  (5)                           '单个冠军结果
Else
txtResult. Text="继续进行PK"
End If
End If
End Sub
答案
(1)n(i)  (2)Timl.Enabled=False  (3)1
(4)ng+1  (5)Str$(j)+“号胜出”,或Str(j)+“号胜出”
试题六[分析]
本题是VB应用程序设计题,涉及到文本框、命令按钮、定时器、形状和控件数组的设计方法。
同一控件数组中的各个控件,具有相同的名、不同的下标。采用控件数组有利于在程序中进行循环处理。在开发时,只要设计了一个控件,再用复制的方法就能形成控件数组。
在本题的程序代码中,一开始就设置T为整数类型的全局变量,用于定时计数(以半秒为单位)。因为初始加载主窗口的过程Form Load时需要为它赋初始值0,而每次进入定时过程Timl Timer时需要增1,退出该过程后需要保留其值。
主窗口的过程Form Load在每次启动应用程序时都会自动加载并执行,因此在该过程中需要设置4个票柱形状的初始位置,还需要设置4个得票数文本框的初始内容及定时器的初始参数。
4个票柱形状ShpM(1)~ShpM(4)在开发时就已设置成矩形(属性Shape=0)、实心(属性Fillstyle=0)、高度为0(属性Height=0)。而在每次程序运行时,这几个形状的顶部位置(属性Top值)及高度(属性Height值)都会有变化,所以在过程Form_Load中,应该设置初始值,起到恢复作用。这是编程时应该养成的良好习惯。
该过程中,4个票柱形状的顶部位置都设置成像素2000,而且高度为0,所以,初始时4个票柱都呈现在同一水平线上。
该过程中,各个得票数文本框TxtM(i)内容均设置为0(系统会自动进行数值与字符的转换)。定时器的初始参数设置包括属性Enable=False(关闭)、属性Interval=5000(时间间隔设置为500ms,即半秒)。
在命令按钮“开始投票”(CmdStart)的单击过程(CmdStart Click)中,需要将定时器设置成打开可用状态(Timl.Enable=Tree)。这时,定时器将按时间间隔属性所确定的时间发出中断,触发Timl Timer过程。在该过程中,还需要将“开始投票”命令按钮颜色变灰(CmdStart.Enable=False),使其暂时不允许用户使用。这也是程序员应养成的良好习惯。
本题的重点是定时器的触发过程Timl Timer。
在该过程中,首先需要定义本过程内部使用的整数类型的局部变量,包括动态收集的4个选手的票数n(1)~n(4),这几个数中的最大值G,票数等于G的人数ng,以及过程内部临时用的变量i与j。
接着,对4位选手进行循环计票处理:先收集在此时间间隔内第i位选手得到的票数n(i),再在得票数文本框中进行累计(注意,VB能自动将数值类型转换成字符串类型),并动态显示出来,同时需要调整该选手的票柱形状。
形状ShpM(i)的顶部位置在屏幕上应往上升,而top属性值则应减少(因为属性Top值是与屏幕顶部的距离,以像素为单位)。本应用设计时考虑到现场最多2000人,票数还会分散给4人。程序中Top的初始值设置为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,关闭定时器。
随后,还需要比较谁是冠军。如有多个并列冠军,则还需要继续进行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。当出现新的冠军时,ng必须调整为1,因此(3)处应填写1。这是程序员最容易犯错误的地方,也是本题最难之处。
最后,如果比赛的结果只有1个冠军,则显示决赛结果“j号胜出”。其中的j应显示其具体的值。在程序中应该用str(j)或str$(j)表示。所以(5)处应填str(j)+“号胜出”,或str$(j)+“号胜出”。
当出现多个冠军时,屏幕显示“继续进行PK”。
试题七
阅读下列说明、图和Java代码,回答问题1至问题3。
【说明】
已知四个类之间的关系如图2-4所示,分别对每个类的方法进行编号,例如Shape的perimeter()为1号,表示为1:perimeter(),Rectangle类的perimeter()为2号,表示为 2:perimeter(),依此类推,其中,每个类的perimeter方法签名相同。
【Java代码】
Triangle tr=new Triangle();
Square sq=new Square();
Shape  sh=tr;
【问题1】 关于上述Java代码中sh和tr的以下叙述中,哪两个是正确的(写出编号)。
①sh和tr分别引用同一个对象;
②sh和tr分别引用同一类型的不同的对象:
③sh和tr分别引用不同类型的不同对象:
④sh和tr分别引用同一个对象的不同拷贝;
⑤sh和tr所引用的内存空间是相同的。
【问题2】 写出下面消息对应的方法编号(如果该消息错误或者没有对应的方法调用,请填写“无”)。
tr.height()     (1)
sh.perimeter()  (2)
sq.height()     (3)
sq.perimeter()  (4)
sh.height()     (5)
tr.perimeter()  (6)
【问题3】 下列赋值语句中哪两个是合法的(写出合法赋值语句的编号)。
①sq=sh;  ②sh=tr;  ③tr=sq;  ④sq=tr;  ⑤sh=sq;
答案
[问题1]
①  ⑤
[问题2]
(1)3  (2)5  (3)无  (4)4  (5)无  (6)5
[问题3]
②  ⑤
试题七[分析]
根据Java代码:
Triangle tr=new Triangle();
Square sq=new Square();
Shape  sh=tr;
可以得出下面的结论:tr引用一个Triangle对象,sq引用一个Square对象,sh和tr引用同一个Triangle对象。因此,对问题1给出的论断,sh和tr引用同一个对象,其引用的内存空间也是相同的,①和⑤正确。对于论断④,由于sh和tr引用同一类型的同一个对象,因此不存在不同的备份。
根据题目的描述,我们知道perimeter是虚拟函数,所以所有通过sh调用的perimeter都将实际调用Triangle类的perimeter方法。
·tr->height():因为订引用一个Triangle对象,所以调用Triangle类的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():因为tr引用一个Triangle对象,所以调用Triangle类的perimeter方法。
问题3主要考虑类型的问题,我们只能够将子类类型的实例或引用赋值给父类类型的变量或引用。因此,赋值运算的左边一定是右边的父类或同一类型。正确的只有②和⑤。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Redis源码学习:字符串
C语言字符串函数大全
C语言难点分析整理
月历
Ultimate Difference
[2016-12-07]第8橙,SQ的
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服