发信人: 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)
页面执行时间:205.349毫秒