二级C语言考前学习资料(机试)及C语言程序二十四种大题题型

二级C语言考前复习资料(机试)


机试做题技巧概述

一、程序填空题

【解析】该类型主要考察学员对一个C程序的整体把握能力。首先须通读整个源程序,了解程序的功能后试着边填空边调试,分析输出结果,以找到正确答案。因此,不像程序修改题那么简单。

【程序填空题的特点和注意事项】

(1)程序填空的试题中通常包含三个空需要填写。

(2)试题中用"******found******/"来提示在下一行或下二行注明填空的位置及编号,如___1___。

(3)程序填空考核对程序的整体把握,出题点可能是:for循环语句的初始化或条件判断、函数返回值、if语句的条件判断、链表中指针如何移动、文件操作相关函数的参数等。

(4)特别要注意的是:只能在填空的位置填写语句或表达式,不要增行或删行,不要改动程序行的顺序,更不要改动程序的结构。

【建议答题步骤】

(1)首先仔细审题,了解试题的要求,看清题目给出的输入和输出例示,以便检验程序运行的结果是否正确。

(2)审视"/******found******/"所在函数,根据题义理解程序所采用的基本算法,做到心里有数。

(3)填好空后对测试程序进行检查是否有语法错误。当编译提示有语法错时,可参考编译提示来查找并改正错误。

(4)当不再出现语法错时,执行程序, 按照试题的示例给出的数据进行试算,若试算的结果与给出的输出结果相同时,该题就做对了;若试算的结果与给出的输出结果不同,就应进一步检查程序中的逻辑错误。

(5)修改完成,得到正确结果后,一定不要忘记把修改后的程序存盘。

 二、程序修改题

【解析】该类型主要考察学员对C程序部分结构或算法的分析和理解能力。因此,对学员的知识把握能力要求不高,通常可以借助计算机帮我们改错(仅限语法错误)。若非语法错误,则需对程序边调试边找错,分析输出结果,找出错误所在并改正。

【程序填空题的特点和注意事项】

(1)上机改错的试题中通常包含两个(或三个)错误需要修改。

(2)试题中用"******found******/"来提示在下一行(或下面第二行)有错。

(3)错误的性质基本分语法错误和逻辑错误两种,也有些试题要求把语句添加在下划线处。

(4)特别注意:只能在出错的行上进行修改,不要改动程序行的顺序,更不要自己另编程序。

【建议答题步骤】

(1)首先仔细审题,了解试题的要求,看清楚试题给出的输入和输出例示,以便检验改错后程序运行的结果是否正确。

(2)审视"/******found******/"所在函数,根据题义理解程序所采用的基本算法,做到心里有数。

(3)先对测试程序进行检查是否有语法错误。当编译提示有语法错时,可参考编译提示来查找并改正错误。

(4)当不再出现语法错时,执行程序, 按照试题的示例给出的数据进行试算,若试算的结果与给出的输出结果相同时,该题就做对了;若试算的结果与给出的输出结果不同,就应进一步检查程序中的逻辑错误。

(5)当程序存在逻辑错误时,首先应当理解题意、读懂程序的算法,必要时可按步检查数据的流程,以便确定错误所在。例如,题目要求数据按由小到大排序,而结果数据是按由大到小进行了排序,问题可能出现在条件判断上。又如,输出的字符串比预期的短,就有可能字符串的结束标志放错了位置。再如做循环的时候数组上限下限错误了,下标是从0开始 而不是1开始的。修改程序中的逻辑错时,要求考生认真读懂程序代码。

(6)修改完成,得到正确结果后,一定不要忘记把修改后的程序存盘。

三、程序设计题

【解析】主要考察学员对C语言综合理解能力和上机实践能力,能够对所给问题,运用所学知识,按照程序设计的步骤独立编写出一段程序,学会用计算机语言描述日常生活中所见到的现象和拟题,通过实际上机操作积累经验,锻炼用C语言描述问题的逻辑思维能力。

【建议答题步骤】

(1)首先仔细审题,了解试题的要求,记下试题给出的输入和输出例示,以便检验在完成指定的函数后程序运行的结果是否正确。

(2)调出源程序后,应对照函数首部的形参,审视主函数中调用函数时的实参内容,以便明确在函数中需要处理的数据对象。

(3)理解试题的要求,审视主函数中调用函数的方式,若在表达式中调用函数(如把函数值赋给某个对象),则要求有函数值返回,需注意函数的类型,并在函数中用return语句返回函数值;若主函数中仅用语句形式调用函数,则需要通过形参间接地返回所得结果。

(4)选择适当的算法进行编程,输入程序语句。不要忘记及时存盘!

(5)编译程序,直到没有语法错误。

(6)调试程序,利用试题中给出的例示数据进行输入(若要求输入的话),运行程序,用示例的输出数据检验输出结果,直到结果相同。

   特别要注意:程序设计题要求完全设计正确才会给分,因此,要么是40分,要么是0分,不会给中间分。那么想通过机试,程序填空题和程序修改题通常来说必须全部正确才能容易通过,否则不容易通过。

上机填空、改错题重点题型归类分析

 

一、填空题(30分)两至三个空

注意:上机考试时要删除填空地方的数字和下划线

如:

long  fun(int n)

{

  if(___1___)  /* 填空时要删除此处的___1___ 此处应该填写if(n>1)*/

      return (n*fun(____2___));

   return ___3___;

}

常见题型:加下划线的代码是可能考填空的!

1.累加求和,累乘求阶乘

例如:求1+2!+3!+4!+...+N!

long fun(int n)

{

long s=0,t=1;

int i;

for(i=1;i<=n;i++){

t=t*i;      /* t负责求解N! */

s=s+t;     /* s负责求和,将每次求解的阶乘都加到s上 */

}

return s;

}

关键代码解析:

求n的阶乘:
for(i=1;i<=n;i++)

          { t=t*i; }

还可以用递归的方法:

long fun(int n){

   if(n>1)  

     return (n*fun(n-1));

   return 1;

}

其它:1+1/(1+2)+1/(1+2+3)+...+1/(1+2+3+...+n)

double fun(int n)

{

double sum=0.0;

for(i=0;i<=n;i++)

{

  t=0.0;

for(j=1;j<=i;j++)

  {  t=t+j;/*此处主要是求分母的和*/

  }

    sum=sum+(double)1/t; /*求总和*/

  }

   return sum;

}

2.素数的判断(除了1和其自身外,不能被任何数整数的数为素数)

判断整数2—n内的所有素数,并将素数输出,返回素数的个数

关键代码:

int fun(int n)

{

int i,j,flag,n=0;

 for(j=2;j<n;j++)

{

  flag=1; /* flag为标志变量,如果最后flag=1,则该数为素

            数* /

 for(i=2;i<j;i++)/* 该层循环主要判断每一个数是否为素数*/

 if(j%i==0)

{   flag=0;break;  /*只要j正整除i,说明j不是素数,跳出循环*/

        }

if(flag==1)   /* flag=1说明是素数*/

{ n++;/*n用于统计素数的个数*/

  printf("%d是素数",j);     

     }

}

return n;

}

3.大小写转化或者大小写字母的判断

例如:将Charch[50]="AAAbbCCddDDeeHHkkmmZZ";数组中的大写转成小写,小写转成大写

关键代码:

for(i=0;i<ch.length;i++){

   if(ch[i]>='a'&&ch[i]<='z') /*判断字母是不是小写*/

      ch[i]=ch[i]-32;      /*小写转大写,减去32即可*/

elseif(ch[i]>='A'&&ch[i]<='Z') /*判断字母是不是大写*/

       ch[i]=ch[i]+32; /*大写转小写,加上32即可*/

}

4.闰年的判断

判断某一年是不是闰年,关键代码:

if(n%4==0&&n%100!=0||n%400==0)

   printf("%d为闰年",n);

如果要求出1000-2000年中的所有闰年,则需要在外层套一个for循环

【分析】判断闰年只需要考虑两种情况:(1)年份能被4整除但不能被100整除(2)年份能被400整除

5.求一组数的中的最大数和最小数

void fun(int n,intx[])

{  int max,min,i;

   max=min=x[0];/*先假设第一个数既是最大数,也是最小*/

    for(i=0;i<n;i++)

 {

if(x[i]>max)

max=x[i];    /*将所有的最大数存放在max中*/

if(x[i]<min)

min=x[i];  /*将所有的最小数存放在min中*/

 }

printf("最大数为:%d,最小数为:%d",max,min);

}

6.逆转(将字符串中的字符逆转或者把数组中的元素逆转)

关键代码分析:

void fun(char *str)

{   int i,j,k;

j=strlen(str)-1; /*strlen(ch)是求出字符串的长度,减1是为

                   了定位到最后一个字符*/

for(i=0;i<j;i++,j--)

{

k=str[i];str[i]=str[j];str[j]=k;  /*互换首尾的字符,实现逆转*/

}

printf("逆转后的字符串:%s",str);

}

7.N*N矩阵的操作

(1)将左三角元素置0,将矩阵转置,求矩阵周边元素的值

for(i=0;i<N;i++)
for(j=0;j<i;j++)
a[i][j]=0; 
/*a[i][j]是左下三角元素*/      /*a[j][i]是右下三角元素*/

此种类型的题目,只要获得了左下三角元素和右下三角元素,就容易求解了!

(2)将N×N矩阵主对角线元素中的值与反向对角线对应位置上元素中的值进行交换。N=3,有下列矩阵:

        1   2    3

        4   5    6

        7   8    9

交换后为:

        3   2    1

        4   5    6

        9   8    7

void fun(int  t[][N], int  n)
{  int  i,s;
   for(i=0;i<n; i++)
   {  s=t[i][i];
      t[i][i]=t[i][n-i-1];
      t[i][n-1-i]=s ;
   }
}

8.整除问题

例如:求100——200内能别2整除不能被3整除的所有整数

void fun()

{

int a[100],j=0;

for(i=101;i<200;i++)

if(i%2==0&&i%3!=0)

a[j++]=i;/*将符合条件的存放在数组中*/

}

如果题目改为:能被3整除或能被7整除但不能同时被3和7整除,则条件判断应为:if((i%3= =0||i%7= =0)&&i%21!=0)

【注意】此处一定是= =,在改错题中经常考

9.获取一个三位数的个位数,十位数,百位数

例如:intx=456,i,j,k;

个位数:i=x%10;       /*此方法对任何位数的整数都适用,必须熟记*/

十位数:j=(x/10)%10   /* x/10=45而不是45.6*/

百位数:k=x/100;

其它位数:对于4位数,5位数,获取最高位的方法很多,不过最简单的方法是除以4位数,5位数的最小数即可

如:4567/1000=4     /*1000为四位数的最小数,整除后即得最高位4*/

23456/10000=2   /*10000为五位数的最小数,整除后即得最高位2*/

获取中间位数的数的方法也很多,/100,/10最后再对10求余都可以获得

10.排序算法——选择法排序(从小到大进行排序)

void fun(int a[],int n)

{

     int i,j,t,p;

      for(i=0;i<n;i++)

        {   p=i;  /* p用于记录最小元素的下标,先假设第

                    一个元素最小*/

         for(j=i+1;j<n;j++)

         if(a[p]>a[j])  /*后面还有比第一个元素还小的数*/

          p=j;        /*将最小数的下标存在p中*/

         if(p!=i)  /*说明a[i]不是最小的数,最小数的下标

                    存在变量p中*/

         {

           t=a[p]; a[p]=a[i]; a[i]=t; 

        }

}

11.取子串,按要求取出长字符串中的子字符串,并统计子串的个数

如取出"abcddsafabsafacab dsfwerab"中的子串ab,并统计个数

int fun(char*str,char *substr)

{  int n = 0 ;

  char *p, *q ;

   while(*str)   /* 或者写成 *str!='\0'和*str!=0都可以*/

     {

p=str;   /* p指向第一个字符串*/

q=substr;/* q指向子字符串*/

while(*q)  /* 或者写成 *q!='\0'和*q!=0都可以*/

       if(*p= =*q)   /*如果内容相等,说明符合条件*/

{  p++;  q++; }  /*指针向后移动,进行后面字符

                  的判断*/

else{ break;}    /*内层循环到此结束*/

if(*q=='\0')    /* 子串内容判断结束了,说明出现了子串*/

n++;           /* 将子串的个数加1*/

str++;       /*移动父串指针,进行后面的判断*/

      }

  return n ;

}

12.统计:统计分数段的人数个数

统计字符串中数字或某一个字符出现的个数

例如:统计成绩在90分以上,80-90,70-80,60-70,60分以下各分数段人数个数,每个分数段的人数分别存放在数组b中

void fun(int n,inta[],int b[])

{

int i;

for(i=0;i<n;i++)

switch(a[i]/10)

{

case 10:

case 9:b[0]++;break;

case8:b[1]++;break;

case7:b[2]++;break;

case6:b[3]++;break;

default:b[4]++;

}

}

13.斐波纳契数(1  1   2   3   5   8   13  21  34  ....)

第一、二个数为1,后面的每一个数是前面两个数的和

例如:求第n位斐波纳契数

int fun(int n)

{

  if(n<=1) /*此处还可以改为 if(n= =0||n= =1)*/

   return 1;

  else  return fun(n-1)+fun(n-2); /*递归算法*/

}

14.链表

给定程序中,函数fun的功能是将带头节点的单向链表结点数据域中的数据从小到大排序。即若原链表结点数据域从头至尾的数据为:10、4、2、8、6,排序后链表结点数据域从头至尾的数据为:2、4、6、8、10。

typedef struct node {

  int  data;

  struct node  *next;

} NODE;

void fun(NODE  *h)

{ NODE  *p, *q;    int t;

  p =  h->next  ;

  while (p) {

     q = p->next;/*使q始终代表当前的节点*/

     while (q) {

        if (p->data >= q->data)

        {  t = p->data;  p->data = q->data;  q->data = t;  }

        q = q->next;

    }

    p = p->next;

  }

}

15.函数

给定程序中,函数fun的功能是根据形参i的值返回某个函数的值。当调用正确时, 程序输出:x1=5.000000, x2=3.000000, x1*x1+x1*x2=40.000000

double f1(double  x)

{  return x*x;  }

double f2(double  x,double  y)

{  return  x*y;  }

double   fun(int i, double  x, double  y)

{ if (i==1)

    return f1 (x);

  else

    return f2 (x, y);

}

main()

{ double  x1=5, x2=3, r;

  r = fun(1, x1, x2);

  r += fun(2, x1, x2);

  printf("\nx1=%f, x2=%f,x1*x1+x1*x2=%f\n\n",x1, x2, r);

}

16.字符串与ASCII

给定程序中,函数fun的功能是:对形参s所指字符串中下标为奇数的字符按ASCII码大小递增排序,并将排序后下标为奇数的字符取出,存入形参p所指字符数组中,形成一个新串。

    例如,形参s所指的字符串为:baawrskjghzlicda,执行后p所指字符数组中的字符串应为:aachjlsw。

void fun(char  *s,char  *p)

{  int  i, j, n, x, t;

   n=0;

   for(i=0; s[i]!='\0';i++)  n++;

   for(i=1; i<n-2;i=i+2) {

       t=i;

      for(j=i+2 ; j<n; j=j+2)

        if(s[t]>s[j])t=j;

      if(t!=i)

      {  x=s[i]; s[i]=s[t]; s[t]=x; }

   }

   for(i=1,j=0; i<n;i=i+2, j++)  p[j]=s[i];

   p[j]=0;

}

   fun(s,p);

   printf("\nTheresult is :  %s\n",p);

}

17.回文

给定程序中,函数fun的功能是:判断形参s所指字符串是否是"回文"(Palindrome),若是,函数返回值为1;不是,函数返回值为0。"回文"是正读和反读都一样的字符串(不区分大小写字母)。21

    例如,LEVEL和Level是"回文",而LEVLEV不是"回文"。

int fun(char  *s)

{ char  *lp,*rp;

  lp= s ;

  rp=s+strlen(s)-1;

 while((toupper(*lp)==toupper(*rp)) && (lp<rp) ) {

     lp++; rp --  ; }

  if(lp<rp) return 0 ;

  else   return 1;

}

18.数字问题

给定程序中,函数fun的功能是:将形参n中,各位上为偶数的数取出,并按原来从高位到低位相反的顺序组成一个新的数,并作为函数值返回。

    例如,输入一个整数:27638496,函数返回值为:64862。

 unsigned longfun(unsigned long  n)

{ unsigned long x=0;    int  t;

  while(n)

  { t=n%10;

    if(t%2==0 )

       x=10*x  +t;

    n=n/10 ;

  }

  return  x;

}

19.字符串中的字符与数字关系

给定程序中,函数fun的功能是: 将s所指字符串中的所有数字字符移到所有非数字字符之后,并保持数字字符串和非数字字符串原有的先后次序。例如,形参s所指的字符串为:def35adh3kjsdf7。执行结果为:defadhkjsdf3537。

 void fun(char  *s)

{  int  i, j=0, k=0;    char t1[80], t2[80];

   for(i=0; s[i]!='\0';i++)

     if(s[i]>='0'&& s[i]<='9')

     {

       t2[j]=s[i]; j++ ;

     }

     else  t1[k++]=s[i];

  t2[j]=0;  t1[k]=0;

  for(i=0; i<k; i++) s[i]=t1[i];

  for(i=0; i<j ; i++)  s[k+i]=t2[i];

}

20.数组中偶数下标与奇数下标

函数fun的功能是:把形参a所指数组中的偶数按原顺序依次存放到a[0]、a[1]、a[2]、……中,把奇数从数组中删除,偶数个数通过函数值返回。例如:若a所指数组中的数据最初排列为:9、1、4、2、3、6、5、8、7,删除奇数后a所指数组中的数据为:4、2、6、8,返回值为4。  

#define    N    9

int fun(int  a[],int  n)

{  int  i,j;

   j = 0;

   for (i=0; i<n; i++)

      if (a[i]%2==0)

 {

        a[j]  = a[i]; j++;

      }

   return j    ;

}

21.文件

给定程序中,函数fun的功能是将形参给定的字符串、整数、浮点数写到文本文件中,再用字符方式从此文本文件中逐个读入并显示在终端屏幕上。

 

 void fun(char  *s, int a, double  f)

{

  FILE *   fp;/*定义一个指向文件的指针*/

  char  ch;

  fp =fopen("file1.txt", "w");

  fprintf(fp, "%s %d%f\n", s, a, f);

  fclose(fp);

  fp =fopen("file1.txt", "r");

  printf("\nTheresult :\n\n");

  ch = fgetc(fp);

  while (!feof(fp  ))

{ putchar(ch    ); ch = fgetc(fp);  }

  putchar('\n');

  fclose(fp);

}

二、改错题(30分)两至三个错误

注意:对于基本的语法错误,可以直接通过编译找出来,但是对于逻辑错误,需要自己在看懂程序的基础上进行修改。把程序要实现的功能搞清楚,修改起来就容易些。

1.遗漏分号,括号等

经常出现在以下地方:

k++    ----------------->k++;

break  ----------------->break;

return sum  ------------>return sum;

if k>1----------------->if( k>1)

if!(n%i)--------------->if (!(n%i))

【例】

给定程序MODI1.C中函数fun的功能是:用递归算法计算斐波拉契数列中第n项的值。从第1项起,斐波拉契数列为:1、1、2、3、5、8、13、21、……

例如,若给n输入7,该项的斐波拉契数值为:13。请改正程序中的错误,使它能得出正确结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构。

#include <stdio.h>

long fun(int  g)

{

/**********found**********/

   switch(g);

   {  case 0: return 0;

/**********found**********/

       case 1 ;case 2 : return 1 ;

   }

   return( fun(g-1)+fun(g-2) );

}

main()

{ long   fib;    int  n;

  printf("Input n:  ");scanf("%d",&n); printf("n = %d\n",n);

  fib=fun(n);

  printf("fib = %d\n\n",fib);

}

【参考答案】:

(1)      switch(g)

(2)case1: return 1; case 2:return 1;

2.条件判断时,判断符合出错

while(i=j)-------------->while(i= =j)

if(m=k)----------------->if(m= =k)

3.赋值出错或没有赋值

(1)变量定义之前没有赋值

long k;而在之后的程序中使用到了k,此时必须对k初始化,如long k=0;

(2)赋值时类型不匹配

char * r,*p;

if(r= =p)----------------->if(*r= =*p)

*p,*r才是表示内容,而r,p是表示地址

int *a;intx=10,t=20;a=&x;

a=t;----------------->a=&t;指针只能存放变量的地址

a=t;----------------->*a=t;将变量赋给指针所指向的变量

charch="\0"; ------->char ch='\0';字符是用单引号括起来

charch='0'------>char ch='\0';此时是将字符0赋给ch变量,而不是\0

        --->char ch=0;因为'\0'的ASCII码就是0,所以可直接用0进行赋值

【例】

给定程序MODI1.C中函数fun的功能是:将长整型数中每一位上为奇数的数依次取出,构成一个新数放在t中。高位仍在高位,低位仍在低位。

   例如,当s中的数为:87653142时,t中的数为:7531。

   请改正程序中的错误,使它能得出正确的结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include <stdio.h>

void fun (long  s, long *t)

{ int   d;

 long  sl=1;

/************found************/

 t = 0;

 while ( s > 0)

 {  d = s%10;

/************found************/

     if (d%2 == 0)

     { *t = d * sl + *t;

       sl*= 10;

     }

     s /= 10;

 }

}

main()

{ long s, t;

  printf("\nPlease enter s:"); scanf("%ld", &s);

  fun(s, &t);

  printf("The result is: %ld\n", t);

}

【参考答案】:

(1)*t=0;

(2)if(d%2!=0)

4.函数定义出错,常见错误如下:(考得非常频繁,请务必熟记

(1)int fun(int m);------>int fun(int m)函数定义时末尾的分号是多余的

(2)int fun(int m) int i=20;char ch;--->int fun(int m){  函数名后必须要有大括号

(3)fun(int n)----->double fun(int n)缺少返回值类型double,会经常考

(4)void fun(int a,int b)---->void fun(int *a,int *b)参数类型不对

(5)void fun(int a,b)------->void fun(int a,int b)相同类型的参数也要分开定义

(6)void fun(int a[][],int n)------>void fun(int a[][10],intn)数组定义时二维下标不能省略

(7)voidfun(int n)----->voidfun(int n)返回值类型和函数名之间有空格

(8)函数定义时有返回值类型,但程序中缺少return 语句

【例】

给定程序MODI1.C中函数fun的功能是:根据形参m的值(2≤m≤9〕,在m行m列的二维数组中存放如下所示规律的数据,由main函数输出。例如,若输入 2              | 若输入  4

      则输出:              | 则输出:

            1  2           |       1  2   3   4

            2  4           |       2  4   6   8

                            |       3  6   9   12

                            |       4  8   12  16

   请改正程序函数中的错误,使它能得出正确的结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include <conio.h>

#include <stdio.h>

#define  M 10

int  a[M][M] = {0} ;

/**************found**************/

void fun(int **a, int m)

{ int j, k ;

  for (j = 0 ; j < m ; j++ )

        for (k = 0 ; k < m ; k++ )

/**************found**************/

          a[j][k] = k * j ;

}

main ( )

{ int  i, j, n ;

  printf ( " Enter n : " ) ; scanf ("%d", &n ) ;

  fun ( a, n ) ;

  for ( i = 0 ; i < n ; i++)

  {    for (j = 0 ; j < n ; j++)

          printf ( "%4d", a[i][j] ) ;

        printf ( "\n" ) ;

  }

}

【参考答案】:

(1)      voidfun(int a[][M], int m)

(2)a[j][k]=(k+1)*(j+1);

【例】:

给定程序MODI1.C中函数 fun 的功能是:求S的值。

    例如,当k为10时,函数值应为:1.533852。

    请改正程序中的错误,使程序能输出正确的结果。

    注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include<stdio.h>

#include<math.h>

/************found************/

void fun(int  k )

{  int n; double s,  w, p, q;

   n = 1;

   s = 1.0;

   while ( n <= k )

   { w = 2.0 * n;

     p = w - 1.0;

     q = w + 1.0;

     s = s * w *w/p/q;

n++;

   }

/************found************/

   return s

}

main ( )

{

   printf("%f\n", fun (10));

}

【参考答案】

(1)floatfun(int  k)

(2)return s;

5.实现交换时赋值出错

(1)

if(a<b){ t=a;b=a;b=t}
if(a<b){ t=a;a=b;b=t}

void fun(int *a,int *b)
{   int t;
t=*b;*b=*a;*a=t;
}/*这段代码不懂就背下来*/

(2)

void fun(int *a,int *b)

{   int t;

t=b;b=a;a=t;

/*上面赋值类型不匹配*/

}

【例】

给定程序MODI1.C中函数fun的功能是:通过某种方式实现两个变量值的交换,规定不允许增加语句和表达式。例如变量a 中的值原为8,b中的值原为3, 程序运行后a 中的值为 3,b中的值为8。

    请改正程序中的错误,使它能得出正确的结果。

    注意: 不要改动 main 函数,不得增行或删行,也不得更改程序的结构!

#include <stdio.h>

int fun(int *x,int y)

{

 int t ;

/**************found**************/

 t = x ; x = y ;

/**************found**************/

 return(y) ;

}

main()

{

 int a = 3, b = 8 ;

 printf("%d  %d\n", a, b);

 b = fun(&a, b) ;

 printf("%d  %d\n", a, b);

}

【参考答案】

(1)t=*x;*x=y;

(2)returnt;

6.for循环的格式不对

for(i=0,i<10,i++)------>for(i=0;i<10;i++)应该以分号为间隔符

for(i=0;i<n-1;i++)----->for(i=0;i<n;i++)循环的次数不对,要根据具体的题目来判断,此处也是一个考点,会在改错题中经常考,要特别注意!

7.++、- -与*结合问题,搞清楚什么时候应该加括号。搞清楚什么时候该加*号

++、- -和*是同一优先级,结合性是从右向左

*p++; 是指针p向后移动一个存储单元 然后取指针p所指变量的值。

(*p)++; 是将指针p所指变量的值自增1.

【例】:

给定程序MODI1.C中函数fun的功能是: 比较两个字符串,将长的那个字符串的首地址作为函数值返回。

    请改正函数fun中指定部位的错误, 使它能得出正确的结果。

    注意:不要改动main函数,不得增行或删行, 也不得更改程序的结构!

#include<stdio.h>

/**********found**********/

charfun(char *s,  char *t)

{  int sl=0,tl=0;    char  *ss, *tt;

   ss=s;   tt=t;

   while(*ss)

   { sl++;

/**********found**********/

      (*ss)++;

   }

   while(*tt)

   { tl++;

/**********found**********/

      (*tt)++;

   }

   if(tl>sl) return  t;

   else      return  s;

}

main()

{  char a[80],b[80];

   printf("\nEnter a string :  "); gets(a);

   printf("\nEnter a string again :  "); gets(b);

   printf("\nThe longer is:\n\n\"%s\"\n",fun(a,b));

}

【参考答案】

(1)char *fun(char *s,char *t)

(2)ss++;

(3)tt++;

7.大小写问题

If、For-------> if 、for

【例】:

由N个有序整数组成的数列已放在一维数组中,给定程序MODI1.C中函数fun的功能是:利用折半查找算法查找整数m在数组中的位置。若找到,返回其下标值;反之,返回-1。

    折半查找的基本算法是:每次查找前先确定数组中待查的范围:low和high(low<high),然后把m与中间位置(mid)中元素的值进行比较。如果m的值大于中间位置元素中的值,则下一次的查找范围落在中间位置之后的元素中;反之,下一次的查找范围落在中间位置之前的元素中。直到low>high,查找结束。

    请改正程序中的错误,使它能得出正确结果。

    注意:不要改动main函数,不得增行或删行,也不得更改程序的结构。

#include<stdio.h>

#define   N   10

/************found************/

voidfun(int  a[], int  m )

{  int low=0,high=N-1,mid;

   while(low<=high)

   { mid=(low+high)/2;

      if(m<a[mid])

        high=mid-1;

/************found************/

      else If(m > a[mid])

        low=mid+1;

      else return(mid);

   }

   return(-1);

}

main()

{  int i,a[N]={-3,4,7,9,13,45,67,89,100,180 },k,m;

   printf("a数组中的数据如下:");

   for(i=0;i<N;i++) printf("%d ",a[i]);

   printf("Enter m: ");  scanf("%d",&m);

   k=fun(a,m);

   if(k>=0)printf("m=%d,index=%d\n",m,k);

   else printf("Not be found!\n");

}

【参考答案】:

(1)int fun(int a[],int m)

(2)elseif(m>a[mid])

8.数组元素逆序存放问题(常考!)

实质就是将数组中首位元素依次互换s[i]       s[sl-i-1];(记住这个对应关系!)

【例】

给定程序MODI1.C中函数fun的功能是:先将s所指字符串中的字符按逆序存放到t所指字符串中,然后把s所指串中的字符按正序连接到t所指串的后面。

   例如:当s所指的字符串为:"ABCDE"时,

          则t所指的字符串应为:"EDCBAABCDE"。

   请改正程序中的错误,使它能得出正确的结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include <stdio.h>

#include <string.h>

void fun (char  *s, char *t)

{

/************found************/

   int   i;

   sl = strlen(s);

   for (i=0; i<sl; i++)

/************found************/

       t[i] = s[sl-i];

   for (i=0; i<sl; i++)

        t[sl+i] = s[i];

   t[2*sl] = '\0';

}

main()

{ char s[100], t[100];

  printf("\nPlease enter string s:"); scanf("%s", s);

  fun(s, t);

  printf("The result is: %s\n", t);

}

【参考答案】:

(1)      inti,sl;

(2)t[i]=s[sl-i-1];

9、带参宏定义,参数要加括号

【例】

给定程序MODI1.C中函数fun的功能是:计算函数F(x,y,z)=(x+y)/(x-y)+(z+y)/(z-y)的值。其中x和y的值不等,z和y的值不等。

   例如,当x的值为9、y的值为11、z的值为15时,函数值为 -3.50。

   请改正程序中的错误,使它能得出正确结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构。

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

/************found************/

#define   FU(m,n)  (m/n)

float fun(float a,float b,float c)

{ float  value;

  value=FU(a+b,a-b)+FU(c+b,c-b);

/************found************/

  Return(Value);

}

main()

{ float  x,y,z,sum;

  printf("Input  x  y z:  ");

  scanf("%f%f%f",&x,&y,&z);

  printf("x=%f,y=%f,z=%f\n",x,y,z);

  if (x==y||y==z){printf("Data error!\n");exit(0);}

  sum=fun(x,y,z);

  printf("The result is : %5.2f\n",sum);

}

【参考答案】:

(1)*t=0;

(2)if(d%2!=0)

10、链表问题,关于链表的插入、删除操作要熟悉

【例】

给定程序MODI1.C是建立一个带头结点的单向链表, 并用随机函数为各结点数据域赋值。函数fun的作用是求出单向链表结点(不包括头结点)数据域中的最大值,并且作为函数值返回。

   请改正函数fun中指定部位的错误, 使它能得出正确的结果。

   注意: 不要改动main函数, 不得增行或删行, 也不得更改程序的结构!

#include <stdio.h>

#include <stdlib.h>

typedef  struct aa

{ int  data;

  struct  aa  *next;

} NODE;

int fun (  NODE *h )

{ int  max=-1;

 NODE  *p;

/***********found**********/

 p=h ;

 while(p)

 {  if(p->data>max )

              max=p->data;

/***********found**********/

     p=h->next ;

 }

 return  max;

}

outresult(int  s, FILE *pf)

{ fprintf(pf,"\nThe max in link :  %d\n",s);}

NODE  *creatlink(int  n, int m)

{ NODE  *h, *p, *s;

  int  i;

  h=p=(NODE *)malloc(sizeof(NODE));h->data=9999;

  for(i=1; i<=n; i++)

  {  s=(NODE *)malloc(sizeof(NODE));

      s->data=rand()%m;  s->next=p->next;

      p->next=s;         p=p->next;

  }

  p->next=NULL;

  return  h;

}

outlink(NODE  *h, FILE *pf)

{ NODE  *p;

  p=h->next;

  fprintf(pf,"\nTHE  LIST:\n\n  HEAD ");

  while(p)

  {  fprintf(pf,"->%d",p->data); p=p->next; }

      fprintf(pf,"\n");

  }

main()

{ NODE  *head;  int  m;

  head=creatlink(12, 100);

  outlink(head , stdout);

  m=fun(head);

  printf("\nTHE  RESULT  :\n"); outresult(m, stdout);

}

【参考答案】

(1)p=h->next;

(2)p=p->next;

其它错误:

(1)返回值不对  return (a)------>return (b);

(2)初始化的值不对 ints=1;------>int s=0;

(3)float f=5.36;int i=int(f)---->inti=(int)f;强制转化是在类型上加括号

(4)inti=4512;i\=10---------->int i=4512;i/=10除号是左下的斜线

(5)int i=j/k;------>int i=j %k;根据具体题目要求来改,也是考点之一,有时候要反过来改,将% 改为 /

【例】

给定程序MODI1.C中函数fun 的功能是:用下面的公式求π的近似值,直到最后一项的绝对值小于指定的数(参数num )为止:

     π       1      1      1

   ┄┄≈1 - ┄┄+ ┄┄ - ┄┄+ ...

     4        3      5      7

   例如, 程序运行后,输入0.0001, 则程序输出3.1414。

   请改正程序中的错误,使它能输出正确的结果。

   注意:不要改动 main 函数,不得增行或删行,也不得更改程序的结构!

#include <math.h>

#include <stdio.h>

float fun ( float num )

{  int s ;

   float n, t, pi ;

   t = 1 ; pi = 0 ; n = 1 ;  s = 1 ;

/**************found**************/

   while(t >= num)

   {

        pi = pi + t ;

        n= n + 2 ;

        s = -s ;

/**************found**************/

        t = s % n ;

   }

   pi = pi * 4 ;

   return pi ;

}

main( )

{  float n1, n2 ;

   printf("Enter a float number: ") ;

   scanf("%f", &n1) ;

   n2 = fun(n1) ;

   printf("%6.4f\n", n2) ;

}

【参考答案】

while((fabs(t))>=num)        

 t=s/n

(6)scanf("%d",a[i][j])---->scanf("%d", &a[i][j])缺少取地址符号

(7)inti=10;printf("%f",i);---->printf("%d",i);输出格式不对

【例】

给定程序MODI1.C中函数fun的功能是:输出M行M列整数方阵,然后求两条对角线上元素之和,返回此和数。

   请改正程序中的错误,使它能得出正确的结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include <stdio.h>

#define  M   5

/************found************/

int  fun(int n, int  xx[][])

{ int  i, j, sum=0;

 printf( "\nThe %d x %d matrix:\n", M, M );

 for( i = 0; i < M; i++ )

 {  for( j = 0; j < M; j++ )

/************found************/

      printf( "%f ", xx[i][j] );

   printf("\n");

 }

 for( i = 0 ; i < n ; i++ )

   sum += xx[i][i]+xx[i][ n-i-1 ];

 return( sum );

}

main( )

{ int aa[M][M]={{1,2,3,4,5},{4,3,2,1,0},

{6,7,8,9,0},{9,8,7,6,5},{3,4,5,6,7}};

 printf ( "\nThe sum of all elements on 2 diagnals is %d.",fun(M, aa ));

}

【参考答案】

(1)int fun(int n,int xx[][M])

(2)printf("%d",xx[i][j]);


(8)'o'-------->'0'要注意区分字符o和数字0的区别

(9)int sum=0.0;-------->doublesum=0.0;变量的类型不匹配或类型定义错误(如:int r;----->double r;)

(10)浮点数不能比较大小,只能用绝对值来比较

float t=1;

if(t>=0.0001)---------->if(fabs(t)>=0.0001)必须要用取绝对值函数fabs

【例】

给定程序MODI1.C中函数fun 的功能是:用下面的公式求π的近似值,直到最后一项的绝对值小于指定的数(参数num )为止:

     π       1      1      1

   ┄┄≈1 - ┄┄+ ┄┄ - ┄┄+ ...

     4        3      5      7

   例如, 程序运行后,输入0.0001, 则程序输出3.1414。

   请改正程序中的错误,使它能输出正确的结果。

   注意:不要改动 main 函数,不得增行或删行,也不得更改程序的结构!

#include <math.h>

#include <stdio.h>

float fun ( float num )

{  int s ;

   float n, t, pi ;

   t = 1 ; pi = 0 ; n = 1 ;  s = 1 ;

/**************found**************/

   while(t >= num)

   {

        pi = pi + t ;

        n = n + 2 ;

        s = -s ;

/**************found**************/

        t = s % n ;

   }

   pi = pi * 4 ;

   return pi ;

}

main( )

{  float n1, n2 ;

   printf("Enter a float number: ") ;

   scanf("%f", &n1) ;

   n2 = fun(n1) ;

   printf("%6.4f\n", n2) ;

}

【参考答案】:

(1)      while((fabs(t))>=num)

(2)t=s/n


(11)条件判断时的符号不对(这种错误要根据具体的题意来修改

如:if(fabs(n-m)<0.0001)-------->if(fabs(n-m)>0.0001)

    if(*s<*p) ------->if(*s>*p)

for(;j<=n;)-------->for(;j<n;)

int *a[10]-------->int(*a)[10]

【例】

给定程序MODI1.C中函数fun的功能是:找出一个大于形参m且紧随m的素数,并作为函数值返回。

    请改正程序中的错误,使它能得出正确的结果。

    注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include<stdio.h>

intfun(int m)

{  int i, k ;

  for (i = m + 1 ; ; i++) {

      for (k = 2 ; k < i ; k++)

/**************found**************/

         if (i % k != 0)

            break ;

/**************found**************/

         if (k < i)

           return(i);

  }

}

void main()

{

 int n ;

 n = fun(20) ;

 printf("n=%d\n", n) ;

}

【参考答案】:

(1)      if(i%k==0)

(2)if(k>=i)

【例】

给定程序MODI1.C中函数fun的功能是:根据整型形参m的值,计算如下公式的值。

                1       1             1

      t = 1 - ----- - ----- - …… - -----

               2*2     3*3            m*m

   例如,若 m 中的值为:5,则应输出: 0.536389。

   请改正程序中的错误,使它能得出正确的结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构!

#include <stdio.h>

double fun ( int m )

{ double   y = 1.0 ;

  int  i ;

/**************found**************/

  for(i = 2 ; i < m ; i++)

/**************found**************/

      y -= 1 /(i * i) ;

  return( y ) ;

}

main( )

{ int n = 5 ;

  printf( "\nThe result is %lf\n", fun ( n ) ) ;

}

【参考答案】:

for(i=2;i<=m;i++)

(2)y-=1.0/i/i;

以上是可能会出错的地方,基本上涵盖了考试中会出现的所有错误,在上机考试时,要多注意这些容易出错的地方!

【补充真题】

1、给定程序MODI1.C中,函数fun的功能是:在任意给定的N个正整数中,从左到右依次逐个取三个数作为一组,按值大小找出该组数的中值,用该中值替换与该组数对应的原三个数中的中间位置的数。处理后原数列中首尾2个数不变。处理后数列在主函数中输出。例如,有10个正整数如下:


   请改正程序中指定部位的错误,使它能得出正确结果。

   注意:不要改动 main 函数,不得增行或删行,也不得更改程序的结构!

#include  <stdio.h>

#define   N   10

int findmid(int  a, int b, int  c)

{ int  t;

  t = (a>b)?(b>c?b:(a>c?c:a)):((a>c)?a:((b>c)?c:b));

/**********found**********/

  return  b;

}

void fun(int  x[])

{ int  i,a,b,c,t[N];

/**********found**********/

  for(i=0;i<N;i++) t[i]=x[i]

  for(i=0;i<N-2;i++)

  {  a=t[i];b=t[i+1];c=t[i+2];

/**********found**********/

      t[i+1]=findmid(a,b,c);

  }

}

main()

{ int  i,x[N]={6,5,7,23,18,5,8,21,45,38};

  for(i=0; i<N; i++) printf("%d ",x[i]);

  printf("\n");

  fun(x);

  for(i=0; i<N; i++) printf("%d ",x[i]);

  printf("\n");

}

【参考答案】:

(1)      returnt;

(2)for(i=0;i<N;i++)t[i]=x[i];

(3)x[i+1]=findmid(a,b,c);

2、

 例如,若给m输入-100,给n输入90,则函数求得的一个根值为2.000。

   请改正程序中的错误,使它能得出正确结果。

   注意:不要改动main函数,不得增行或删行,也不得更改程序的结构。

#include <stdio.h>

#include <math.h>

double funx(double  x)

{  return(2*x*x*x-4*x*x+3*x-6);  }

double fun( double  m, double n)

{

/************found************/

   int  r;

   r=(m+n)/2;

/************found************/

   while(fabs(n-m)<0.001)

   {   if(funx(r)*funx(n)<0)  m=r;

       else  n=r;

       r=(m+n)/2;

   }

   return  r;

}

main( )

{ double  m,n, root;

  printf("Enter  m  n : \n"); scanf("%lf%lf",&m,&n);

  root=fun( m,n );

  printf("root = %6.3f\n",root);

}

【参考答案】:

(1)doubler;

(2)while(fabs(m-n)>0.001) 

上机编程题重点题型归类分析(二十四章经)

题型一:整数合并

题型二:累加、累乘求和

题型三:素数判定

题型四:在一维数组中按指定条件筛选

题型五:一维数组最值求解

题型六:一维数组排序

题型七:元素平移问题

题型八:数组去掉值重复的元素

题型九:数组元素的查找

题型十:二维数组周边元素

题型十一:二维数组对角线、上三角和下三角元素的操作

题型十二:二维数组转一维数组

题型十三:二维数组转置问题(即行列互换)

题型十四:数字字符串转整数

题型十五:“回文”字符串

题型十六:字符串统计问题

题型十七:字符串指定字符删除

题型十八:字符串数组求最值

题型十九:字符串的逆置

题型二十:字符串的连接

题型二十一:结构体数组求最值

题型二十二:结构体数组排序

题型二十三:链表

题型二十四:Fibonacci数列

 

 题型一:整数合并

1、函数fun的功能是: 将a、b中的两个两位正整数合并形成一个新的整数放在c中。合并的方式是:将a中的十位和个位数依次放在变量c的百位和个位上,b中的十位和个位数依次放在变量c的千位和十位上。

    例如,当a=45,b=12。调用该函数后,c=1425。

请编写fun函数实现该功能:

void fun(int a, int b, long *c)

{

*c=a/10*100+a%10+b/10*1000+b%10*10;

}

【解题思路】本题主要考了以下几个知识点:

(1)如何获得一个二位数的个位和十位:

不管是几位数,获得个位数的方法:a%10即可获得个位

两位数获得十位的方法:a/10

(2)十进制中四位数的构成:

如十进制的1234=1*1000+2*100+3*10+4*1

也就是说:只要知道该四位数的各位上的数码,通过以上组合的方式就可以组合成一个四位数。如:b的十位放在c的千位,b/10*1000就是c的千位上的数了,其它的依次类推

题型二:累加、累乘求和

2、编写函数fun,它的功能是计算下列级数和,和值由函数值返回。

    例如,当n = 10,x=0.3时,函数值为1.349859。

#include <stdio.h>

#include <math.h>

double fun(double x , int n)

{

int i;

double a=1,b=1,s=1;

for(i=1;i<=n;i++)

{

a*=x;  /* a负责求解分子部分x的次方数*/

b*=i;  /* b负责求解分母部分的阶乘 */

s+=a/b; /* s作为总和 */

}

return s;

}

main()

{  void

  printf("%f\n", fun(0.3,10));

}

【解题思路】将复杂的多项式拆分开,找出各项或其中一部分的规律

(1)计算表达式的值,应根据题目要求定义变量数据类型以及如何初始化,找出各项的共同点。

(2)本程序中a,b用来表示每项的分子与分母(即各项中的阶乘),注意其初值都为1

题型三:素数判定

3、请编写函数fun,函数的功能是:将大于形参m且紧靠m的k个素数存入xx所指的数组中。例如,若输入17, 5,则应输出:19, 23, 29, 31, 37。函数fun中给出的语句仅供参考。

#include <stdio.h>

void fun(int m, int k, int xx[])

{

  /* 以下代码仅供参考 */

  int i, j=0, t=m+1;

  while(j<k)  /*找大于m的素数,循环k次即找出紧靠m的k个素数*/

  {

/* 以下完成判断素数,并存放到数组xx中 */

 

 

  }

}

main()

{

   int m, n, zz[1000];void

   printf( "\nPleaseenter two integers:") ;

  scanf("%d%d", &m, &n ) ;

   fun( m, n, zz) ;

   for( m = 0 ; m < n; m++ )

      printf("%d", zz[m]) ;

   printf("\n");

}

【参考答案】

for(i=2;i<t;i++)

if(t%i==0) break; /*判断该数是否能将之间的数整除,注意在退出for循环时的i的值是多少*/

if(t==i)

{

xx[j++]=t; /*如果是素数,放入数组xx中,已找到素数的个数变量j的值增1*/

}

t++;/*不管是否为素数,t的值都要增1,以便于while循环对下一位数判断*/

【解题思路】素数是历年考试中的重点和难点,掌握素数的基本概念:即除了1和t本身外,不能被“其它数”整除,“其它数”应该是从2到t-1的范围,从而确定循环变量的起始值、终止值

(1)本题答案中粗体部分是判断一个整数t是否为素数,通过for循环语句;if语句;break语句,与if语句连在一起满足条件时跳出循环。

(2)外层的while循环将大于m且紧靠m,即从m+1开始向后逐一判定,当个数j的值等于k时结束循环

题型四:在一维数组中按指定条件筛选

4、请编写函数fun,它的功能是: 求出 1 到 1000 之间能被 7 或11整除、但不能同时被 7 和 11 整除的所有整数并将它们放在a所指的数组中,通过 n 返回这些数的个数。

#include <stdio.h>

void  fun (int *a, int*n)

{

}

main( )

{  int aa[1000], n, k ;

   void

   fun ( aa, &n ) ;

   for ( k = 0 ; k < n; k++ )

      if((k + 1) % 10 ==0) printf("\n") ;

      elseprintf("%5d", aa[k]) ;

}

【参考答案】

void  fun (int *a, int*n)

{int i,j=0;

    for(i=1;i<=1000;i++)

   if((i%7==0||i%11==0)&&i%77!=0) /*指定的条件*/

        a[j++]=i; /*满足条件存放到数组后,j的值增1*/

    *n=j;         /*传回满足条件的数的个数*/

}

解题思路:将指定条件的数值“依次”追加到数组,在这个过程中追加元素的个数从0开始计算,因此变量j作为下标的初值设为0,存到数组后j增1,即现已找到的个数为1,同时1也是下一次待存入元素的下标,依次类推

(1)if语句,但是又不能同时被7和11整除的数,在这里充分理解"逻辑与"和"逻辑或"的区别;注意:(i%7==0||i%11==0)两边必须要有小括号

题型五:一维数组最值求解

5、请编写函数fun,其功能是求出数组的最大元素在数组中的下标并存放在k所指的存储单元中。

    例如, 输入如下整数: 876 675 896 101 301 401 980 431 451 777,则输出结果为: 6, 980

#include <stdio.h>

void fun(int *s, int t, int *k)

{

}

main( )

{

    inta[10]={876,675,896,101,301,401,980,431,451,777}, k ;void

    fun(a, 10, &k) ;

    printf("%d,%d\n", k, a[k]) ;

}

【参考答案】

void fun(int *s,int t,int *k)

{

   int i,n;

   n=0; /*假设第一个元素是最大值,n作为最大值的下标,初值为0*/

   for(i=1;i<t;i++) /*从第二个元素开始循环,依次比较*/

        if(s[n]<s[i]) n=i; /*找到数组的最大元素,把该元素的下标赋给n*/

   *k=n;  /*s[n]即为找到数组的最大元素,把n的值赋给k所指的数*/

}

【解题思路】求最值问题是数组应用的基本考核方式,具体方法:

(1)假设第一个元素为最大(小)值

(2)与之后的其他元素“依次”比较,若比假设值大(小),则将该值设为假设值,依次类推

题型六:一维数组排序

6、函数fun的功能是:用选择法对数组中的n个元素按从小到大的顺序进行排序。

 #include <stdio.h>

    #define N 20

    void fun(int a[],int n)

    {

    }

    void main()

    {int a[N]={9,6,8,3,-1},i,m=5;

     printf("排序前的数据:");

     for(i=0;i<m;i++) printf("%d",a[i]);

    printf("\n");

     fun(a,m);

     printf("排序后的顺序:");

     for(i=0;i<m;i++) printf("%d",a[i]);

    printf("\n");

    }

【参考答案】

void fun(int a[],int n)

{ int i,j,t;

     for(i=0;i<n;i++)

         for(j=i+1;j<n;j++)

            if(a[i]<a[j]) 

         {t=a[p];

 a[p]=a[j];

 a[j]=t; 

            }

}

【解题思路】 题中所提到的是"从小到大"的顺序。这类题可以利用选择法,即从后N个比较过程中,选择一个最小的与第一个元素交换,依此类推,即用第二个元素与后N-1个进行比较,并进行交换。该题与我们常见的C语言排序题类似,也是改错和编程题中的重点,请参看同类试题,以便达到举一反三的目的。

7、请编写函数fun,对长度为7个字符的字符串,除首、尾字符外,将其余5个字符按ASCII码值升序排列。

    例如,原来的字符串为Bdsihad,则排序后输出为Badhisd。

#include <stdio.h>

#include <string.h>

#include <ctype.h>

void fun(char *s, int num)

{

 

}

void main()

{char s[10];

 char b[10]="Bdsihad";

 printf("输入7个字符的字符串:");

 gets(s);

 fun(s,7);

 printf("\n%s",s);

}

【参考答案】

int fun(char *s, int num)

{  char t;

   int i, j;

    for(i=1;i<num-2;i++)  /*下标值从1开始,用循环依次取得字符串中的字符*/

        for(j=i+1;j<num-1;j++)   /*将字符与其后的每个字符比较*/

        if(s[i]>s[j])

   /*如果后面字符的ASCII码值小于该字符的ASCII码值*/

        {   t=s[i];/*则交换这两个字符*/

            s[i]=s[j];

            s[j]=t;

        }

}

【解题思路】本题考查利用循环来控制数组元素的操作,首尾元素除外,因此,数组的下标值要从1开始,用循环变量i来依次取得数组中的元素,用数组中的元素s[i]和s[j]进行比较,如果后一个元素的ASCII码值小于前一个元素的ASCII码值,则交换这两个数组元素的值。

题型七:元素平移问题

8、请编写函数fun, 函数的功能是: 移动一维数组中的内容; 若数组中有n个整数, 要求把下标从0到p(含p,p小于等于n-1)的数组元素平移到数组的最后。

    例如, 一维数组中的原始内容为: 1,2,3,4,5,6,7,8,9,10; p的值为3。移动后, 一维数组中的内容应为:5,6,7,8,9,10,1,2,3,4。

#include <stdio.h>

#define    N    80

void  fun(int  *w, int p, int  n)

{

}

main()

{  int  a[N]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

   int  i,p,n=15;void

   printf("Theoriginal data:\n");

   for(i=0; i<n;i++)printf("%3d",a[i]);

  printf("\n\nEnter  p:  ");scanf("%d",&p);

   fun(a,p,n);

   printf("\nThedata after moving:\n");

   for(i=0; i<n;i++)printf("%3d",a[i]);

  printf("\n\n");

}

【参考答案】

void fun(int *w, int p, int n)

{

   int i,j,t;

   for(i=0;i<=p;i++)

/*循环左移p+1次*/

   {

        t=w[0];          /*将0下标元素备份到t中*/

        for(j=1;j<n;j++) /*从1下标开始,后面所有元素循环左移*/

            w[j-1]=w[j];

        w[j-1]=t;       /*将t中原0下标元素存放到最后下标元素里*/

   }

}

【解题思路】本题采用"循环左移"的算法,即从第2个字符开始以后的每个字符都依次前移一个字符,而原来的第1个字符放在串中的最后一个字符。当要平移p个字符时,则要进行p次的循环左移。

题型八:数组去掉值重复的元素

9. 请编写函数fun,该函数的功能是:删去一维数组中所有相同的数,使之只剩一个。数组中的数已按由小到大的顺序排列,函数返回删除后数组中数据的个数。

例如:若一维数组中的数据是:2 2 2 3 4 4 5 6 6 6 6 7 7 8 9 9 10 10 10,删除后,数组中的内容应是:22 34 5 6 7 8 9 10

# include <stdio.h>

# define  N  80

int fun(int a[], int n)

{

 

}

main()

{

int a[N]={2,2,2,3,4,4,5,6,6,6,6,7,7,8,9,9,10,10,10,10}, i,n=20;

    printf("Theoriginal data :\n");

    for(i=0; i<n; i++)

        printf("%3d",a[i]);

    n=fun(a,n);

    printf("\nThedata after deleted :\n");

    for(i=0;i<n;i++)

        printf("%3d",a[i]);

}

【参考答案】

int fun(int a[], int n)

{

    int i,t,j=0,*p=a;

    t=p[0];

    for(i=0;i<=n;i++)

        if(t==p[i])

            ;

        else

        {

            a[j]=t;

            t=p[i];

            j++;

        }

    if(i>=n)

        a[j]=t;

    return j;

}

【解题思路】

由于数组是已经排好序的,相同的指定在一起,所以从前往后比,只要发现一个不和前面相同,后面就不再会有和前面相同的了。

题目中把准备保存下来的数存着t中,然后他后面的数顺序与他比较,如果不相等,那么就把这个数存起来,此时数组下标用另一个j来表示,只要出现不相等的情况,j才++,同时t换成这个和他不相等的新数。

提示:如果没排好序的我们可以先排序然后进行上面的操作。

题型九:数组元素的查找

10.请编写函数fun,函数的功能是查找x在s所指数组中下标的位置作为函数值返回,若x不存在,则返回-1。

#include  <stdio.h>

#include <stdlib.h>

#define   N   15

int  fun( int *s, int x)

{

 

}

main()

{  int a[N]={29,13,5,22,10,9,3,18,24,25,14,15,2,7,27},i,x,index;

   printf("a数组中的数据:\n");

   for(i=0;i<N;i++)printf("%4d",a[i]); printf("\n");

   printf("给x输入待查找的数:");  scanf("%d",&x);

   index=fun(a, x);

   printf("index=%d\n",index);

}

【参考答案】

int  fun( int *s, int x)

{

    int i;

    for(i = 0; i < N;i++)

      if(s[i] == x)

        return i;

    if(i == N)

      return -1;

}

【解题思路】

查找数组元素值为x的下标,只需要把数组的每个元素a[i](i从0到N-1)与x比较,如果相等则返回i的值,否则返回-1。

注意:改错中还有一个二分查找法需要掌握。

题型十:二维数组周边元素

11.下列程序定义了的二维数组,并在主函数中赋值。请编写函数fun,函数的功能是:求出数组周边元素的平均值并作为函数值返回给主函数中的s。例如,若a数组中的值为:

     0  1 2  7  9

     1  9 7  4  5

     2  3 8  3  1

     4  5 6  8  2

     5  9 1  4  1

     则返回主程序后s的值应为3.375。

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

#define  N  5

double fun (int w[][N])

{

 

}

void main()

{ inta[N][N]={0,1,2,7,9,1,9,7,4,5,2,3,8,3,1,4,5,6,8,2,5,9,1,4,1};

  int i, j;

  double s;

  printf("*****Thearray*****\n ");

  for (i=0; i<N; i++)

    { for(j=0;j<N;j++)

        {printf("%4d ",a[i][j]);}

      printf("\n");

    }

  s=fun(a);

  printf("*****THERESULT*****\n ");

  printf("The sum is: %lf\n ",s);

}

【参考答案】

double fun (int w[][N])

{

    int i,j,k=0;

    double av=0.0;

    for(i=0;i<N;i++)

       for(j=0;j<N;j++)

            if(i==0||i==N-1||j==0||j==N-1)

/*只要下标中有一个为0或N-1,则它一定是周边元素*/

    { av=av+w[i][j]; /*将周边元素求和*/

      k++;           /*周边元素个数k增1 */

    }

    return av/k; /*返回周边元素的平均值*/

}

【解题思路】

该题采用逐一判断的方式,周边元素的下标一定有一个是0或N-1,所以只要下标中有一个为0或N-1,那么它一定是周边元素。计算周边元素个数的方式是当给av加一个值时,k也加1,k也可用2*N+2*N-4求得。

题型十一:二维数组对角线、上三角和下三角元素的操作

12.程序定义了N×N的二维数组,并在主函数中自动赋值。请编写函数fun(int a[][N],int n),该函数的功能是:使数组左下半三角元素中的值乘以n。例如:或n的值为3,a数组中的值为

        1 9  7                                       

a=    2 3  8          

        4 5  6     

则返回主程序后a数组中的值应为:                                   

        3  9  7

a=    6 9  8

        12 15 18

#include <stdio.h>

#include <stdlib.h>

#define N 3

void  fun ( int a[][N],int n )

{

 

}

 

main()

{

    int a[N][N], i, j;

    printf("***** Thearray *****\n");

    for ( i=0; i<N;i++)

    {

        for(j=0; j<N;j++)

        {

            a[i][j]=rand()%10;

            printf("%4d",a[i][j]);

        }

        printf("\n");

    }

    fun (a,3);

    printf("***** THERESULT *****\n");

    for(i=0;i<N;i++)

    {

        for ( j=0; j<N;j++ )

            printf("%4d", a[i][j] );

        printf("\n");

    }

}

【参考答案】

void  fun ( int a[][N],int n )

{

    int i, j ;

    for(i=0 ; i<N ;i++)

        for(j=0 ; j<=i; j++)

            a[i][j]=a[i][j]*n;

}

【解题思路】

针对二维数组元素a[i][j],如果i>=j,也即行号大于等于列号时,是对角线下半三角的元素,相反i<=j,也即行号小于等于列号时,是对角线上半三角的元素,而i==j,即行号等于列号时,正好是对角线上的元素。

题型十二:二维数组转一维数组

13、请编写函数fun, 函数的功能是: 将M行N列的二维数组中的数据,按行的顺序依次放到一维数组中, 一维数组中数据的个数存放在形参n所指的存储单元中。

    例如, 二维数组中的数据为:

         33 33  33  33

         44 44  44  44

         55 55  55  55

    则一维数组中的内容应是:

    33 33  33  33 44  44  44 44  55  55 55  55。

#include <stdio.h>

void  fun(int  (*s)[10], int *b, int  *n, int mm, int nn)

{

}

main()

{ int w[10][10] ={{33,33,33,33},{44,44,44,44},{55,55,55,55}},i,j ;

  int a[100] = {0}, n = 0;void

  printf("Thematrix:\n") ;

  for(i = 0 ; i < 3 ;i++)

  { for(j = 0 ; j < 4; j++) printf("%3d",w[i][j]) ;

    printf("\n") ;

  }

  fun(w, a, &n, 3, 4);

  printf("The Aarray:\n") ;

  for(i = 0 ; i < n ;i++) printf("%3d",a[i]);printf("\n\n") ;

}

【参考答案】

void fun (int (*s)[10], int *b, int*n, int mm, int nn)

{  int i,j,k=0;

   for(i=0;i<mm;i++) /*将二维数组s中的数据按行的顺序依次放到一维数组b中*/

        for(j=0;j<nn;j++)

            b[k++]=s[i][j];

   *n=k; /*通过指针返回元素个数*/

}

【解题思路】我们可以用两个循环来处理问题,由于是按行的顺序取出,所以第1个循环用于控制行下标,第2个循环用于控制列下标;

若改成按列的顺序取出,则循环应改成:

for(i=0;i<nn;i++)

   for(j=0;j<mm;j++)

        b[k++]=s[j][i];

注意s[j][i]的下标,不能用s[i][j]。

题型十三:二维数组转置问题(即行列互换)

14、请编写函数fun, 函数的功能是:实现B=A+A',即把矩阵A加上A的转置, 存放在矩阵B中。计算结果在 main函数中输出。例如,输入下面的矩阵:      其转置矩阵为:

             1  2 3              1  4  7

             4  5 6              2  5  8

             7  8 9              3  6  9

    程序输出:

                        2   6  10

                        6  10  14

                       10  14  18

#include <stdio.h>

void  fun ( int a[3][3],int b[3][3])

{

}

main( )   /* 主程序 */

{  int a[3][3] = {{1, 2,3}, {4, 5, 6}, {7, 8, 9}}, t[3][3] ;

   int i, j ;

   void

   fun(a, t) ;

   for (i = 0 ; i < 3; i++) {

      for (j = 0 ; j <3 ; j++)

       printf("%7d", t[i][j]) ;

     printf("\n") ;

   }

}

【参考答案】

void fun (int a[3][3], int b[3][3])

{  int i,j;

   for(i=0;i<3;i++)

       for(j=0;j<3;j++)

            b[i][j]=a[i][j]+a[j][i];

/*把矩阵a加上a的转置,存放在矩阵b中*/

}

【解题思路】行列数相等的二维数组的转置就是行列互换,即转置后的第i行第j列正好对应原矩阵的第j行第i列。

(1)若要将矩阵a转置后还存入a中,可用程序:

int i,j,t;

for(i=0;i<N;i++)

   for(j=i;j<N;j++)

   {t=a[i][j];a[i][j]=a[j][i];

   a[j][i]=t;}

注意,第2个循环的初值。

(2)若要将矩阵a转置后存入c中:

int i,j;

for(i=0;i<N;i++)

   for(j=0;j<N;j++)

        c[i][j]=a[j][i];

注意,数组c和a的下标。

题型十四:数字字符串转整数

15、请编写一个函数fun,它的功能是:将一个数字字符串转换为一个整数(不得调用C语言提供的将字符串转换为整数的函数)。例如,若输入字符串"-1234",则函数把它转换为整数值 -1234。函数fun中给出的语句仅供参考。

#include <stdio.h>

#include <string.h>

long  fun ( char *p)

{

 

}

main()   /* 主函数 */

{ char s[6];void

  long    n;

  printf("Enter astring:\n") ;

  gets(s);

  n = fun(s);

 printf("%ld\n",n);

}

【参考答案】

long fun(char *p)

{

   long n=0;

   int flag=1;

   if(*p=='-')  /*负数时置flag为-1*/

   {p++;flag= -1;}

   else if(*p=='+')  /*正数时置flag为1*/

        p++;

   while(*p!='\0')

   {    n=n*10+*p-'0';/*将字符串转成相应的整数*/

        p++;

   }

   return n*flag;

}

【解题思路】if( )的作用是判断它应该是正数还是负数,变量t为1或-1作为符号标示。while( )循环的作用是将字符串转成相应的整数。

注意: p[i]的值是一个字符(如'9'、'4'),并不是一个数,要将其转成相应的数字必须令其减去'0'(不是'\0'),即*p-'0' 就得到*p这个字符的相应数字,如'0'-'0'=0、'8'-'0'=8等。

题型十五:“回文”字符串

16、请编写函数fun, 函数的功能是: 判断字符串是否为回文?若是, 函数返回1,主函数中输出: YES, 否则返回0, 主函数中输出NO。回文是指顺读和倒读都一样的字符串。

    例如, 字符串LEVEL是回文, 而字符串123312就不是回文。

#include <stdio.h>

#include <string.h>

#define  N  80

int fun(char *str)

{

}

main()

{ char  s[N] ;void

  printf("Enter astring: ") ; gets(s) ;

 printf("\n\n") ; puts(s) ;

  if(fun(s))printf("  YES\n") ;

  else       printf("  NO\n") ;

}

【参考答案】

int fun(char *str)

{  int i,n=0,fg=1;

   char *p=str;

   n=strlen(str);

   for(i=0;i<n/2;i++)          /*循环比较字符*/

        if(str[i]==str[n-1-i]); /*相同,什么都不作*/

        else                    /*不同,直接跳出循环*/

        {  fg=0;

            break;

        }

   return fg;

}

题型十六:字符串统计问题

17、请编写一个函数 void fun(char  *tt, int pp[]),统计在tt所指字符串中'a' 到 'z' 26个小写字母各自出现的次数,并依次放在pp所指数组中。

    例如,当输入字符串:abcdefgabcdeabc 后,程序的输出结果应该是:

     3 3 3 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0

#include <stdio.h>

#include <string.h>

void fun(char *tt, int pp[])

{

}

main( )

{  char aa[1000] ;

   int  bb[26], k ;

   void

   printf( "\nPleaseenter  a char string:" ) ;scanf("%s", aa) ;

   fun(aa, bb ) ;

   for ( k = 0 ; k <26 ; k++ ) printf ("%d ", bb[k]) ;

   printf( "\n") ;

}

【参考答案】

void fun(char *tt, int pp[])

{   int i;

    for(i=0;i<26;i++)

        pp[i]=0; /*初始化pp所指数组,使其所有值均为0*/

    for(i=0;tt[i];i++)  /*控制条件也可是tt[i]!=‘\0’或tt[i]!=0  */

        pp[tt[i]-‘a’]++; /*tt[i]-‘a’ 的值,即为字符tt[i]的个数存放在pp所指数组中对应的下标*/

}

【解题思路】26个字母的个数在pp所指数组中为0-25,其中数组下标可以通过某一个字符的ASCII值减去97或直接减'a'也可以,就可以得出该字符出现次数存放的位置。例如:字符为b,那么位置为'b'-'a'=1,就是实际存放的位置。

18. 编写一个函数,该函数可以统计一个长度为2的字符串在另一个字符串中出现的次数。

例如,假定输入的字符串为:asd asasdfg asd as zx67 asd mklo,子字符串为as,则应输出6。

#include <stdio.h>

#include <string.h>

int fun(char *str,char *substr)

{

 

}

main()

{

    charstr[81],substr[3];

    int n;

    printf("输入主字符串:");

    gets(str);

    printf("输入子字符串:");

    gets(substr);

    puts(str);

    puts(substr);

    n=fun(str,substr);

    printf("n=%d\n",n);

}

【参考答案】

int fun(char *str,char *substr)

{

    intn;

    char*p , *r;

   n=0;

    while( *str )

    {

        p=str;

        r=substr;

        while(*r)

            if(*r==*p)

            {

                r++;

                p++; 

            }

            else

                break;

            if(*r=='\0')

                n++;

            str++;

    }

    returnn;

}

【解题思路】

主字符串从第一个字符开始,不断循环直到结束,在循环中让指针p指向主字符串的当前位置,而指针r每次都重新指向子字符串的首地址,比较p和r指向的值是否相等,如果相等,需要比较后面的是否还相等,故p和r同时++指向后面一个字符,如果到r指向的值为’\0’前面都相等,那么说明找到一个,n+1;如果其中出现不相等的情况,则进入下一次外层循环,主字符串从下一个字符开始重新比较。

19.请编写函数fun,该函数的功能是:统计一行字符串中单词的个数,作为函数值返回。一行字符串在主函数中输入,规定所有单词由小写字母组成,单词之间由若干个空格隔开,一行的开始和结束都没有空格。

#include <stdio.h>

#include <string.h>

#define  N  80

int fun(char *s)

{

   

}

main()

{

    char  line[N];  

    int  num=0;

    printf("Entera string :\n");

    gets(line);

    num=fun(line);

    printf("Thenumber of word is : %d\n\n",num);  

}

【参考答案】

int fun(char *s)

{

    inti,n=0;

    for(i=0;i<strlen(s);i++)

    {

        if(s[i]>='a'&&s[i]<='z'&&s[i+1]==''||s[i+1]=='\0')

            n++;

    }

    return n;

}

【解题思路】

单词以空格隔开,加上最后一个单词是字符串的结尾,所以只需要判断当前的下一个字符是不是空格或者’\0’,如果是说明前面是一个单词。

题型十七:字符串指定字符删除

20、假定输入的字符串中只包含字母和*号。请编写函数fun,它的功能是:删除字符串中所有的*号。在编写函数时,不得使用C语言提供的字符串函数。

    例如,字符串中的内容为:****A*BC*DEF*G*******,删除后,字符串中的内容应当是:ABCDEFG。

#include <stdio.h>

void  fun( char *a )

{

}

main()

{  char  s[81];

   void

   printf("Enter astring:\n");gets(s);

   fun( s );

   printf("Thestring after deleted:\n");puts(s);

}

【参考答案】

void fun(char *a)

{  int i,j=0;

   for(i=0;a[i]!='\0';i++)

        if(a[i]!='*')

            a[j++]=a[i]; /*若不是要删除的字符'*'则留下*/

   a[j]='\0';/*最后加上字符串结束符'\0'*/

}

【解题思路】(1)本题中是删除全部字符('*'),所以用循环从字符串的开始往后逐个进行比较,若不是要删除的字符(用if(a[i]!='*')来控制)则保留。注意在保存的时候,下标变量j要从0开始,最后还要加上字符串结束符'\0'。

(2)此类题可以多种形式出现,以字符串中第一个字母和最后一个字母为坐标,如:只删除前导*,只删除后面所有*,只删除中间部分的*等等。通用的方法是如何定位第一个字母和最后一个字母,以它们作为起始点,通过循环追加来完成。

21、假定输入的字符串中只包含字母和*号。请编写函数fun,它的功能是:使字符串中尾部的*号不得多于n个;若多于n个,则删除多余的*号;若少于或等于n个,则什么也不做, 字符串中间和前面的*号不删除。

    例如,字符串中的内容为:****A*BC*DEF*G*******,若n的值为4,删除后,字符串中的内容应当是:****A*BC*DEF*G****;若n的值为7,则字符串中的内容仍为:****A*BC*DEF*G*******。n的值在主函数中输入。在编写函数时,不得使用C语言提供的字符串函数。

#include <stdio.h>

void  fun( char*a,int  n )

{

}

main()

{  char  s[81]; int  n;

   void

   printf("Enter astring:\n");gets(s);

   printf("Enter n:  ");scanf("%d",&n);

   fun( s,n );

   printf("Thestring after deleted:\n");puts(s);

}

【参考答案】

void fun(char *a,int n )

{  int i=0, k=0;

   char *p, *t;

   p=t=a;         /*开始时,p与t同时指向数组的首地址*/

   while(*t=='*') /*用k来统计前部星号的个数*/

      {k++;t++;}

    if(k>n)      /*如果k大于n,则使p的前部保留n个*,其后的字符依次存入数组a中*/

   { while(*p)

        {a[i]=*(p+k-n);

            i++;

            p++;

        }

        a[i]='\0'; /*在字符串最后加上结束标志位*/

   }

}

【解题思路】(1)while()循环的作用是计算出字符串中前部星号的个数;

(2)if( )的作用是判断*号个数是否大于n个,若是则只保留n个星号,即从字符串前部的倒数第n个星号到最后一个字符都存入数组a中,最后记得在字符串末尾加上结束标志位。

题型十八:字符串数组最值

22.编写一个函数,从传入的num个字符串中找出最长的一个字符串,传回该串地址(用****作为结束标志)。

#include <stdio.h>

#include <string.h>

char *fun(char (*a)[81],int num)

{

   

}

main()

{

   char ss[10][81],*max;

   int n,i=0;

   printf("输入若干个字符串:");

   gets(ss[i]);

   puts(ss[i]);

   while(!strcmp(ss[i],"****")==0)

   {

        i++;

        gets(ss[i]);

        puts(ss[i]);

   }

   n=i;

   max=fun(ss,n);

   printf("\nmax=%s\n",max);

}

【参考答案】

char *fun(char (*a)[81],int num)

{

    inti;

    char*max;

    max=a[0];

    for(i=0;i<num;i++)

        if(strlen(max)<strlen(a[i]))

            max=a[i];

    returnmax;

}

【解题思路】

思路同一位数组求最值,先把第一个字符串当成要的最值,然后拿其他的和他进行比较,此处strlen是求字符串的长度,所以最后求出的是字符最长的字符串,如果用strcmp可以去比较字符串的大小。同样用这样的方法可以考虑字符串的排序。方法同一维数组。

题型十九:字符串逆置

23. 请编写一个函数fun(char *s),该函数的功能是把字符串中的内容逆置。

例如:字符串中原有的字符为abcdefg,则调用该函数后,串中的内容为gfedcba。

#include<string.h>

#include<stdio.h>

#define  N  81

voidfun ( char *s)

{  

 

}

main()

{

    char a[N];

    printf ( "Enter  a string :  ");

    gets ( a );

    printf ( "The original string is:" );

    puts( a );

    fun ( a );

    printf("\n");

    printf ( "The string after modified :");

    puts ( a );

}

【参考答案】

void fun ( char *s)

{  

    charch;

    inti,m,n;

    i=0;

    m=n=strlen(s)-1;

    while(i<(n+1)/2)

    {

        ch=s[i];

        s[i]=s[m];

        s[m]=ch;

        i++;

        m--;

    }

}

【解题思路】

要把字符串逆置其实就是以中间元素为对称轴对调,只需要将第一个字符和最后一个字符交换,第二个字符和倒数第二个字符交换,以此类推,所以题目中将s[i]和s[m]交换,i是从0到整个长度的一半,m是从整个字符串的长度到整个长度的一半。

注意:这个循环的次数一定要限制为整个字符串长度的一半,如果为字符串的长度那么相当于掉了两次,最后又回到刚开始的情况。

题型二十:字符串的连接

24. 编写一个函数fun,它的功能是:实现两个字符串的连接(不使用库函数strcat),即把p2所指的字符串连接到p1所指的字符串后。

    例如,分别输入下面两个字符串:

            FirstString--

            SecondString

    程序输出:

            FirstString--SecondString

#include <stdio.h>

void fun(char p1[], char p2[])

{

   

}

main()

{    char s1[80], s2[40];

     printf("Enters1 and s2:\n") ;

    scanf("%s%s", s1, s2) ;

    printf("s1=%s\n", s1) ;

    printf("s2=%s\n", s2) ;

     fun(s1, s2) ;

     printf("Afterinvoking:\n") ;

    printf("%s\n", s1) ;

}

【参考答案】

void fun(char p1[], char p2[])

{

    char *p,*q;

    p=p1;

    q=p2;

    while(*p) p++;

    while(*q) *p++=*q++;

    *p='\0';

}

【解题思路】

(1) 让指针p指向第一个字符串的最后,即’\0’的位置;

(2) 将第二个字符串的各个字符依次加在后面;

(3) 最后在加上’\0’代表字符串结束。

题型二十一:结构体数组求最值

25、学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,它的功能是:把分数最高的学生数据放在b所指的数组中,注意:分数最高的学生可能不止一个,函数返回分数最高的学生的人数。

#include <stdio.h>

#define   N   16

typedef  struct

{  char  num[10];

   int   s;

} STREC;

int  fun( STREC  *a, STREC *b )

{

}

main()

{  STREC s[N]={{"GA05",85},{"GA03",76},{"GA02",69},{"GA04",85},

        {"GA01",91},{"GA07",72},{"GA08",64},{"GA06",87},

        {"GA015",85},{"GA013",91},{"GA012",64},{"GA014",91},

        {"GA011",77},{"GA017",64},{"GA018",64},{"GA016",72}};

   STREC  h[N];

   int  i,n;FILE *out ;

   n=fun( s,h );

   printf("The %dhighest score :\n",n);

   for(i=0;i<n; i++)

     printf("%s  %4d\n",h[i].num,h[i].s);

  printf("\n");

   out =fopen("c:\\test\\out.dat","w") ;

   fprintf(out,"%d\n",n);

   for(i=0;i<n; i++)

     fprintf(out,"%4d\n",h[i].s);

   fclose(out);

}

【参考答案】

int fun (STREC *a, STREC *b)

{

   int i,j=0,max=a[0].s;

   for(i=0;i<N;i++)

        if(max<a[i].s)

            max=a[i].s;/*找出最大值*/

   for(i=0;i<N;i++)

        if(max==a[i].s) b[j++]=a[i]; /*找出成绩与max相等的学生的记录,存入结构体b中*/

   return j; /*返回最高成绩的学生人数*/

}

【解题思路】(1)对于如何找出数组中最大值的操作,前面涉及过,对结构体数组进行类似操作也可采用同样方法。

(2)第1个for语句的作用是找出最大值;第2个循环的作用是找出与max相等的成绩(即最高成绩)的学生记录,并存入b中。对于结构体类型的数组来说,每个元素均由两个成员组成,其中s是成绩,因此我们只需要对其中成绩成员s进行访问,如a[i].s

题型二十二:结构体数组排序

     26、学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun,它的功能是:按分数的高低排列学生的记录,高分在前。

#include <stdio.h>

#define   N   16

typedef  struct

{  char  num[10];

   int   s;

} STREC;

void  fun( STREC  a[] )

{

}

main()

{  STREC s[N]={{"GA005",85},{"GA003",76},{"GA002",69},{"GA004",85},

        {"GA001",91},{"GA007",72},{"GA008",64},{"GA006",87},

        {"GA015",85},{"GA013",91},{"GA012",64},{"GA014",91},

        {"GA011",66},{"GA017",64},{"GA018",64},{"GA016",72}};

   int  i;FILE *out ;

   fun( s );

   printf("The dataafter sorted :\n");

   for(i=0;i<N; i++)

   {  if( (i)%4==0 )printf("\n");

     printf("%s  %4d  ",s[i].num,s[i].s);

   }

  printf("\n");

   out =fopen("c:\\test\\out.dat","w") ;

   for(i=0;i<N; i++)

   {  if( (i)%4==0 && i) fprintf(out,"\n");

      fprintf(out,"%4d  ",s[i].s);

   }

  fprintf(out,"\n");

   fclose(out) ;

}

【参考答案】

int fun (STREC a[])

{ int i,j;

   STREC t;

   for(i=0;i<N-1;i++)

     for(j=1;j<N;j++)

       if(a[i].s<a[j].s)

         {  t=a[i]; /*按分数的高低排列学生的记录,高分在前*/

a[i]=a[j];

a[j]=t;

}

}

题型二十三:链表

27、N名学生的成绩已在主函数中放入一个带头节点的链表结构中,h指向链表的头节点。请编写函数fun,它的功能是:求出平均分,由函数值返回。

    例如,若学生的成绩是:85,76,69,85,91,72,64,87, 则平均分应当是:78.625。

#include <stdio.h>

#include <stdlib.h>

#define   N   8

struct  slist

{  double   s;

   struct slist  *next;

};

typedef  structslist  STREC;

double  fun( STREC*h  )

{

}

STREC * creat( double *s) /*建立带有头结点的单向链表*/

{ STREC  *h,*p,*q;   int i=0;

 h=p=(STREC*)malloc(sizeof(STREC));p->s=0;

  while(i<N)

  {q=(STREC*)malloc(sizeof(STREC));

    q->s=s[i];i++;  p->next=q; p=q;

  }

  p->next=0;

  return  h;

}

outlist( STREC *h)

{ STREC  *p;

  p=h->next;printf("head");

  do /*该循环顺序访问各节点数据域的值,输出各成绩*/

  { printf("->%4.1f",p->s);

p=p->next;

} while(p!=0);

 printf("\n\n");

}

main()

{  double  s[N]={85,76,69,85,91,72,64,87},ave;

   void

   STREC  *h;

   h=creat( s );   outlist(h);

   ave=fun( h );

   printf("ave= %6.3f\n",ave);

}

【参考答案】

double fun(STREC *h)

{  double av=0.0;

   STREC *p=h->next;

/*p直接指向"头节点"的下一个节点,即第一个成绩*/

   while(p!=NULL)

   {av=av+p->s; /*求总分数*/

        p=p->next;

   }

   return av/N; /*返回平均值*/

}

【解题思路】(1)本题是考查链表问题,所以,一定要弄清表示初始指针变量p指向下一个"节点"的方法及表示结束的判断。

(2)因为"头结点"中没有数值,所以程序中让p直接指向"头节点"的下一个节点,使用语句STREC *p=h->next,当然也可将p一开始指向"头节点",即STREC*p=h,然后再p=p->next。

题型二十四:Fibonacci数列

28. 编写函数fun,它的功能是:求Fibonacci数列中大于t的最小的一个数,结果由函数返回。其中Fibonacci数列F(n)的定义为:

         F(0)=0,F(1)=1

         F(n)=F(n-1)+F(n-2)

    例如:当t = 1000时,函数值为:1597。

#include <math.h>

#include <stdio.h>

int  fun( int  t)

{

}

main()   /* 主函数 */

{  int  n;

   void

   n=1000;

   printf("n = %d, f= %d\n",n, fun(n));

}

【参考答案】

int  fun( int  t)

{

    int a=1,b=1,c=0,i;

    for(i=4;i<=t;i++)

    {

        if(c<t)

        {

            c=a+b;

            a=b;

            b=c;

        }

        else

            break;

    }

    return c;

}

【解题思路】

当前项等于前面两项之和,然后把前面的第二项改为当前的前面第一项,把当前项改为前面的第二项。如此循环。

提示:用递归写是不是更简单更好理解。

int  fun( int  t)

{

    if(t==1)  return 1;

    else if(t==0) return0;

    else returnfun(t-1)+fun(t-2);

}

 

阅读更多

没有更多推荐了,返回首页