1991年度程序员级下午试卷
试题 2
在
COMET 型计算机上可以使用试卷上所附的 CASL 汇编语言。阅读下列程序说明和
CASL 程序,把应填入程序中__(n)__ 处的字句,写在答卷的对应栏内。
[程序说明]
本程序是一个除法程序。
(1)被除数、除数均是正整数,分别存放在标号为A,B的存贮字内。
(2)商存贮在标号为ANS的存贮字内,对商的小数点后第一位进行舍入,结果为整数。
(3)假定除法过程不会产生溢出。
本程序在除法中实现四舍五入的方法是:将被除数乘以 10,除以除数,对商作适当处理,再将处理后的结果除以
10。
[问题]
在程序中的①~⑧处各填入一条正确的指令,以完成此程序。除非必要,标号栏不要填写。
[程序]
| 标号 | 操作码 | 操作数 | |
| START | DGN | ||
| DGN | LD | GR0,A | |
| __①__ | |||
| __②__ | |||
| ADD | GR0,A | ||
| LD | GRl,B | ||
| CALL | DIV | ||
| L1 | __③__ | ||
| LEA | GRl,10 | ||
| CALL | DIV | ||
| ST | GR2,ANS | ||
| EXIT | |||
| A | DS | 1 | |
| B | DS | 1 | |
| ANS | DS | 1 | |
| DIV | ST | GRl,WORK | |
| __④__ | |||
| DIV1 | CPA | GR0,WORK | |
| JMI | DIV2 | ||
| __⑤__ | |||
| __⑥__ | |||
| JMP | DIV1 | ||
| DIV2 | RET | ||
| WORK | DS | 1 | |
| END |
试题 3
阅读下列程序说明和
C 程序,将应填入程序中__(n)__处的字句写在答卷纸的对应栏内。
[程序说明]
已知某数的前二项为2和3,其后继项根据当前最后二项的乘积按下列规则生成
(1)若乘积为一位数,则该乘积即为数列的后继项;
(2)若乘积为二位数,则该乘积的十位数和个位数依次作为数列的两个后继项。
本程序输出该数列的前n项以及它们的和。其中,函数sum(n,pa)返回数列的前n项之和,并将生成的前n项存放于首指针为pa的数组中。程序中规定输入的n值必须大于2并且不超过给定的常数值MAXNUM。
例如:若输入n值为10,则程序输出如下内容:
sum(10)=44
2 3 6 1 8 8 6 4 2 4
[程序]
#include <stdio.h>
#define MAXNUM 100
int sum( n,pa )
int n, *pa;
{ int count,total,temp;
*pa=2;
__(1)__ = 3;
total = 5; count = 2;
while (count++<n)
{ temp=.(pa-1)..pa;
if (temp<10)
{ total+=temp;
*(++pa)=temp;
}
else
{
__(2)__ = temp/10;
total += *pa;
if ( count<n)
{ count++;pa++;
__(3)__ = temp%10;
total += *pa;
}
}
}
__(4)__;
}
main ()
{ int n,.p,.q,num[MAXNUM];
do { printf( "Input N=? (2<N<%d):",MAXNUM+1 );
scanf( "%d",&n );
} while ( __(5)__ );
printf( "\nsum(%d)=%d\n",n,sum(n,num) );
for ( p=num, q = __(6)__ ;p<q;p++) printf("%4d",*p );
printf("\n");
}
试题 7
在
COMET 型计算机上可以使用试卷上所附的 CASL 汇编语言,阅读下列程序说明和
CASL 程序,把应填入程序中__(n)__处的字句,写在答卷的对应栏内。
[程序说明]
本程序用来复原被压缩过的数据。
原始数据的压缩规则如下:
(1)在原始数据中连续出现 N( N≥2 ) 个相同的数 X,则在压缩数据中相继存放 N 和 X 两个数。
(2)在原始数据中,对于不属于上述情况的数据段,即相邻而又不相等的 M 个数据,则在压缩数据中先存放 -M,再存放这 M 个数。
(3)压缩数据中数的存放次序与原始数据中数的出现次序相一致,并在压缩数据的最后加上 0,作为结束标记。
例: 原始数据中有以下数:
-15 11 11 11 11 11 11 11 11 -2 14 9 9 9 9 9
则压缩后的数据为
-1 -15 -8 11 -2 -2 14 5 9 0
程序中标号为PACKED开始的存贮字中存放了上述压缩后的数据;程序执行后,在标号为 UNPACK 开始的 16 个存贮字中生成原始数据。
[问题]
在程序中的①~⑧处各填入一条正确的指令,以完成此程序。除非必要,标号栏不要填写。
[程序]
| 标号 | 指令码 | 操作数 | |
| START | BEGIN | ||
| BEGIN | __(1)__ | ||
| LEA | GR2,0 | ||
| LOOP0 | __(2)__ | ||
| LD | GR3,PACKED,GR1 | ||
| LEA | GR3,0,GR3 | ||
| __(3)__ | |||
| __(4)__ | |||
| LEA | GRl,1,GRl | ||
| LD | GR0,PACKED,GRl | ||
| LOOP1 | __(5)__ | ||
| LEA | GR2,1,GR2 | ||
| LEA | GR3,-1,GR3 | ||
| JNZ | LOOP1 | ||
| JMP | LOOP0 | ||
| ONEONE | __(6)__ | ||
| LOOP2 | LEA | GRl,l,GRl | |
| LD | GR0,PACKED,GRl | ||
| __(7)__ | |||
| LEA | GR2,l,GR2 | ||
| LEA | GR3,-1,GR3 | ||
| __(8)__ | |||
| JMP | LOOP0 | ||
| ENDPGM | EXIT | ||
| UNPACK | DS | 16 | |
| HXFFFF | DC | #FFFF | |
| PACKED | DC | -1 | |
| DC | -15 | ||
| DC | 8 | ||
| DC | 11 | ||
| DC | -2 | ||
| DC | -2 | ||
| DC | 14 | ||
| DC | 5 | ||
| DC | 9 | ||
| DC | 0 | ||
| END |
试题 8
阅读下列程序说明和
C 程序,将应填入程序中__(n)__ 处的字句,写在答卷纸的对应栏内。
[程序说明]
本程序对某电码文(原文)进行加密形成密码文.其加密算法如下:
假定原文为C1C2C3...Cn,加密后形成的密文为S1S2S3...Sn,首先读入正整数Key(Key>1)作为加密钥匙,并将密文字符位置按顺时针方向连成一个环,如下图所示:

加密时从 S1 位置起顺时针计数,当数到第 Key 个字符位置时,将原文中的字符放入该密文字符位置中,同时从环中除去该字符位置;接着从环中下一个字符位置起继续计数,当再次数到第 Key 个字符位置时,将原文中字符 C2 放入其中,并从环中除去该字符位置;依次类推,直至 n 个原文字符全部放入密文环中.由此产生的 S1S2...Sn 即为原文的密文。
例如,当 Key=3 时,原文: THIS IS AN DECODING SYSTEM 的密文为:
AOTGNHEDI YS D IMIETSNC SS
当Key=4时,该原文的密文为:
SSDTYD HTEGIASISCNM E ION
本程序将电码的原文存放在字符数组 old 中,加密钥匙存放在整数 Key 中.函数 decode 用于将原文 old 加密并返回密文字符数组的首指针。其中函数采用一个双向循环链表 CODE 来表示密文环.函数 strlen 用于计算一个字符串中的字符个数( 不包括字符串结尾符 '\0' )。为了简单起见,程序中假设内存容量足以满足动态存贮单元分配的要求。
[程序]
#include <stdio.h>
#include <alloc.h>
#define CR 13
typedef struct node
{ char ch;
struct node *forward; /* Link to next node. */
struct node *backward;/* Link to previous node.*/
} CODE;
main()
{ char __(1)__ ,old[256];
int strlen() , key , num=0;
printf("\nPlease input the telegraph: \n")l
while ( num<255 && ( old[num++] = getch()) != CR );
old [ __(2)__ ] = '\0';
do { printf( "\nPlease input Key=?( Key>1 ):" );
scanf("%d",&key);
} while ( key<=1 );
printf( "\nThe decode of telegraph:'%s' is:\n'%s'\n",old,decode( old,key ) );
}
char *decode(old,key)
char *old; int key;
{ char *new; int length,count,i;
CODE *loop,*p;
length=strlen(old);
loop=( __(3)__ ) malloc( length.sizeof(CODE) );
for ( i = 1;i<length-1;i++ )
{ loop[i].forward = &loop[i+1];
loop[i].backward = &loop[i-1];
}
loop[0].backward = &loop[length-1];
loop[0].forward = &loop[1];
loop[length-1].forward = loop;
loop[length-1].backward = &loop[length-2];
for ( p = loop,i = 0;i<length;i++ )
{ for ( count = 1;count<key;count++ )
p= __(4)__ ;
p->ch=.old++;
p->backward->forward = __(5)__ ;
p->forward->backward = __(6)__ ;
p=p->forward;
}
new = ( char *)malloc( ( length+1 ) *sizeof(char) );
for ( i=0;i<length;i++ ) new[i] =l oop[i] *ch;
new[length]='\0';
return (new);
}
int strlen(s)
char *s;
{ int len = 0;
while ( __(7)__ != '\0' ) len++;
return( len );
}
试题 12
在 COMET 型计算机上可以使用试卷上所附的 CASL 汇编语言。阅读下列程序说明和
CASL 程序,把应填入程序中__(n)__
处的字句,写在答卷的对应栏内。
[程序说明]
本程序将一个汉字的点阵逆时针旋转 90°,并输出旋转后的点阵字形。
图12-1是汉字“转”字的 16×16点阵字形。用“0”表示空白位置,用“1”表示非空白位置,“转”字的第一行即可表示为
0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0
若把它看作一个宇的16个Bit,“转”字的第一行就可以用十六进制的 1040 来表示。同理“转”字的第二行可表示为 1040,第三行可表示为1048,……在 COMET 机中,用 16 个字即可存放一个汉字的点阵字形。“转”字的点阵数据及字形如图 12-1 所示。
将一个汉字点阵逆时针旋转 90°,就是把该汉字点阵的最右列作为旋转后点阵的第一行,次最右列作为第二行,依次类推,形成一个旋转后的点阵字形。图 12-2 是将“转”字逆时针旋转 90° 后的点阵数据和字形。
| 1040 | ...x.....x...... | 0000 | ................. | |
| 1040 | ...x.....x...... | 0200 | ......x......... | |
| 1048 | ...x.....x..X... | 1640 | ...x.xx..x...... | |
| FDFC | xxxxxx.xxxxxxx.. | 32E0 | ..xx..x.xxx..... | |
| 2040 | ..x......x...... | 1259 | ...x..x..x.xx..x | |
| 2844 | ..x.x....x...x.. | 1246 | ....x..x...x..xx. | |
| 4BFE | .x..x.xxxxxxxxx. | FE44 | xxxxxxx..x...x.. | |
| 7C80 | .xxxxx..x....... | 13C8 | ...x..xxxx..x... | |
| 0888 | ....x...x...x... | 1240 | ...x..x..x...... | |
| 09FC | ....x..xxxxxxx.. | 0200 | ......x......... | |
| 0C08 | ...xxx......x... | 1120 | ...x...x..x..... | |
| E810 | xxx.x......x.... | 17FF | ...x.xxxxxxxxxxx | |
| 4890 | .x..x...x..x.... | F120 | xxxx...x..x..... | |
| 0860 | ....x....xx..... | 1D10 | ...xxx.x...x.... | |
| 0820 | ....x.....x..... | 1318 | ...x..xx...xx... | |
| 0810 | ..,,x.,....x..., | 1010 | ...x.,,,...x.... | |
| 图 12-1 | 图 12-2 |
程序中,标号为 OLDPN 起的 16 个字中存放着“转”字的点阵数据,旋转后的点阵数据存放在标号为
NEWPN 起的 16 个字中。程序的前半部分,将该点阵数据逆时针旋转90°;程序的后半部分,将旋转后的点阵数据加以编辑。用字符“.”表示值为
0 的位,用字符“*”表示值为 1 的位。从而将新的点阵字形按行输出。
[问题]
在程序中的①~⑧处各填入一条正确的指令,以完成此程序。除非必要,标号栏不要填写。
[程序]
| 标号 | 操作码 | 操作数 | |
| START | BEGIN | ||
| BEGIN | ST | GR4,SPSAVE | |
| LEA | GR2,0 | ||
| NEWLN | LEA | GR3,0 | |
| ST | GR3,NEWPN,GR2 | ||
| NEWCL | ST | GR3,WORK | |
| LD | GR0,OLDPN,GR3 | ||
| __①__ | |||
| AND | GR0,NUM01 | ||
| LEA | GR1,15 | ||
| SUB | GR1,WORK | ||
| SLL | GR0,0,GR1 | ||
| __②__ | |||
| ST | GR0,NEWPN,GR2 | ||
| __③__ | |||
| LEA | GRl,0,GRl | ||
| JNZ | NEWCL | ||
| __④__ | |||
| CPA | GR2,NUMl6 | ||
| JMI | NEWLN | ||
| GETLN | LD | GR2,NEWPN,GR1 | |
| LEA | GR3,15 | ||
| SETLN | LEA | GR4,0,GR2 | |
| AND | GR4,NUM01 | ||
| __⑤__ | |||
| ST | GR0,OUTLN,GR3 | ||
| SRT * | GR2,1 | ||
| __⑥__ | |||
| JPZ | SETLN | ||
| OUT | OUTLN,NUMl6 | ||
| __ ⑦__ | |||
| LEA | GR0,-16,GR1 | ||
| JNZ | GETLN | ||
| __⑧__ | |||
| EXIT | |||
| OUTLN | DS | 16 | |
| NEWPN | DS | 16 | |
| NUM01 | DC | 1 | |
| WORK | DS | 1 | |
| NUMl6 | DC | 16 | |
| CHRET | DC | '.X’ | |
| OLDPN | DC | #1040 | |
| DC | #1040 | ||
| DC | #1048 | ||
| DC | #FDFC | ||
| DC | #2040 | ||
| DC | #2844 | ||
| DC | #4BFE | ||
| DC | #7C80 | ||
| DC | #0888 | ||
| DC | #09FC | ||
| DC | #1C08 | ||
| DC | #E810 | ||
| DC | #4890 | ||
| DC | #0860 | ||
| DC | #0820 | ||
| DC | #08101 | ||
| SPSAVE | DS | 1 | |
| END |
*老顽童注:此指令有错,疑为 SRL
试题13
阅读下列程序说明和 C 程序,将应填入程序中__(?)__处的字句,写在答卷纸的对应栏内。
[程序说明]
本程序将一个给定汉字的点阵逆时针旋转90度,并输出旋转前后的点阵数据及字形。
附图是汉字"转"字的 16×16 点阵字形,用数字 '0' 表示空白位置,用数字 '1' 表示非空白位置,“转”字的第一行机即可表示成如下的{0,1}序列:
0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0
如果把它看作一个字的 16 个位,“转”字的第一行可以用 16 进制数的 1040 来表示.同理,"转"字的第二行可以表示为1040 ,第三行可以表示为 1048,...等等。依次类推,用16个双字节整型数即可存放一个汉字点阵字形。"转"字的点阵数据及字形如附图的左半部分所示.将一个汉字逆时针旋转90度,就是把该汉字点阵的最右列作为旋转后点阵的第一行,次右列作为旋转后点阵的第二行,...,来形成一个旋转后的点阵字形。
附图的右半部分就是将"转"字旋转 90 度后的点阵数据和字形。
程序中,数组 old 中存放着“转”字的点阵数据.函数 turnleft 将该点阵数据逆时针旋转 90 度,旋转后的点阵数据存放在数组 new 中.函数 display 将旋转前后的点阵数据加以编辑,用字符 '.' 表示值为0的位,用字符 'x' 表示值为 1 的 位,从而将旋转前后的点阵按行输出其 16 进制数据及字形,如同图 13-3 和图 13-2 所表示的那样。
| 1040 | ...x.....x...... | 0000 | ................. | |
| 1040 | ...x.....x...... | 0200 | ......x......... | |
| 1048 | ...x.....x..X... | 1640 | ...x.xx..x...... | |
| FDFC | xxxxxx.xxxxxxx.. | 32E0 | ..xx..x.xxx..... | |
| 2040 | ..x......x...... | 1259 | ...x..x..x.xx..x | |
| 2844 | ..x.x....x...x.. | 1246 | ....x..x...x..xx. | |
| 4BFE | .x..x.xxxxxxxxx. | FE44 | xxxxxxx..x...x.. | |
| 7C80 | .xxxxx..x....... | 13C8 | ...x..xxxx..x... | |
| 0888 | ....x...x...x... | 1240 | ...x..x..x...... | |
| 09FC | ....x..xxxxxxx.. | 0200 | ......x......... | |
| 0C08 | ...xxx......x... | 1120 | ...x...x..x..... | |
| E810 | xxx.x......x.... | 17FF | ...x.xxxxxxxxxxx | |
| 4890 | .x..x...x..x.... | F120 | xxxx...x..x..... | |
| 0860 | ....x....xx..... | 1D10 | ...xxx.x...x.... | |
| 0820 | ....x.....x..... | 1318 | ...x..xx...xx... | |
| 0810 | ..,,x.,....x..., | 1010 | ...x.,,,...x.... | |
| 图 13-1 | 图 13-2 |
[程序]
#include <stdio.h>
#define EMPTY '.'
#define NONEMPTY 'X'
#define LEFT 0
#define RIGHT 1
main ()
{ static unsigned old[16]=
{ 0x1040,0x1040,0x1048,0xFDFC,0x2040,0x2844,
0x4BFE,0x7C80,0x0888,0x09FC,0x1C08,0xE810,
0x4890,0x0860,0x0820,0x0810
};
unsigned new[16];
trunleft( old,new );
display( old,new );
}
turnleft( old,new)
unsigned old[],new[];
{ int row,k;
for ( row=0;row<16;row++ )
for ( k=0, __(1)__ ;k<16;k++ )
new[row]|=(( old[k]>> __(2)__ ) &1) << __(3)__ ;
}
display( old,new )
unsigned *old,*new;
{
char out[2][17],letter[2];
int row,col;
letter[0] = EMPTY;
letter[1] = NONEMPTY;
out[LEFT][16]=out[RIGHT][16]=__(4)__;
for ( row = 0;row<16;row++,old++,new++ )
{ for ( col = 0;col<16;++col )
{ out[LEFT][col] = letter[ ( __(5)__) &1];
out[RIGHT][col] = letter[ (__(6)__) &1];
}
printf("\n %4x %s ",*old,&out[LEFT][0]);
printf(" %4x %s",*new,&out[RIGHT][0]);
}
}