一、
1 #include<stdio.h> 2 3 int main(){ 4 int *p,k=10; 5 double *q,f=5.6; 6 p=&k; 7 q=&f; 8 printf("%g\n",*q); 9 printf("%d\n",*p); 10 p=(int *)q; 11 printf("%g\n",*p); 12 printf("%d\n",*p); 13 return 0; 14 }
运行结果:
为啥? 将q指针所指的变量的地址赋给了p,则p指向的就是变量f了。
至于答案给了一个B、5 我就不知道为啥了。
2、
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 struct node{ 5 char c; 6 char s[10]; 7 }ss[2]={'1',"time",'2',"work"},*p=ss; 8 int main() 9 { 10 p=(struct node *)ss[0].s; 11 printf("%c",*(p+1)); 12 return 0; 13 }
运行结果
为什么是这个呢?
二、
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 5 struct node{ 6 int a,*b; 7 }*p; 8 int s[6]={2,4,6,8,10,12}; 9 struct node ss[6]={10,0,20,0,30,0,40,0,50,0,60,0}; 10 11 void sub(int s[6],struct node *p){ 12 int i; 13 for(i=0;i<6;i++) 14 (p+i)->b=s+i; 15 printf("%d\n",*(++p)->b); 16 printf("%d\n",p->a); 17 printf("%d\n",*p->b++); 18 printf("%d\n",p->a); 19 printf("%d\n",*++p->b); 20 printf("%d\n",p->a); 21 } 22 23 int main(){ 24 int i,s[6]={1,3,5,7,9,11}; 25 sub(s,ss); 26 for(i=0;i<6;i++) 27 printf("%d ",s[i]); 28 return 0; 29 }
运行结果如下:
分析:
三、程序填空题
1、一个简单的变型
1 #include<stdio.h> 2 3 int main(){ 4 char s[5][80]; 5 FILE *fp1,*fp2; 6 if((fp1=fopen("in.dat","r"))==NULL){ 7 printf("Can't open the file.\n"); 8 exit(1); 9 } 10 if((fp2=fopen("out.dat","w"))==NULL){ 11 printf("Can't open the file.\n"); 12 exit(1); 13 } 14 15 fgets(s[0],80,fp1); 16 fputs(s[0],fp2); 17 fclose(fp1); 18 fclose(fp2); 19 return 0; 20 }
这样写是对的,而真题中的题目只需将s[0]中的0改成i就行。
四、程序改错
2、
(一)
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 struct node{ 5 int num; 6 char name[20]; 7 struct node * next; 8 }nodea[2]={1,"zhang",0,2,"we",0}; 9 10 struct node * create(struct node *a,int n){ 11 struct node *h,*q; 12 13 for(h=NULL;n;n--,a++){ 14 q=(struct node *)malloc(sizeof(struct node)); 15 q->name=a->name;//这里是不对的!!!! 16 q->num=a->num; 17 q->next=h; 18 h=q; 19 } 20 return h; 21 }; 22 int main() 23 { 24 struct node *h1; 25 h1=create(nodea,2); 26 printf("%s\n",h1->name); 27 return 0; 28 }
为什么不对?
先看一下报错把:
啥意思呢?
就是说name[20]是一个20个字节大小的内存空间,而右值a->name只是一个常量有名字的字符串地址,即第15行是把一个地址赋给了数组,不匹配。
总的来说:结构体字符数组的赋值必须用字符串函数,不能直接进行复制。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 struct node{ 5 int num; 6 char name[20]; 7 struct node * next; 8 }nodea[2]={1,"zhang",0,2,"we",0}; 9 10 struct node * create(struct node *a,int n){ 11 struct node *h,*q; 12 13 for(h=NULL;n;n--,a++){ 14 q=(struct node *)malloc(sizeof(struct node)); 15 strcpy(q->name,a->name);//这样写就对了! 16 q->num=a->num; 17 q->next=h; 18 h=q; 19 } 20 return h; 21 } 22 int main() 23 { 24 struct node *h1; 25 h1=create(nodea,2); 26 printf("%s\n",h1->name); 27 return 0; 28 }
运行结果是:
至于为啥是we?
因为创建的过程是这样的:
(二)
继续:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include<string.h> 4 struct node{ 5 int num; 6 char name[20]; 7 int score1; 8 struct node *next; 9 }; 10 11 struct node *create(struct node *a,int n){ 12 struct node *h,*q; 13 int i; 14 for(h=NULL;n;n--,a++){ 15 q=(struct node *)malloc(sizeof(struct node)); 16 q->num=a->num; 17 strcpy(q->name,a->name); 18 q->score1=a->score1; 19 q->next=h; 20 h=q; 21 } 22 return h; 23 } 24 25 26 void del(struct node **h){ 27 struct node *p,*q,*h1; 28 h1=q=(struct node *)malloc(sizeof(struct node)); 29 q->next=*h;//创建一个头结点 30 p=q->next; 31 while(p){ 32 33 if(p->score1<60){ 34 q->next=p->next; 35 free(p); 36 p=q->next; 37 }else{ 38 q=p; 39 p=p->next; 40 } 41 } 42 *h=h1->next; 43 free(h1); 44 } 45 int main() 46 { 47 struct node *p,*head1,*head2; 48 struct node a[3]={1,"zhang",30,0,2,"we",50,0,3,"asd",20,0};//真题中给的数据是:分数的数据是zhang: 60 ;we: 50 ;asd: 80 49 head1=create(a,3); 50 51 head2=head1; 52 del(&head2); 53 p=head1; 54 while(p){ 55 printf("%d %s %d\n",p->num,p->name,p->score1); 56 p=p->next; 57 } 58 return 0; 59 }
运行结果是:
发现不对!但是用真题中的那组数据分数运行结果是:
符合预期。
为什么会有上述情况?
因为
void del(struct node **h)
函数没有考虑到这样一种情况,它存在BUG。
是什么BUG?从del函数实现来看,作者为了让删除满足条件的结点方便,所以增加了一个头结点,并且让头结点指向第一个元素结点。这个是正确的策略,但是作者没有考虑到,如果第一个元素结点就不满足条件,被free掉了,那么main函数中的head2指针即head1指针指向什么内容也就不知道了,因为可能被其他内容给覆盖掉。不妨试一试:
把第一个元素结点的成绩80改成20就出错,因为head1指针始终是指向第一个元素结点,但是由于成绩小于60,所以这个元素结点被free了,标记为可用的内存空间,但是仅仅是free(p),并不会把p指向的另外一个地址置为空。所以,你会发现,当继续用head1时,虽然这片空间被free掉了,但是依然还指定了一个地址。
关于这个,可以看:https://bbs.csdn.net/topics/340108285
养成好习惯,free(p);后再p=NULL;
关于free函数
怎么掉这个BUG?很简单,把有效的第一个元素结点返回给head1指针不就行了吗?若是结点全部删除了,依然能返回一个空值给它。代码加了红色的部分。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include<string.h> 4 struct node{ 5 int num; 6 char name[20]; 7 int score1; 8 struct node *next; 9 }; 10 11 struct node *create(struct node *a,int n){ 12 struct node *h,*q; 13 int i; 14 for(h=NULL;n;n--,a++){ 15 q=(struct node *)malloc(sizeof(struct node)); 16 q->num=a->num; 17 strcpy(q->name,a->name); 18 q->score1=a->score1; 19 q->next=h; 20 h=q; 21 } 22 return h; 23 } 24 25 26 struct node * del(struct node **h){ 27 struct node *p,*q,*h1; 28 h1=q=(struct node *)malloc(sizeof(struct node)); 29 q->next=*h;//创建一个头结点 30 p=q->next; 31 while(p){ 32 33 if(p->score1<60){ 34 q->next=p->next; 35 free(p); 36 p=q->next; 37 }else{ 38 q=p; 39 p=p->next; 40 } 41 } 42 *h=h1->next; 43 free(h1); 44 return *h; 45 } 46 int main() 47 { 48 struct node *p,*head1,*head2; 49 struct node a[3]={1,"zhang",60,0,2,"we",50,0,3,"asd",20,0}; 50 head1=create(a,3); 51 52 head2=head1; 53 head1=del(&head2); 54 p=head1; 55 while(p){ 56 printf("%d %s %d\n",p->num,p->name,p->score1); 57 p=p->next; 58 } 59 return 0; 60 }
运行结果:
关于这里的free(p);要不要后面p->next=NULL?完全没必要,因为用不上那个空间,没啥影响,不过加上也可以。至于为啥不p=NULL?因为把指针赋为NULL,没那片被free掉的空间内容产生丝毫影响,只是让p指针不指向那片被free掉的空间罢了。
当然对于del函数,完全可以不用二级指针,一级指针就行。因为该函数最终把有效的指针h返回给了head1指针。但是值得说的是此时head2指针完全没意义了,因为对于程序中的该组数据而言,head2指针所指的空间被free了。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include<string.h> 4 struct node{ 5 int num; 6 char name[20]; 7 int score1; 8 struct node *next; 9 }; 10 11 struct node *create(struct node *a,int n){ 12 struct node *h,*q; 13 int i; 14 for(h=NULL;n;n--,a++){ 15 q=(struct node *)malloc(sizeof(struct node)); 16 q->num=a->num; 17 strcpy(q->name,a->name); 18 q->score1=a->score1; 19 q->next=h; 20 h=q; 21 } 22 return h; 23 } 24 25 26 struct node * del(struct node *h){ 27 struct node *p,*q,*h1; 28 h1=q=(struct node *)malloc(sizeof(struct node)); 29 q->next=h;//创建一个头结点 30 p=q->next; 31 while(p){ 32 33 if(p->score1<60){ 34 q->next=p->next; 35 free(p); 36 p=q->next; 37 }else{ 38 q=p; 39 p=p->next; 40 } 41 } 42 h=h1->next; 43 free(h1); 44 return h; 45 } 46 int main() 47 { 48 struct node *p,*head1,*head2; 49 struct node a[3]={1,"zhang",50,0,2,"we",70,0,3,"asd",20,0}; 50 head1=create(a,3); 51 52 head2=head1; 53 head1=del(head2); 54 p=head1; 55 while(p){ 56 printf("%d %s %d\n",p->num,p->name,p->score1); 57 p=p->next; 58 } 59 return 0; 60 }
运行结果:
五、
五、编程序(第1题12分,第2题18分,共30分)
说明:按各题要求编程,否则不给分。
1.设计一个程序, 重排N个整数的顺序,使所有负数都在非负数之前。
要求:
(1)不要对这N个整数排序,否则不给分。
(2)程序应是非递归的。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MAXN 100 4 5 void f(int a[],int n){ 6 int t; 7 int i=0; 8 int j=n-1; 9 while(i<j){ 10 while(a[i]<0&&i<j) 11 i++; 12 while(a[j]>0&&i<j) 13 j--; 14 t=a[i]; 15 a[i]=a[j]; 16 a[j]=t; 17 } 18 } 19 20 int main() 21 { 22 int n,i; 23 int a[MAXN]; 24 printf("n:"); 25 scanf("%d",&n); 26 for(i=0;i<n;i++) 27 scanf("%d",&a[i]); 28 f(a,n); 29 for(i=0;i<n;i++) 30 printf("%d ",a[i]); 31 printf("\n"); 32 return 0; 33 }
运行结果:
2.设A和B分别是两个有序循环单链表(明表中结点已经按降序排序),pa 和pb分别指向这两个循环单链表的尾结点。设计一个程序,将这两个链表归并为个有 序的循环链表。
要求:
(1)结点的数据域只有一个整数域;
(2)将B有序表归并到A结果是pa指向循环链表的结点,不另外生成新链表;
(3) A、B所表示的有序链表建立过程,写一函数(input)实现;归并过程写-函数 (merger)实现,在主函数中调用这两个函数。
(4)程序应是非递归的。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct node{ 5 int data; 6 struct node *next; 7 }Lnode; 8 9 10 struct node *input(Lnode *h,int a[],int n){ 11 Lnode *p,*r; 12 int i; 13 for(h=NULL,i=1;i<=n;i++){ 14 15 p=(Lnode *)malloc(sizeof(Lnode)); 16 p->data=a[n-i]; 17 p->next=h; 18 h=p; 19 if(i==1) 20 r=p; 21 } 22 r->next=h; 23 return r; 24 } 25 26 void Display(Lnode *h,int n){ 27 Lnode *p=h; 28 while(n--){ 29 printf("%d ",p->data); 30 p=p->next; 31 } 32 printf("\n"); 33 } 34 35 void merger(Lnode *pa,Lnode *pb,int n,int m){ 36 Lnode *ha=pa->next,*hb=pb->next; 37 Lnode *pre_ha=pa,*pre_hb=pb; 38 int t=0; 39 while(n&&m){ 40 41 while(ha->data>hb->data&&n){ 42 n--; 43 pre_ha=ha; 44 ha=ha->next; 45 46 47 } 48 49 50 if(n){ 51 t++; 52 pre_hb->next=hb->next; 53 pre_ha->next=hb; 54 hb->next=ha; 55 pre_ha=hb; 56 hb=pre_hb->next; 57 m--; 58 } 59 } 60 if(m){ 61 pre_ha->next=pb->next; 62 pb->next=pa->next; 63 } 64 } 65 66 int main() 67 { 68 int a[]={7,6,5,4,3,2,1,1,-1}; 69 int b[]={6,5,4,0,-1,-2,-2,-3,-4}; 70 int lena=sizeof(a)/sizeof(int); 71 int lenb=sizeof(b)/sizeof(int); 72 Lnode *pa,*pb,*ha,*hb; 73 pa=input(ha,a,lena); 74 ha=pa->next; 75 76 printf("A:"); 77 Display(ha,lena); 78 79 pb=input(hb,b,lenb); 80 hb=pb->next; 81 82 printf("B:"); 83 Display(hb,lenb); 84 merger(pa,pb,lena,lenb); 85 Display(ha,lena+lenb); 86 return 0; 87 }
运行结果:
着重讲解:
被这一部分给绕吐了,看了老久才找出哪出问题了。
这个弄对了一切ok!
最后,就是看B数组还有没有剩余的,若有直接A的尾部与B的头部相接,B的尾部与A的头部想接。
对于:1:pre_ha->next=pb->next; 也能写成pa->next=pb->next;