发信人: chaojie (chaojie), 信区: Computer
标 题: Re: 捉虫大赛分数及获奖名单公布
发信站: BBS 哈工大紫丁香站 (Sat Dec 10 16:46:18 2005)
试题及参考答案
第一部分
1. 计算1-1/3+1/5-1/7+...直到最后一项小于10e-4(有1个语法错误)
#include <math.h>
main()
{
float pi, sum = 0, term, sign = 1.0;
int count = 0, n = 1;
term = 1.0;
while (fabs(term)>=1e-4);
{
sum = sum+term;
count++;
sign = -sign;
n = n + 2;
term = sign / n;
}
pi = sum * 4;
printf("pi=%f\ncount=%d\n",pi,count);
}
答案:while语句尾不应该有分号,否则导致死循环
2. 判断m是否为素数(有2个隐蔽错误,3个语法错误)
#include <stdio.h>
#include <math.h>
int isprime(int m)
main()
{
int n, flag;
printf("Input n:");
scanf("%d", n);
flag = isprime(n);
if(flag)
printf(Yes!\n");
else
printf("No!\n");
}
int isprime(int *m)
{
int i;
for (i=2; i<=sqrt(m); i++)
{
if(m%i = 0) return 0;
}
return 1;
}
答案:(1)int isprime(int m)缺分号
(2)scanf("%d", n);缺&
(3)printf(Yes!\n");缺双引号
(4)int isprime(int *m)参数类型声明错误
(5)if(m%i = 0) return 0;缺=
3. 成绩由百分制向5分制转换(有1个隐蔽的语法错误,1个隐蔽的逻辑错误)
#include <stdio.h>
main()
{
int score, mark;
printf("Please enter score:");
scanf("%d", &score);
mark = score / 10;
switch (mark)
{
case10:
case9:
printf("%d--A\n", score);
break;
case8:
printf("%d--B\n", score);
break;
case7:
printf("%d--C\n", score);
break;
case6:
printf("%d--D\n", score);
break;
case5:
case4:
case3:
case2:
case1:
case0:
printf("%d--E\n", score);
break;
default:
printf("Input error!\n");
}
}
答案:(1)case后面缺少空格
(2)输入101~109分数时测试结果不对
4. 判断三角形类型(有3个隐蔽错误,1个语法错误)
#include <stdio.h>
#include <math.h>
main()
{
float a, b, c;
scanf("%f, %f, %f", a, b, c);
if (a+b>c && b+c>a && a+c>b)
{
if (a=b || b=c || c=a)
{
printf("isosceles triangle\n"); /*等腰三角形*/
}
else if (a*a+b*b=c*c || a*a+c*c=b*b || c*c+b*b=a*a)
{
printf("right angled triangle\n");/*直角三角形*/
}
else
{
printf("general triangle\n");/*普通三角形*/
}
}
else
{
printf("not triangle\n"); /*不是三角形*/
}
}
答案:(1)判断相等不用=,而用==,而且实数不能直接判断相等
(2)不用if~else,用三个并列的if
(3)用标志变量来判断是否为一般三角形
(4)scanf("%f, %f, %f", a, b, c);应该改成
scanf("%f, %f, %f", &a, &b, &c);
5. 编程计算1*2*3 + 3*4*5 +……+ 99*100*101的值。(有2个隐蔽错误,2个语法错误
)
#include <stdio.h>
main()
{
int i;
long term, sum;
for (i=1, i<=99, i=i+2)
{
term = i * (i + 1) * (i + 2);
sum = sum + term;
}
printf("sum=%d",sum);
}
答案:(1)int i;改成long i;否则类型溢出
(2)sum未赋初值0
(3)printf("sum=%d",sum);改成printf("sum=%ld",sum);
(4)for (i=1, i<=99, i=i+2)应该为分号
6. 计算自然数的立方和,直到大于1000000为止。(有1个隐蔽错误)
#include<stdio.h>
main()
{
int m,i;
long sum = 0;
for (i=1; ;i++)
{
sum = sum + i*i*i;
if (sum >= 1000000)
break;
}
m = i;
printf("m=%d\n",m);
}
答案:(1)应该定义变量i为长整型,否则类型溢出
7. 猜数游戏(有1个运行错误,1个语法错误)
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
main()
{
int magic;
int guess;
int counter;
srand (time (NULL));
magic = rand() % 100 + 1;
counter = 0;
do{
printf("Please guess a magic number:");
scanf("%d", &guess);
counter ++;
if (guess > magic);
printf("Wrong!Too low!\n");
else if (guess < magic)
printf("Wrong!Too high!\n");
}while (guess != magic);
printf("Right!\n");
printf("counter = %d\n", counter);
}
答案:(1)错误提示"Wrong!Too low!\n"与"Wrong!Too high!\n"的位置放置反了
(2)if (guess > magic);多了一个分号
8. 计算矩阵相乘之积(有2个隐蔽错误,2个语法错误)
#include<stdio.h>
#define ROW 2
#define COL 3
main()
{
int a[ROW][COL], b[COL][ROW], c[ROW][ROW], i, j;
printf("Input array a:\n");
for (i=0; i<ROW ;i++)
{
for (j=0; j<COL; j++)
{
scanf("%d", &a[i][j]);
}
}
printf("Input array b:\n");
for (i=0; i<COL; i++)
{
for (j=0; j<ROW; j++)
{
scanf("%d", &b[i][j]);
}
}
MultiplyMatrix(a, b, c);
printf("Results:\n);
for (i=0; i<ROW; i++)
{
for (j=0; j<ROW; j++)
{
printf("%6d", c[i][j]);
}
printf("\n");
}
}
void MultiplyMatrix(int a[ROW][COL],int b[COL][ROW],int c[ROW][ROW])
{
int i, j, k;
for (i=0; i<ROW; i++)
{
for (j=0; j<ROW; j++)
{
for (k=0; k<COL; k++)
{
c[i][j] = c[i][j] + a[i][k] * b[j][k];
}
}
}
}
答案:(1)未初始化为0
for (j=0; j<ROW; j++)
{
c[i][j] = 0;
for (k=0; k<COL; k++)
(2)c[i][j] = c[i][j] + a[i][k] * b[j][k];应该改成
c[i][j] = c[i][j] + a[i][k] * b[k][j];
(3)printf("Results:\n);字符串未结束
(4)缺少函数原型
9. 利用 前200项之积计算π。(有2个隐蔽错误)
#include <stdio.h>
main()
{
float term, result;
int n;
for (n = 2; n <= 200; n = n + 2)
{
term = ( n * n)/(( n - 1) * ( n + 1));
result = result * term;
}
printf("result = %f\n", 2*result);
}
答案:(1)result未赋初值1
(2)term = ( n * n)/(( n - 1) * ( n + 1));应修改为
term = (float)( n * n)/(( n - 1) * ( n + 1));,否则精度丢失
10. 编程将若干字符串按字母顺序由小到大排序输出。(有1个隐蔽错误)
#include <stdio.h>
#include <string.h>
#define MAX_LEN 10
#define N 5
main()
{
int i, j;
char temp[MAX_LEN];
char str[N][MAX_LEN] = {"Pascal","Basic","Fortran","Java",
"Visual C"};
printf("Before sorted:\n");
for (i=0; i<N; i++)
{
puts(str[i]);
}
for (i=0; i<N-1; i++)
{
for (j = i+1; j<N; j++)
{
if (strcmp(str[j], str[i]) < 0)
{
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
}
printf("After sorted:\n");
for (i=0; i<N; i++)
{
puts(str[i]);
}
}
答案:(1)字符串拷贝错误
temp = str[i];
str[i] = str[j];
str[j] = temp;
应该改成:
strcpy(temp,str[i]);
strcpy(str[i],str[j]);
strcpy(str[j],temp);
第二部分
1. 编写一个将字符串倒序存放的函数。下面程序有2个隐蔽错误,1个语法错误,请找
出这些错误,并说明错误的原因,不要求写出完整的正确的程序。
#include <string.h>
#include <stdlib.h>
char *Invert(char *string)
{
int num, i;
char *p;
num = strlen(string);
p = (char *)malloc( num*sizeof(char)+1 );
for (i=0;i<num;i++)
*(p+num-i-1) = *(string+i);
return p;
}
main()
{
char *str={"teststring"}, result;
printf("Before invert string : %s\n", str);
result = Invert(str);
printf("After invert string : %s\n", result);
}
答案:(1)返回了动态内存分配的地址;
(2)*(p+num) = 0;没有置字符串结尾标志
(3)result应该声明为指针类型,且初始化
2. 利用一个数组实现字符串的逆序存放。下面程序有1个隐蔽错误,1个语法错误,3个
不良代码风格问题,请找出这些错误,并说明错误原因,不要求写出完整的正确程序。
#include<stdio.h>
main()
{
char a[10];
printf("Please enter ten strings : ");
gets(a);
Inverse(a);
puts(a);
}
Inverse(char str[])
{
int len, i;
char temp;
len = strlen(str);
for (i = 0; i<len; i++; len--)
{
temp = str[i];
str[i] = str[len];
str[len] = temp;
}
}
答案:(1)不良风格1,a定义为10个元素,用gets输入,容易导致缓冲区溢出,改成fge
ts(stdin,a,MAX_LEN),用宏定义定义MAX_LEN
(2)不良风格2,每次循环都改变循环终值
(3)不良风格3,函数未指明返回值类型,默认为int,且省略函数原型
(4)len = strlen(str)-1;
(5)for语句多了一个分号
3. 编写一个字符串连接函数,完成两个字符串的连接(有3个隐蔽错误,1个语法错误
)
#include <stdio.h>
#include <string.h>
main()
{
char *first;
char *second;
char *result;
printf("Input the first string:");
gets(first);
printf("Input the second string:");
gets(second);
result = StringCat(first, second);
printf("The result is : %s\n", result);
}
char* StringCat(char *dest, char *source)
{
int i = 0;
while (*(dest+i)!='\0') i++;
for (; *(source+i)!='\0'; i++)
*(dest+i) = *(source+i);
return dest;
}
答案:(1)指针first和second未初始化就使用,应该为:
char str1[10], str2[10];
char *first = str1;
char *second = str2;
(2)缺少函数原型
(3)使用gets输入字符串易导致缓冲区溢出
(4)函数StringCat编写错误,应该为:
char* StringCat(char *dest, char *source)
{
int i = 0, j;
while (*(dest+i)!='\0') i++;
for (j=0; *(source+j)!='\0'; j++,i++)
*(dest+i) = *(source+j);
*(dest+i) = '\0';
return dest;
}
4. 下面程序统计一个文件中的行数、字符数、字母数和数字数。
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<ctype.h>
typedef struct
{
int lines;
int chars;
int letters;
int digits;
} src_counter;
int main(int argc, char* argv[])
{
char* pathname=NULL;
src_counter counter;
if (argc < 2)
{
printf("Which file?");
gets(pathname);
}
else
{
pathname = argv[1];
}
counter=CountFile(pathname);
printf("\nThe counters in file %s are:\n", pathname);
PrintCounter(&counter);
return 0;
}
src_counter CountFile(const char* pathname)
{
src_counter counter;
FILE* fp=NULL;
char ch;
fp = fopen(pathname, "r");
while ((ch = fgetc(fp)) != EOF)
{
counter.chars++;
if (ch == '\n')
counter.lines++;
else if (isalpha(ch))
counter.letters++;
else if (isdigit(ch))
counter.digits++;
}
fclose(fp);
}
void PrintCounter(const src_counter* pCounter)
{
printf("Lines:%d\n", pCounter->lines);
printf("Chars:%d\n", pCounter->chars);
printf("Digits:%d\n", pCounter->digits);
printf("Letters:%d\n", pCounter->letters);
}
答案:
(1) CountFile和PrintCounter应在前面有声明
(2) CountFile未指定返回值
(3) gets的使用带来危险,而且pathname指向NULL,不是可控内存
(4) fopen没有进行错误处理
(5) 为counter赋初值
【 在 chaojie (chaojie) 的大作中提到: 】
: 各位参赛选手如有异议,请联系mstc_hit@163.com
: 同时,本次比赛的所有题目和答案均可通过邮件索要获得!
: 微软俱乐部
--
※ 来源:·哈工大紫丁香 http://bbs.hit.edu.cn·[FROM: 202.118.249.98]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:203.163毫秒