C语⾔编写单链表所遇到的若⼲问题和易犯的错误
使⽤C语⾔实现单链表的创建,删除,添加。
所遇到问题:
1、 Node head;
head->next=NULL;
这个没有分配地址,直接使⽤ head->next,会导致程序崩溃
。同样的问题,在创建删除的函数是⼜同样遇到,例如while(p!=NULL&&p->id!=id),若是先判断p->id!=id,则会导致程序崩溃。为什么?其原因是当p指向NULL时,p->id!=id会导致程序崩溃。
解决⽅案:先判断是否为空,再判断p->id!=id。
2、free()仅仅是将指针所指地址回收,实质是指针所指的地址还在,只是其中内容不再保护,地址中的值会出现各种内容,为了规范和避免引起不必要的⿇烦,则需要将指针置空。
3、⼆级指针,函数参数中使⽤⼆级指针,如 void deleteEmun(Node * head,int id),⼀般的如果在⾃定
义的函数中没有使⽤malloc()函数,即形参指针指向malloc所定义的节点,⽽不是指向实参所传的地址,这时候就需要使⽤⼆级指针。当然,如果是返回值是指针的函数,则不需要⼆级指针,返回值返回函数内定义好的指针即可。
typedef struct{
int id;
char name[5];
double scores;
struct Node *next;
}Node;
int main(int argc,char*argv[])
{
/**
注意:指针若指向未分配的地址会导致崩溃
Node *head;
head->next=NULL;
这是典型错误,没有分配内存,head->next=NULL会导致运⾏崩溃
这个错误困扰我很久
*/
Node *head =(Node*)malloc(sizeof(Node));
Node *p,*q,*rear;
int id;
head->next=NULL;
printf("head->next=%d\n",head->next);
head=create(head);
p=head->next;
printf("\n\np=%d (p=head->next)\n",p);
printf("\n-----------------头插法元素遍历----------------\n");//分割线
printf("学号\t姓名\t成绩\t地址\t");
while(p!=NULL){
printfNode(p);
p=p->next;
//rear=p;
// printf("\nrear的地址是%d\n",rear);
}
printf("\n-----------------删除元素----------------\n");
printf("\n输⼊需要删除元素的ID:\n");
scanf("%d",&id);
deleteEmun(&head,id);
q=head->next;
while(q!=NULL){
printfNode(q);
q=q->next;
}
printf("\n----------------插⼊元素(头插法)-----------------\n");//分割线
insert(head);
printf("\n学号\t姓名\t成绩\t地址\t");
p=head->next;
while(p!=NULL){
printfNode(p);
p=p->next;
}
printf("\n---------------------------------\n");//分割线
return0;
}
```c
Node*create(Node* head){
printf("\n----------------初始化(头插法)-----------------\n");//分割线
int i;
for(i=0;i<10;i++){
Node *p =(Node*)malloc(sizeof(Node));
p->id=createRandomID(p);
createRandomName(&p);
printfNode(p);
p->next=head->next;
head->next=p;
}
return head;
}
/**
molloc函数以节点的地址为随机数的种⼦。如果以时间为随机数的种⼦,那么在for循环中CPU运算速度快,则会导随机产⽣的ID和姓名都⼀样*/
int createRandomID(Node* p){//在创建单链表时,随机⽣成节点中属性的ID
int a ;
// time_t timer;
srand((int)p);
a =rand()%100;
return a;
}
void createRandomName(Node** p){//在创建单链表时,随机⽣成节点中属性的名字
int i;
// time_t timer;
srand((int)(*p));
(*p)->name[0]=rand()%26+66;
for(i=1;i<5;i++){
(*p)->name[i]=rand()%26+97;
}
}
Node*insert(Node* head){
Node *p =(Node*)malloc(sizeof(Node));
printf("请输⼊学⽣的学号姓名成绩 \n");
scanf("%d%s%lf",&p->id,&p->name,&p->scores);
p->next=head->next;
head->next=p;
return head;
} ``
void deleteEmun(Node** head,int id){
printf("\n所要删除的元素的id:%d\n",id);
Node *p =(*head)->next;
Node *pre=*head;//这是指向p的前⼀个指针
while(p!=NULL&&p->id!=id){
printf("\np: %d\tp->next: %d\n",p,p->next);
pre=p;
p=p->next;
}
if(p!=NULL&&p->id==id){
pre->next=p->next;
printf("\n未free(p)前p的地址:%d\n",p);
free(p);
printf("free(p)后p的地址:%d\n",p);
p=NULL;
printf("free(p)和p=NULL后p的地址:%d\n",p);
}else{
printf("没有该ID");
exit(0);
}
}
void printfNode(Node* p){
printf("\n%d\t%s\t%6.1lf\t%d\t",p->id,p->name,p->scores,p); }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论