一、

 

 

 

 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行是把一个地址赋给了数组,不匹配。

总的来说:结构体字符数组的赋值必须用字符串函数,不能直接进行复制。

还不懂可以看这个:https://blog.csdn.net/melody_1016/article/details/83345399?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-2.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-2.nonecase

 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;