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 }
运行结果如下: