user-0 提问: 这段链表代码卡两天了一直找不到错误,程序媛自学好难

回复:
user: user-1
content: 没有数据结构的代码

user: user-2
content: 建议把功能分一下，  入链表 push 出链表pop 创建链表 create 遍历显示 show 这样你只关心每个功能的细节， 都混着写 很容易出错。

user: user-3
content: 参考代码段 http://pan.baidu.com/s/17yIcQ

user: user-4
content: 引用 24 楼 Data_Flow 的回复:楼上说10天学完CPP的 您老这是让人看完CPP吗？这分明是翻完CPP  没点钻劲儿还学什么计算机。话说当年俺第一次接触数据库，而且用电脑也不是很方便，只在床边坐了三天就翻完了厚厚的一本dBase 教程，然后扔掉书到别人的机房里验证所学去了。

user: user-5
content: 楼上说10天学完CPP的 您老这是让人看完CPP吗？这分明是翻完CPP

user: user-6
content: p = q = (struct Info *) malloc(sizeof (struct Info *)); 这句只申请了4字节的内存空间，只能用来保存一个地址。而每一个结点至少需要4+20*1+10*1+4+4 = 42字节内存空间，所以会出错。  head是链表首地址，如果head作为函数参数传入，比如删除结点函数，这个地址会被push到栈中，子函数就从这个栈地址去取到链表首地址。 p,q 一般用来存放结点地址，编译器通常会把他们在内存中放到一起。无论是创建链表，删除链表结点，还是插入链表结点，CPU都需要记住当前和之前处理的结点地址，p就用来保存当前正在处理的结点地址，q用来保存之前处理过的结点地址。比如创建链表的时候，新建一个结点，得到新结点的地址，这个地址就保存在p中，这个地址需要放到之前处理过的结点的next域中，而q中就保存了之前刚处理过的结点的地址，之后q中的地址就过时了，于是用p中的地址来更新，p,q保存的地址就这样随着循环跳转不断变化，直到最后一个结点。 或许你会问为什么一定要用p，q来保存之前和当前结点的地址，用其他地址不行吗？当然可以，但前提是没有循环。计算机的强大就在于利用循环来实现自动化。要实现循环就必须保证每次循环都跳转到相同的偏移地址，而p和q就保证了每次循环都有相同的偏移地址。

user: user-7
content: 对妹纸要温柔~引用 9 楼 sholber 的回复:p = q = (struct Info *) malloc(sizeof (struct Info *)); 神额，要分配的空间是一个指针的大小，而不是结构的大小？？      int a;//用户输入要进行的功能     int n = 0;     struct Info * head;     struct Info * p, * q; 声明这么多狗屁变量干甚？

user: user-8
content: case ‘1’:                 creat(head,&n,p,q);                 break;             case ‘2’:                 change(head);                 break;             case ‘3’:                 streichen;                 break;             case ‘4’:                 search;                 break;             case ‘5’:                 show(head);                 break;  上述的case 12345必须加单引号

user: user-4
content: 引用 16 楼 user-13 的回复:[quote=引用 14 楼 sholber 的回复:] 学两个月还没学会C，可以改行了。要是让我当老师的话，勒令学生10天看完CPP，然后用标准文档强化训练。  大神  我最近也在自学C语言 不知道能不能请你当我的老师 指导下我啊  [/quote]  我贪财，学费贵。

user: user-4
content: 引用 17 楼 cysccnu 的回复:p = q = (struct Info *) malloc(sizeof (struct Info *)); 这句只申请了4字节的内存空间，只能用来保存一个地址。而每一个结点至少需要4+20*1+10*1+4+4 = 42字节内存空间，所以会出错。  head是链表首地址，如果head作为函数参数传入，比如删除结点函数，这个地址会被push到栈中，子函数就从这个栈地址去取到链表首地址。 p,q 一般用来存放结点地址，编译器通常会把他们在内存中放到一起。无论是创建链表，删除链表结点，还是插入链表结点，CPU都需要记住当前和之前处理的结点地址，p就用来保存当前正在处理的结点地址，q用来保存之前处理过的结点地址。比如创建链表的时候，新建一个结点，得到新结点的地址，这个地址就保存在p中，这个地址需要放到之前处理过的结点的next域中，而q中就保存了之前刚处理过的结点的地址，之后q中的地址就过时了，于是用p中的地址来更新，p,q保存的地址就这样随着循环跳转不断变化，直到最后一个结点。 或许你会问为什么一定要用p，q来保存之前和当前结点的地址，用其他地址不行吗？当然可以，但前提是没有循环。计算机的强大就在于利用循环来实现自动化。要实现循环就必须保证每次循环都跳转到相同的偏移地址，而p和q就保证了每次循环都有相同的偏移地址。  评论：振振有词，毫无根据。 p = q = (struct Info *) malloc(sizeof (struct Info *)); 这句只申请了4字节（为啥是4字节？？）的内存空间，只能用来保存一个地址。而每一个结点至少需要4+20*1+10*1+4+4 = 42字节（为啥是42字节？？不会有内部填充吗？？）内存空间，所以会出错。 子函数？C里还有子函数？？ 至于p  q之类，就不说了。

user: user-6
content: 引用 18 楼 sholber 的回复:[quote=引用 17 楼 cysccnu 的回复:] p = q = (struct Info *) malloc(sizeof (struct Info *)); 这句只申请了4字节的内存空间，只能用来保存一个地址。而每一个结点至少需要4+20*1+10*1+4+4 = 42字节内存空间，所以会出错。  head是链表首地址，如果head作为函数参数传入，比如删除结点函数，这个地址会被push到栈中，子函数就从这个栈地址去取到链表首地址。 p,q 一般用来存放结点地址，编译器通常会把他们在内存中放到一起。无论是创建链表，删除链表结点，还是插入链表结点，CPU都需要记住当前和之前处理的结点地址，p就用来保存当前正在处理的结点地址，q用来保存之前处理过的结点地址。比如创建链表的时候，新建一个结点，得到新结点的地址，这个地址就保存在p中，这个地址需要放到之前处理过的结点的next域中，而q中就保存了之前刚处理过的结点的地址，之后q中的地址就过时了，于是用p中的地址来更新，p,q保存的地址就这样随着循环跳转不断变化，直到最后一个结点。 或许你会问为什么一定要用p，q来保存之前和当前结点的地址，用其他地址不行吗？当然可以，但前提是没有循环。计算机的强大就在于利用循环来实现自动化。要实现循环就必须保证每次循环都跳转到相同的偏移地址，而p和q就保证了每次循环都有相同的偏移地址。  评论：振振有词，毫无根据。 p = q = (struct Info *) malloc(sizeof (struct Info *)); 这句只申请了4字节（为啥是4字节？？）的内存空间，只能用来保存一个地址。而每一个结点至少需要4+20*1+10*1+4+4 = 42字节（为啥是42字节？？不会有内部填充吗？？）内存空间，所以会出错。 子函数？C里还有子函数？？ 至于p  q之类，就不说了。[/quote]  没错，还是低调点好。。。

user: user-9
content: 你可知道这样传递参数 void creat(struct Info * head, int * n, struct Info * p, struct Info * q) 在函数里面做这样的 head = xxx p = xxx q = xxx 更改结果都不会返回出去的.  用指针来返回值只能返回这种更改: head->xxx = xxx *head = xxx

user: user-10
content: 找个好老公什么事都解决了，不用自己那么累了

user: user-11
content: 仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

user: user-12
content: void creat(struct Info * head, int * n, struct Info * p, struct Info * q) 	{ 		 		printf("请输入要创建的订单号,(如需返回上一层,请输入0)\n"); 		scanf("%d", &p->num); 		if (p->num == 0) 			return; 		printf("请输入订餐客户姓名\n"); 		scanf("%s", &p->name); 		printf("请输入预定就餐时间\n"); 		scanf("%s",&p->time); 		printf("请输入就餐人数\n"); 		scanf("%d", &p->number); 		 		q = (struct Info *)malloc(sizeof(struct Info *)); 		q->next = NULL; 		 		*n = *n + 1;  		if (*n == 1)     //如果是第一个结点,则head指向p 			head = p;  		p->next = q; 		p = q;  		return;  	}

user: user-5
content: sorry我搞错了 因为我一般不会这样写  p = (struct Info *)malloc(sizeof(struct Info *)); 这里只分配了一个指针大小的内存，而不是一个结构

user: user-13
content: 引用 14 楼 sholber 的回复:学两个月还没学会C，可以改行了。要是让我当老师的话，勒令学生10天看完CPP，然后用标准文档强化训练。  大神  我最近也在自学C语言 不知道能不能请你当我的老师 指导下我啊

user: user-10
content: 引用 14 楼 sholber 的回复:学两个月还没学会C，可以改行了。要是让我当老师的话，勒令学生10天看完CPP，然后用标准文档强化训练。 估计不是没学会C，是数据结构基础上不来吧！

user: user-5
content: creat函数 你要改变链表要传递的参数应该是指向链表第一个节点指针的指针。你其实可以把所有的项目再创建一个结构，这样变量太多了，可读性不好。

user: user-4
content: 学两个月还没学会C，可以改行了。要是让我当老师的话，勒令学生10天看完CPP，然后用标准文档强化训练。