2007年下半年《程序员》下午试题(标准答案+解析版)

0
收藏   分享
  • 卷面总分:75分
  • 试卷类型:真题考试
  • 测试费用:免费
  • 答案解析:是
  • 练习次数:18次
  • 作答时间:150分钟
试卷简介
2007年下半年《程序员》下午试题(标准答案+解析版):2007年下半年《程序员》下午试题(标准答案+解析版):本试卷总分75分;共有1类型题目,此试卷有详细解析。
试卷预览
1

试题七(共 15 分)

阅读下列说明、图和Java 代码,回答问题1 至问题3,将解答写在答题纸的对应栏内。 

[说明]

 已知四个类之间的关系如图 7-1 所示,分别对每个类的方法进行编号,例如 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

试题六(共 15 分)

    阅读以下应用说明以及 Visual Basic 程序代码,将应填入 (n) 处的字句写在答题纸的对应栏内。

[应用说明]

某电视台拟开发应用程序来显示戏曲大赛中1~4号四位选手决赛的现场投票情况。该程序从现场观众中(不超过 2000 人)每 0.5 秒收集一次对这四位选手的支持票数,并在屏幕上动态显示这四位选手的票柱(以高度反映票数)与累计得票数,如图 6-1 所示。投票过程限时 30 秒,每名观众最多为 1 名选手投票。投票结束后系统通过比较各位选手的累计得票数,显示决赛结果: “*号胜出” (如有单个冠军)或“继续进行 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

 Tim1.Enabled = False : Tim1.Interval = 500 : T = 0

End Sub

Private Sub CmdStart_Click()

  Tim1.Enabled = True                  '开始投票

  CmdStart.Enabled = False

End Sub

Private Sub Tim1_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

试题五(共 15 分)

阅读下列说明、图和C++代码,回答问题1 至问题3,将解答写在答题纸的对应栏内。

[说明]

 已知四个类之间的关系如图 5-1 所示,分别对每个类的方法进行编号,例如 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

试题三(共 15 分)

阅读以下说明和 C 语言程序,将应填入 (n) 处的字句写在答题纸的对应栏内。

[说明]

某电信公司记录了每个用户的详细通话情况(每次通话数据记录在一行) ,现将某用户某月的通话数据存入一个文本文件“dial.txt” ,其数据格式如下:

       拨入或拨出标记 通话开始时间 通话结束时间 对方号码

   注 1:数据字段以一个空格作为分隔符。

注 2:拨入和拨出标记均为小写字母。拨入标记为“i”,表示其他用户呼叫本机,本机用户不需付费;拨出标记为“o” ,表示本机呼叫其他用户,此时本机用户需要付费。 

注 3:通话开始和结束时间的格式均为:HH:MM:SS。其中 HH 表示小时,取值 00~23;MM 表示分钟,取值 00~59;SS 表示秒,取值 00~59。从通话开始到结束这段时间称为通话时间,假定每次通话时间以秒为单位,最短为 1 秒,最长不超过 24 小时。

注 4:跨月的通话记录计入下个月的通话数据文件。

   例如“o 23:01:12 00: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

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

试题二(共 15 分)

阅读以下说明和 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;  

}