2004年真题

二、

6、

 1 #include <iostream>
 2 
 3 #include<stdio.h>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 #include<math.h>
 7 #define SLEN 20
 8 #define M 50
 9 #define N 20
10 #define LEN 12
11 
12 void f(int i,char *cp){
13     for(;i;i--)
14         printf("%c",*cp++);
15 }
16 
17 
18 int main(){
19    char a[][4]={"ABC","DEF","GH"};
20    char *p;
21    p=a[0];
22    f(1,p++);
23    f(1,p++);
24    f(1,p++);
25    printf("\n");
26    p=a[1];
27    f(3,p++);
28    f(2,p++);
29    f(1,p);
30    printf("\n");
31    printf("%s\n",a[0]);
32     return 0;
33 }

运行结果:

 

 这道题也向我们清晰的展示了所谓的形参为指针时,不一定能使得实参改变。

上面在main函数中执行f(1,p++)时,p传递的是p指针所存储的地址值给cp,而函数在执行时是不断的动用cp指针,而指针p除了p++这一次动了,就没动了。

想让p跟着cp变也可以,只要传递指针p所在的空间大的地址值,但是cp应该改为二级指针。

如下:

 

 

 注意在f()函数中一定是*(*cp)++,括号一定不能少,这是由符号的优先级和结合方向所决定的

首先由于cp是二级指针则心中要明白  *cp<=>p

其次由于*运算符和++运算符是同级的,但是结合方向是自右向左的。

比如:*p++<=>p++ 这个是先运算后加一 所以p++得到表达式的值为p,再*表达式的值即*p.最后再p++;

因此同理为*(*cp)++;

如果不加()写成**cp++,先**cp这个没有错,但是cp加一就不对了!因为cp指向的是p指针,cp再加一,它最后指向的内容就不知道是个啥东西了,可以试试。

 

 至于为啥cp变了,但是p没跟着变?前面我已经说了(*cp)才与p等价,而不是cp,此时变得是cp,即cp已经不指向p了!

四、

1、程序功能为4个字符串中求最大字符串并输出结果

若是还不懂看:https://www.cnblogs.com/industrial-fd-2019/p/14021383.html

对于char *s[]={"boy","girl","mother","father"};这种定义里的字符串一定不能改变其中的任何字母

因为它等价于 char *(s+i)="dakhfkah";

char *s="boy",*s1="girl",*s2="mother",*s3="father".

也就是上面所说的char const *str。指针可以指向其他地方,但是指针所指的字符串字母不能够改变

例如:

 

 不能strcpy(*st,s[1])!!!!理由上面已经说了

一下程序功能:在4个字符串中求最大字符串并输出结果

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include<string.h>
 4 int main()
 5 {
 6     char *s[]={"boy","girl","mother","father"};
 7     char **st;
 8     int i;
 9     st=s;
10     for(i=1;i<4;i++)
11         if(strcmp(*st,s[i])<0)
12             *st=s[i];
13     printf("%s\n",*st);
14     return 0;
15 }

运行结果如下:

 

 至于为啥是mother,很简单因为mother的第一个字母'm'的ASCII都比其他几个字符串的第一个字母的ASCII大。

 四、

2、

10个学生5门课,下面的程序从文件f1. dat读入所有学生的各课成绩,计算出每个学生的总分,并按总分降序的次序将每个学生名次、各课得分及总分输出到文件f2. dat。
提示:为了避免排序时可能要交换s[i][k]和s[j][k],程序另引进数组ord[],改上述交换为ord[i]和ord[j]的交换。

 

由于打开二进制文件是一堆乱码,所以我先用文本文件模式打开进行读写操作。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int s[10][7];
 4 
 5 int main()
 6 {
 7     int i,j,sum,order[10],t;
 8     FILE *fp;
 9 
10     if((fp=fopen("f1.dat","r"))==NULL){
11         printf("Can't open file %s\n","f1.dat");
12         exit(1);
13     }
14 
15     for(i=0;i<10;i++){
16         for(j=0;j<=5;j++)
17             fscanf(fp,"%d",&s[i][j]);
18         sum=0;
19         for(j=1;j<=5;j++)
20             sum+=s[i][j];
21         s[i][6]=sum;
22         order[i]=i;
23     }
24 
25     for(i=0;i<9;i++){
26         for(j=i+1;j<9;j++){//选择排序法
27             if(s[order[i]][6]<s[order[j]][6]){
28                 t=order[i];
29                 order[i]=order[j];
30                 order[j]=t;
31             }
32         }
33     }
34 
35     fp=fopen("f2.dat","w");
36 
37     for(i=0;i<10;i++){
38         s[order[i]][0]=i+1;
39         for(j=0;j<7;j++)
40             fprintf(fp,"%d ",s[order[i]][j]);
41         fprintf(fp,"\n");
42     }
43     printf("Finished!\n");
44     fclose(fp);
45     return 0;
46 }

运行结果如下:

 

 

 

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int s[10][7];
 4 
 5 int main()
 6 {
 7     int i,j,sum,order[10],t;
 8     FILE *fp;
 9 
10     if((fp=fopen("f1.dat","rb"))==NULL){
11         printf("Can't open file %s\n","f1.dat");
12         exit(1);
13     }
14 
15     for(i=0;i<10;i++){
16         fread(s[i],sizeof(int),6,fp);
17         sum=0;
18         for(j=1;j<=5;j++)
19             sum+=s[i][j];
20         s[i][6]=sum;
21         order[i]=i;
22     }
23 
24     for(i=0;i<9;i++){
25         for(j=i+1;j<9;j++){//选择排序法
26             if(s[order[i]][6]<s[order[j]][6]){
27                 t=order[i];
28                 order[i]=order[j];
29                 order[j]=t;
30             }
31         }
32     }
33 
34     fp=fopen("f2.dat","wb");
35 
36     for(i=0;i<10;i++){
37         s[order[i]][j]=i+1;
38         fwrite(s[order[i]],sizeof(int),7,fp);
39     }
40     printf("Finished!\n");
41     fclose(fp);
42     return 0;
43 }

 五、编程序


1.编程序实现单链表的起泡排序。
要求:

(1) 结点的数据域只有一个整数域;
(2)N个结点的整数链表的建立过程,写一函数(create)
实现,数据从键盘输入。

//实现方法:结点不动,只交换数据域

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 typedef struct Lnode{
 5     int data;
 6     struct node *next;
 7 }LNODELIST;
 8 
 9 LNODELIST *create(int n){
10     LNODELIST *h=NULL,*q;
11     while(n--){
12         q=(LNODELIST *)malloc(sizeof(LNODELIST));
13         scanf("%d",&q->data);
14         q->next=h;
15         h=q;
16     }
17     return h;
18 }
19 
20 void Display(LNODELIST *h){
21     LNODELIST *p=h;
22     while(p){
23         printf("%4d",p->data);
24         p=p->next;
25     }
26     printf("\n");
27 }
28 
29 void Bubblesort(LNODELIST *h,int n){
30     int i,t;
31     LNODELIST *p,*q;
32 
33     for(i=0;i<n-1;i++){
34         p=h;
35         q=p->next;
36         while(q){
37             if(p->data>q->data){
38                 //从小到大排
39                 t=p->data;
40                 p->data=q->data;
41                 q->data=t;
42             }
43             p=q;
44             q=p->next;
45         }
46     }
47 }
48 int main()
49 {
50     int n;
51     LNODELIST *h;
52     printf("n:");
53     scanf("%d",&n);
54     printf("请输入%d个整数:",n);
55     h=create(n);
56     printf("排序前:\n");
57     Display(h);
58     printf("排序后:\n");
59     Bubblesort(h,n);
60     Display(h);
61     return 0;
62 }

运行结果:

 

 至于为什么排序前是和输入相反的,是因为在创建链表时,是如下图的过程:

 

 


2.如果一个数列中的任意-段(至少是两个元素)的各个元素均相同,我们称之为等值数列段。等值数列段中元素的个数叫等值数列段长度。现有100个元素组成的整数数列A,求A中长度最大的所有等值数列段的首末位置,并输出该等值数列段的首末位置。如果没有等值数列段,则输出结束标志(not have)。
要求:所有运算均应在原数组上进行,不得引进第二个数组。

算法思想参考了一位同行的想法:https://blog.csdn.net/debug__boy/article/details/8189512?locationNum=2&fps=1

 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 int arr_src[100]={0};
 4 int arr_res[100]={1};
 5 
 6 int f(int n){
 7     int i,flag=0;
 8     for(i=1;i<n;i++){
 9         if(arr_src[i-1]==arr_src[i]){
10             flag=1;
11             arr_res[i]=arr_res[i-1]+1;
12         }else
13             arr_res[i]=1;
14     }
15     return flag;
16 }
17 int main()
18 {
19     int n,i;
20     int flag=0;//flag为0表示没有等值数列段
21     printf("n:");
22     scanf("%d",&n);
23     printf("arr:");
24     for(i=0;i<n;i++)
25         scanf("%d",&arr_src[i]);
26     flag=f(n);
27 
28 
29     if(flag){
30         for(i=1;i<n;i++){
31             if(arr_res[i]-arr_res[i-1]<0){
32                 printf("(%d to %d)\n",i-arr_res[i-1],i-1);
33             }
34 
35         }
36     }else{
37         printf("not have\n");
38     }
39 
40     return 0;
41 }

运行结果如下: