全国计算机技术与软件专业技术资格(水平)考试
2004 年上半年程序员级下午试卷
(考试时间 14:00~16:30 共 150 分钟)
请按下述要求正确填写答题纸
1. 在答题纸的指定位置填写你所在的省、自治区、直辖市、计划单列市的名称。
2. 在答题纸的指定位置填写准考证号、出生年月日和姓名。
3. 答题纸上除填写上述内容外只能写解答。
4. 本试卷共 9 道题,试题一是必答题,试题二至试题九选答 4
题。每题15 分,满分 75 分。请按下表选答试题。
试题号一二~三四~五六~七八~九
选择方法必答题选答 1 题选答 1 题选答 1 题选答 1 题
5. 解答时字迹务必清楚,字迹不清时,将不评分。
6. 仿照下面例题,将解答写在答题纸的对应栏内。
例题
2004 年上半年全国计算机技术与软件专业技术资格(水平)考
试日期是(1)月(2)日。
因为正确的解答是“5 月 23 日”,故在答题纸的对应栏
内写上…5?和…23?(参看下表)。
例题解答栏
(1) 5
(2)23
2004 年上半年程序员级下午试卷第 1 页(共 13 页)
试题一是必答题
试题一
阅读下列说明、流程图和算法,将应填入 (n) 处的字句写在答题纸的对应栏内。 [流程图说明]
下面的流程图用 N-S 盒图形式描述了数组 A 中的元素被划分的过程。其划分方法是:以数组中的第一个元素作为基准数,将小于基准数的元素向低下标端移动,而大于基准数的元素向高下标端移动。当划分结束时,基准数定位于A[i],并且数组中下标小于i 的元素的值均小于基准数,下标大于 i 的元素的值均大于基准数。设数组 A 的下界为low,上界为 high,数组中的元素互不相同。例如,对数组(4,2,8,3,6),以 4 为基准数的划分过程如下:
[流程图]
pivot ← A[low]
i ← low; j← high
i < j
i<j && A[j]>pivot
(1)
A[i] ← A[j]
i<j && A[i]<pivot
(2)
A[j] ← A[i]
(3)pivot
①
4
4
3
4
3
2 8
3 6
②
③
2 8 6
④
⑤
⑥
2 8 6
2004 年上半年程序员级下午试卷第 2 页(共 13 页)
[算法说明]
将上述划分的思想进一步用于被划分出的数组的两部分,就可以对整个数组实现递增排序。设函数 int p(int A[],int low,int high)实现了上述流程图的划分过程并返回基准数在数组 A 中的下标。递归函数void sort(int A[],int L,int H )的功能是实现数组 A 中元素的递增排序。[算法]
void sort(int A[], int L, int H) {
if ( L < H ) {
k = p(A, L, H); //p()返回基准数在数组 A 中的下标
sort( (4)); //小于基准数的元素排序
sort( (5)); //大于基准数的元素排序
}
}
2004 年上半年程序员级下午试卷第 3 页(共 13 页)
有效。
试题二
阅读下列函数说明和C函数,将应填入(n)处的字句写在答题纸的对应栏内。 [函数 2.1 说明]
函数 palindrome(char s[])的功能是:判断字符串 s 是否为回文字符串,若是,则返回0,否则返回-1。若一个字符串顺读和倒读都一样时,称该字符串是回文字符串,例如:“LEVEL”是回文字符串,而“LEVAL”不是。
[函数 2.1]
int palindrome(char s[])
{ char *pi, *pj;
pi = s; pj = s+strlen(s)-1;
while ( pi < pj && (1)) {
pi++; pj--;
}
if ( (2)) return -1;
else return 0;
}
[函数 2.2 说明]
函数 f(char *str,char del)的功能是:将非空字符串 str 分割成若干个子字符串并输出,del 表示分割时的标志字符。
例如若 str 的值为“33123333435”,del 的值为…3?,调用此函数后,将输出三个子字符串,分别为“12”、“4”和“5”。
[函数 2.2]
void f(char *str,char del)
{ int i, j, len;
len = strlen(str);
i = 0;
while( i < len ){
while( (3)) i++; /*忽略连续的标志字符*/
/*寻找从str[i]开始直到标志字符出现的一个
子字符串*/ j = i + 1;
while(str[j] != del && str[j] != ′\0′) j++;
(4)= ′\0′; /*给找到的字符序列置字符串结束标志*/ printf("%s\t", &str[i]);
(5);
}
}
2004 年上半年程序员级下午试卷第 4 页(共 13 页)
试题三
以下是与 Visual Basic 开发应用有关的 5 个问题。对每一个问题,请将解答填入答题纸的对应栏内。
(1) 在 Visual Basic 中,工程文件、窗体文件和标准模块文件的扩展名是什么?请从下列选项中选择:
prg、prj、exe、vbp、form、frm、win、fra、std、bas、vbs、vbm
(2) 设某窗体上有一个命令按钮,其名称为CmdSave,运行时该按钮上显示有“保存(S)”字样的信息。为使热键ALT+S与该命令按钮相关联,应该对按钮CmdSave的Caption 属性设置什么样的属性值?
(3) 设某窗口内有一个图像框 Image1,以及两个命令按钮“放大”和“缩小”。单击“放大”按钮就会使该图像框的长和宽都放大 10%;单击“缩小”按钮就会使该图像框的长和宽都缩小 10%(该图像框的左上角不动)。请分别写出这两个命令按钮的单击事件过程中的程序代码。
(4) 为使某个单选按钮初始时默认被选中,在开发时应怎样做?
(5) 若有语句 Tmpval=MsgBox("非法操作!", vbOKCancel + vbCritical, "提示"),请简要描述程序运行时弹出的消息框的主要特征。
2004 年上半年程序员级下午试卷第 5 页(共 13 页)
有效。
试题四
阅读以下说明和C代码,将应填入(n)处的字句写在答题纸
的对应栏内。 [说明]
函数 MultibaseOutput(long n, int B)的功能是:将一个无符号十进制整数n 转换成 B(2≤B≤16)进制数并输出。该函数先将转换过程中得到的各位数字入栈,转换结束后再把 B 进制数从栈中输出。有关栈操作的诸函数功能见相应函数中的注释。C 代码中的符号常量及栈的类型定义如下:
#define MAXSIZE 32
typedef struct {
int *elem; /* 栈的存储区 */
int max; /* 栈的容量,即栈中最多能存放的元素个数 */
int top; /* 栈顶指针 */
}Stack;
[C 代码]
int InitStack(Stack *S, int n) /* 创建容量为 n 的空栈 */
{ S->elem = (int *)malloc(n * sizeof(int));
if(S->elem == NULL) return -1;
S->max = n; (1)= 0 ; return 0;
}
int Push(Stack *S, int item) /* 将整数 item 压入栈顶 */
{ if(S->top == S->max){ printf("Stack is full!\n"); return -1;}
(2)= item ; return 0;
}
int StackEmpty(Stack S) { return (!S.top) ? 1 : 0; } /* 判断栈是否为空 */ int Pop(Stack *S) /* 栈顶元素出栈 */
{ if(!S->top) { printf("Pop an empty stack!\n"); return -1;} return (3);
}
void MultibaseOutput(long n, int B)
{ int m; Stack S;
if (InitStack(&S, MAXSIZE)) do {
if (Push(&S, (4)
n = (5);
}while(n != 0);
while(!StackEmpty(S)) { m = Pop(&S); {printf("Failure!\n"); return;}
)) {printf("Failure!\n"); return;} /* 输出 B 进制的数 */
if(m < 10) printf("%d", m);
else printf("%c", m + 55);
}
printf("\n");
} /* 小于 10,输出数字 */
/* 大于或等于 10,输出相应的字符 */
2004 年上半年程序员级下午试卷第 6 页(共 13 页)
试题五
阅读以下应用说明及Visual Basic程序代码,将应填入_ (n)处的字句写在答题纸的对应栏内。
[应用说明 5.1]
本应用程序的窗体中有一个下拉式列表框(名称为Combo1)和两个文本框(名称分别为 Txt1 和 Txt2)。运行时,用户从 Combo1 的列表中进行选择,程序就会将选中条目的内容以及编号(从0 开始)分别在文本框Txt1 和 Txt2 中显示出来。
[程序代码 5.1]
Private Sub Combo1_Click()
Txt1.Text = Combol. (1)
Txt2.Text = Combol. (2)
End Sub
(注:可供(2)处选择的选项:List, Index, ListIndex, ListCount, Number)
[应用说明 5.2]
本应用程序的运行窗口如下图所示:
当用户在输入框(名为 TxtIn)中输入数值数据,并从下拉式列表框(名为 CmbOp)中选择所需的运算后,输出框(名为 TxtOut)中就会显示运算的结果。用户单击“清除”按钮(名为CmdClear)后,输入框和输出框都清空。
开发该应用的部分程序代码如下:
[程序代码 5.2]
Private Sub CmbOp_Click( )
Dim DataIn As Double, DataOut as Double
DataIn = (3)
Select Case (4)
Case "取整数部分"
DataOut = Int(DataIn)
Case "求平方根"
If DataIn<0 Then
MsgBox$ ("负数不能开平方!
")
Else
DataOut = Sqr(DataIn)
End If
Case "取绝对值"
DataOut = Abs(DataIn)
(5)
TxtOut.Text = str$(DataOut)
End Sub
2004 年上半年程序员级下午试卷第 7 页(共 13 页)
从下列的 2道试题(试题六至试题七)中任选 1
道解答。
如果解答的试题数超过 1道,则题号小的 1道解答
有效。
试题六
阅读下列函数说明和C函数,将应填入(n)处的字句写在答题纸的对应栏内。 [函数 6 说明]
函数DelA_InsB(LinkedList La,LinkedList Lb,int key1,int key2,int len)的功能是:将线性表 A 中关键码为 key1 的结点开始的 len 个结点,按原顺序移至线性表 B 中关键码为 key2 的结点之前,若移动成功,则返回 0;否则返回-1。线性表的存储结构为带头结点的单链表,La 为表 A 的头指针,Lb 为表 B 的头指针。单链表结点的类型定义为:
typedef struct node {
int key;
struct node *next;
}*LinkedList;
[函数 6]
int DelA_InsB(LinkedList La,LinkedList Lb,int key1,int key2,int len)
{ LinkedList p,q,s,prep,pres;
int k;
if (!La->next||!Lb->next||len <= 0 ) return -1; p =
La->next; prep = La;
while ( p && p->key != key1 ) { prep = p; p = p->next;
}
if (!p) return -1;
q = p; k = 1;
while (q && (1)) { (2); k++;
}
if (!q) return -1;
s = Lb->next; (3); while (s && s->key != key2) {
pres = s; s = s->next; }
if (!s) return -1; /*查找表 A 中键值为 key1 的结点*/
/*表 A 中不存在键值为 key1 的结点*/
/*在表A中找出待删除的len个结点*/
/*表 A 中不存在要被删除的 len 个结点*/ /*查找表 B 中键值为 key2 的结点*/
/*表 B 中不存在键值为 key2 的结点*/
(4)= q->next;
q->next = (5);
pres->next = p;
return 0;
} /*将表A中的len个结点删除*/ /*将 len 个结点移至表 B*/
2004 年上半年程序员级下午试卷第 8 页(共 13 页)
试题七
阅读以下应用说明、属性设置及Visual Basic程序代码,将应填入(n) 处
的字句写在答题纸的对应栏内。
[应用说明 7]
本应用程序的运行窗口如下图所示:
只要用户单击“闪烁”按钮,文字“欢迎光临”就会以 0.3 秒消失、0.3 秒显示反
复进行闪烁;单击“停止”按钮时,闪烁停止,恢复
图示的初态。
在开发过程中,需要设置的属性如下:
[属性设置 7]
对象对象名属性名属性值
窗体Frm1 Caption 闪烁显示演示
标签Labe1 Caption 欢迎光临
命令按钮CmdF Caption 闪烁
命令按钮CmdT Caption 停止
定时器Timer1 Enabled (1)
Interval (2)
在开发过程中,需要编写的程序代
码如下: [程序代码 7]
Private Sub CmdF_Click()
Timer1. (3)= True
Labe1.Visible = False
End Sub
Private Sub Timer1_Timer( )
(4)= not Labe1.Visible
End Sub
Private Sub CmdT_Click()
Timer1.Enabled = (5)
Labe1.Visible = true
End Sub
2004 年上半年程序员级下午试卷第 9 页(共 13 页)
从下列的 2道试题(试题八至试题九)中任选 1
道解答。
如果解答的试题数超过 1道,则题号小的 1道解答
有效。
试题八
阅读下列程序说明和C程序,将应填入(n)处的字句写在答题
纸的对应栏内。 [程序 8 说明]
程序8 用于计算某公司每个职工应缴纳的个人所得税额和全体职工缴纳的个人所得税总额。职工的当月收入(工资或薪金)通过键盘输入,每次输入一个职工的工号和工资(或薪金)。由于该公司的工资或薪金是不定时发放的,所以输入过程中每个职工的收入会出现多次输入,整个输入以工号小于等于 0 结束。
假设个人所得税法规定:个人收入所得,按月计税,以每月收入总额减除免税金额800 元后的余额作为该月的月应纳税所得额。适用税率如下表所示。
级数月应纳税所得额适用税率(%)
1 不超过 500 元的部分 5
2 501 元~2000 元的部分10
3 2001 元~5000 元的部分15
4 5001 元~20000 元的部分20
5 20001 元~40000 元的部分25
6 40001 元~60000 元的部分30
7 60001 元~80000 元的部分35
8 80001 元~100000 元的部分40
9 超过 100000 元的部分45
上表表明,个人收入所得税是按照超额累进的税率来征收的。
设一个人的月应纳税所得额为K(元),用下面的公式计算其应缴纳的个人所得税额S(元):
若 0<K≤500,则 S = K?%;
若 500<K≤2000,则 S = 500?%+(K-500)?0%;
若 2000<K≤5000,则 S = 500?%+1500?0%+(K-2000)?5%;
若 5000<K≤20000,则 S = 500?%+1500?0%+3000?5%+(K-5000)?0%;
例如,某人某月收入总额为 4100 元,减去 800 元后,应纳税所得额为3300 元,其应缴纳的个人所得税额为 500*5%+1500*10%+1300*15%=370 元。
2004 年上半年程序员级下午试卷第 10 页(共 13 页)
[程序 8]
#include
int paylevel[]={0,500,2000,5000,20000,40000,60000,80000,100000,1000001}; int taxPrate[]={5,10,15,20,25,30,35,40,45}; /*税率表*/ typedef struct {
int Id; /*职工的工号*/ long Salary; /*职工的工资*/ }Info;
/*查找工号为 Id 的职工在数组 employee 中的下标,返回值为 0 表示没有*/ int find(int Id, Info employee[], int m) {
int j;
employee[0].Id = Id; for(j = m; (1) ; j--); return j; }
void main(void)
{ Info employee[MaxNum+1]; long Wage;
double sum = 0, K, S; int i, j, N = 0, Code;
scanf("%d %ld", &Code, &Wage); /*读入职工号、工资或薪金*/ while (Code > 0) {
i = find(Code, employee, N);
if (i > 0) employee[i].Salary += Wage; else { (2) ;
employee[N].Id = Code; employee[N].Salary = Wage;
}
scanf("%d %ld", &Code, &Wage); }
for(i = 1; i <= N; i++) { K = (3) ; /*计算月应纳税所得额*/ S = 0; /*月应纳税额赋初值*/ if (K > 0) {
for(j = 1; j <= 9; j++) if ( (4) ) /*月应纳税所得额超过第j 级*/
S = S + (paylevel[j]- paylevel[j-1])*taxPrate[j-1]/100; else { S = S + ( (5)
}
printf("职工%d 应缴纳的个人所得
税额:
sum += S; }
)*taxPrate[j-1]/100; break;} %10.2lf\n", employee[i].Id, S); printf("全体职工个人所得税总额: %10.2lf\n", sum); }
2004 年上半年 程序员级下午试卷 第 11 页(共 13 页)
试题九
阅读以下应用说明及Visual Basic程序代码,将应填入(n) 处的字句写在答题
纸的对应栏内。
[应用说明 9]
本应用程序的运行窗口如下图所示:
窗口中的三个文本框和两个按钮名称分别为Txt_salary、Txt_base、
Txt_tax、Cmd_compute 和 Cmd_quit。运行时,文本框 Txt_base 中存放的是
免税金额基数(应扣除的基本费用)。当用户在文本框Txt_salary 中输
入月收入(工资或薪金)并单击“计算”按钮 Cmd_compute 后,Txt_tax 框
中就显示计算所得的应纳税额。文本框 Txt_base 和 Txt_tax 在运行时不接受用
户输入,Txt_base 的内容以灰色显示。
个人工资(或薪金)所得税是按照超额累进的税率来征收的,方法
是:以每月收入总
额减去免税金额基数后的余额作为该月的月应纳税所得额,再将应纳
税所得额按相应级
数采用相应的税率进行累进计算。目前的免税金额基数为 800 元,税
率如下表所示:
级数月应纳税所得额税率(%)
1 不超过 500 元的部分 5
2 501 元~2000 元的部分10
3 2001 元~5000 元的部分15
4 5001 元~20000 元的部分20
5 20001 元~40000 元的部分25
6 40001 元~60000 元的部分30
7 60001 元~80000 元的部分35
8 80001 元~100000 元的部分40
9 超过 100000 元的部分45
设一个人的月应纳税所得额为 K(元),用下面的公式计算其应缴纳
的个人所得税额S(元):
若 0<K≤500,则 S = K?%;
若 500<K≤2000,则 S = 500?%+(K-500)?0%;
若 2000<K≤5000,则 S = 500?%+1500?0%+(K-2000)?5%;
若 5000<K≤20000,则 S = 500?%+1500?0%+3000?5%+(K-5000)?0%;
例如,某人某月工资总额为 4100 元,减去 800 元后,应纳税所得额为
3300 元,其应缴纳的个人所得税额为 500*5%+1500*10%+1300*15%=370 元。
2004 年上半年程序员级下午试卷第 12 页(共 13 页)
在开发过程中,需要编写的程序代
码如下: [程序代码 9]
Option Base 0
Private Sub Cmd_compute_Click()
Dim paylevel, taxPrate
paylevel = Array(0,500,2000,5000,20000,40000, 60000, 80000, 100000, 1000001) taxPrate = Array(5, 10, 15, 20, 25, 30, 35, 40, 45)
K = (1)
S = 0
If (K > 0) Then
For j = 1 To 9
If (2) Then
S = S + (paylevel(j) - paylevel(j - 1)) * taxPrate(j - 1) / 100 Else
) * taxPrate(j - 1) / 100
S = S + ( (3)
Exit For
End If
Next j
End If
(4)= Str$(S)
End Sub
Private Sub Cmd_quit_Click()
End
End Sub
Private Sub Form_Load()
Txt_tax.Text = ""
Txt_salary.Text = ""
Txt_base.Text = 800
Txt_tax.Locked = True
Txt_base.Enabled = (5)
End Sub
2004 年上半年程序员级下午试卷第 13 页(共 13 页)