家们网!                                                   鼎誉推广助手 长沙网站制作 长沙营销型网站建设 长沙成交型网站建设 更多友情
  •  
     
      三级网络技术和三级数据库技术的C语言上机试题难度较大,题型多样,因此颇难掌握,今将这些试题分类解析,希望能帮大家顺利通过上机考试。

      三级的上机题可以分为十几个类型,每类中的题目数量不一,多则十几道题,少则三四道题,但是每类题都差不多,每类中只要掌握一道题,再理清做题的思路,那就相当于全掌握了。

      好了,今天现看几个题目比较多得类型。

      第一类:关于f(p)=p*11 mod 256字符变换的题型,一般这类题的题目说明如下

      函数ReadDat()实现从文件ENG.IN中读取一篇英文文章,存入到字符串数组xx中;请编制函数encryptChar(),按给定的替代关系对数组xx中的所有字符进行替代,仍存入数组xx的对应的位置上,最后调用函数WriteDat()把结果xx输出到文件PS10.DAT中。

      替代关系:f(p)=p*11 mod 256 (p是数组中某一个字符的ASCII值,f(p)是计算后新字符的ASCII值[U][I]),如果原字符的ASCII值是偶数或计算后f(p)值小于等于32,则该字符不变,否则将f(p)所对应的字符进行替代[/I][/U]。

      void encryptChar()

      {

      int i,j;

      unsigned char fp;

      for(i=0;i

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

      {

      fp=xx[i][j]*11 % 256 ;

      if(!(xx[i][j]%2==0||fp<=32))

      xx[i][j]=fp;

      }

      }

      题解:这类题比较简单,每道题的不同之处在于,要替换的字符的条件不一样,但条件中总会说“如果该字符符合什么条件,字符就不变,否则就替换。”解决这个问题最省事的办法就是把不变的条件写好,前面加上逻辑非,如 (!(xx[i][j]%2==0||fp<=32)) 。

      另一个要注意的问题是把改变后的字符要临时存放在一个变量中,这个变量,如本题中的fp,必须是unsigned char 类型或int类型的变量,若写成char类型的会出错,因为从公式 fp=xx[i][j]*11 % 256 ;中可以看出fp的取值范围应在0~255之间,而char类型的变量范围仅在-128~+127之间。

      在本题中用两重循环遍历字符串数组,外层循环遍历行,maxline中存放的是xx数组中存放字符串的真实的行数;外层循环遍历每行的每个字符,因为在xx中每行是一个字符串,而每个字符串都有一个‘\0'做结束标致,所以内层循环的表达式2用xx[i][j]!='\0'来控制循环。

      第3题:

      函数readDat()的功能是实现从文件IN.DAT中读取一篇英文文章

      存入到字符串数组xx中;请编写函数StrOR(),该函数的功能是:以

      行为单位把字符串中的所有小写字母o左边的字符串内容移到该字符

      串的右边存放,然后并把小写字母o删除,余下的字符串内容移到已

      处理字符串的左边存放.最后把已处理的字符串仍按行重新存入字符

      串数组xx中,最后调用函数WriteDat()把结果xx输出到文件OUT.DAT

      中。

      例如:原文:You can create an index on any field.

       You have the correct record.

      结果:n any field. Yu can create an index

      rd. yu have the crrect rec

      原始数据文件存放的格式是:每行的宽度均小于80个字符,含标

      点符号和空格。

      注意:部份源程序已在程序PROG1.C中给出。

      请勿改动主函数main()、读函数readDat()和写函数writeDat()

      的内容。

      解题:本题如果用标准算法实难解释清楚,这里完全用字符串处理函数来做,涉及到的函数有:

      (1) char *strchr(char *s,char ch);——从S所指向的字符串中找到打一个ch代表的字符,返回该字符的指针,若找不到返回空指针NULL。

      (2)void memset(char *s ,char ch,unsigned count);——将S所指向的数组的前count个字符全部赋于ch所代表的字符,如果ch为‘\0’,count为字符数组的长度,则代表清空数组。

      (3)void memcpy(char *s1,char *s2,unsigned count);——将S2字符串的前count个字符拷贝到S1所代表的字符串中。

      关于strcpy()和strcat()两个函数就不用说了吧!

      好,程序的源码如下:

      void Str0R(void)

      {

      int i; /*用来遍历行 */

      char *p,t[100];/*p用来指向字符'o',t用来临时存放待处理的字符串中'o'前面的串*/

      for(i=0;i

      {

      p=strchr(xx[i],'o'); /* 找找看,有没有字符'o',有的话让p指向它,若没有返回NULL*/

      while(p!=NULL)/*根据以上的P值是否为空,判断是否有'o'字符,有的话做下面处理*/

      {

      memset(t,'\0',100); /* 清空数组t*/

      memcpy(t,xx[i],p-xx[i]); /*将'o'前面的字符形成一个串拷贝到t中,临时存放 */

      strcpy(xx[i],p+1); /* 删除'o'连同'o'前面的字符串*/

      strcat(xx[i],t); /*将原'o'前面的字符串连接到处理后的字符串的末尾,到次已经处理玩

      了一个字符'o' */

      p=strchr(xx[i],'o'); /* 寻找下一个字符'o'*/

      }

      }

      }

      再看一道类型题,本题共出现十道题,题目说明很相似,只是排序的条件不同,所以这种题代码非常规则,我们全部用冒泡法排序,只改以下排序的条件即可。我们把这类题称为“按金额、代码排序的题”。

      例如:

      已知在文件IN.DAT中存有100个产品销售记录,每个产品销售记录由产品代码dm(字符型4位)、产品名称mc(字符型10位)、单价dj(整型)、数量sl(整型)、金额je(长整型)几部份组成。其中:金额=单价×数量可计算得出。函数ReadDat()的功能是读取这100个销售记录并存入结构数组sell中。请编制函数SortDat(),其功能要求:按产品名称从小到大进行排列,若产品名称相同,则按金额从大到小进行排列,最终排列结果仍存入结构数组sell中,最后调用函数WriteDat()把结果输出到文件OUT.DAT中。

      注意:部份源程序已在程序PROG1.C中给出。

      请勿改动主函数main()、读函数readDat()和写函数writeDat()的内容。

      typedef struct{

      ??char dm[5]; /*产品代码*/

      ??char mc[11]; /*产品名称*/

      ??int dj; /*单价*/

      ??int sl; /*数量*/

      ??long je; /*金额*/

      ??}PRO;

      ??PRO sell[MAX];

      解题:这类题一律用冒泡法排序,但要注意(1)冒泡法排序要使用交换变量,这里的交换变量类型应和被排序的数组的类型一致,本类题中应使用结构体类型的变量。(2)本题中的产品名称和产品代码都为字符串,对其进行比较时,应使用strcmp函数。(3)本类题的排序都是用两个关键字排序的,分为第一关键字(如上题中的“产品名称”)和第二关键字(如上题中的“金额”),这种排序都是先按第一关键字排序,如果第一关键字相同,再按第二关键字排序,这时即可以写成两个排序过程,也可以写在一起,我们为了简略,把两个排序写成一个排序过程,不过这时排序的条件稍有写复杂,应该注意。

      (4)排序条件由两部分构成,请注意看代码中的括号。

      (5)题目说明中斜体部分就是本类题经常变化的地方。

      好了,排序的代码如下:

      void SortDat()

      {int i,j;

      PRO t;

      for(i=0;i<100;i++) /* 这里的100也可以写成MAX */

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

      if( strcmp(sell[i].mc,sell[j].mc)>0||( strcmp(sell[i].mc,sell[j].mc)==0&&sell[i].je

      {t=sell[i];sell[i]=sell[j];sell[j]=t;} /* 交换sell[i]和sell[j] */

      }

      好了,再说一道难一些的题,本题是100道题中的第57题,俗称“猴子选王”的题,但“猴子选王”注重于结果,即最后出圈的是谁,而这道题注重于过程,即要将出圈的顺序放在一个指定的数组中。虽然要点不同,但编程的思路和方法确是相同的。

      本题的说明如下:

      设有n个人围坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数,报数到第m个人,此人出圈,再从他的下一个人重新开始1到m的报数,如此进行下去直到所有的人都出圈为止。现要求出圈次序,每10人为一组,给出这n个人的顺序表。请编制函数Josegh()实现此功能并调用函数Writedat()把编号按照出圈的顺序输出到文件OUT.DAT中。

      设n=100,s=1,m=10进行编程。

      注意:部份源程序已在程序PROG1.C中给出。

      请勿改动主函数main()和输出数据函数WriteDat()的内容。

      题目解析:

      void Josegh(void)

      {

      int t[100], /*t用来存放100个人的编号 */

      i, /*用来遍历t数组中的编号,真正遍历的时候是用 i%n 做下标的*/

      j, /*j用来计数,它从0开始,数到m后,又重新从0开始*/

      k=0; /*用来负责向存放出圈顺序的数组p中放数,它用 k++ 做p的下标*/

      for(i=0;i

      for(i=s-1,j=0;k

      所以从0开始,k

      的人已经全部出圈,所以程序结束。*/

      { if(t[i%n]!=-1) j++; /*如果数组t中的第(i%n)个元素不为-1,说明这里有人,应让j计数*/

      if(j==m) /*如果j数到了m,说明有一个人应该出圈*/

      {

      p[k++]=t[i%n];/*把出圈人的顺序号写入p数组*/

      t[i%n]=-1;/*出圈一个人,就把它的位置上放上-1,以标志该处没人,不能数数,应该跳过去*/

      j=0;/*j已经数到m了,应该从0重新计数*/

      }

      }

      }

      注:(1)t数组的下标之所以用 (i%n)是为了让 i 循环指向数组的下标,因为i在一直增大,而(i%n)的变化范围是0->1->2.....->98->99->0->1....->98->99.......... i总是在这样变化,所以能一遍一遍的循环引用t数组的元素。

      一般C语言中的结构,如for、if、while、do...while等都只能控制一条语句,如果逆向让他们控制多条语句,就必须把这多条语句用{}扩起来。至于什么时候控制多条语句,那得看题目而定了,没有规则。

      例如:if(a>b) t=a;a=b;b=t;

      这看起来好像是说:如果a大于b为真,则交换a和b得值,但不是,这时if结构只能控制t=a;这条语句。可以对比下一个结构:if(a>b) {t=a;a=b;b=t;} 这里就不一样了,这里得if结构控制得是复合语句{t=a;a=b;b=t;} ,相当于控制了三条语句。

      再如:int i=0,sum=0;

      while(i<=100)

      sum+=i;

      i++;

      printf("%d",sum);

      请问这个程序打印得结果是什么? 答案是:死循环,不会打印出结果。

      因为这时while只控制了sum+=i;这条语句,而i++;不受它控制,所以循环的过程中i不变,时钟为0,因此条件永远为真。

      可以对比如下的程序:

      int i=0,sum=0;

      while(i<=100)

      { sum+=i;

      i++;

      }

      printf("%d",sum);

      输出结果是:5050

     
    ......
    本文标签: 计算机等级考试 
  • 招考