C语言链表删除函数报‘struct pessoa类型定义不完整’错误求助
C语言链表删除函数编译错误排查与修复
核心错误原因:结构体类型定义不完整
你的结构体定义写法存在语法问题:
typedef struct{ char nome[40]; char telefone[15]; char celular[15]; char email[40]; struct pessoa *prox; // 引用了未声明的struct pessoa } pessoa;
这里struct pessoa是一个未完成的类型声明——你在匿名struct内部引用它,但编译器此时还不知道struct pessoa的完整定义,因此触发“incomplete definition of type 'struct pessoa'”错误。
正确的写法是先给struct命名,再完成typedef:
typedef struct pessoa { char nome[40]; char telefone[15]; char celular[15]; char email[40]; struct pessoa *prox; } pessoa;
这样编译器在解析struct pessoa *prox时,已经明确它指向当前正在定义的结构体,就能正常识别类型。
删除函数的逻辑修正
你的remover函数中,while循环内的if语句位置错误,会导致提前修改链表指针,破坏遍历逻辑。修正后的函数如下:
pessoa* remover(pessoa **lista, char nome[40]){ pessoa *aux, *remover = NULL; if(*lista){ if(strcmp((*lista)->nome, nome) == 0){ remover = *lista; *lista = remover->prox; } else { aux = *lista; // 先遍历找到目标节点的前一个节点 while(aux->prox != NULL && strcmp(aux->prox->nome, nome) != 0){ aux = aux->prox; } // 确认找到目标节点后执行删除 if(aux->prox != NULL){ remover = aux->prox; aux->prox = remover->prox; } } } return remover; }
其他需修复的问题
- 多余的内存分配:main函数中
malloc的指针会被criarLista()返回的NULL覆盖,造成内存泄漏,直接改为:pessoa *lista = criarLista(); pessoa *b = criarLista(); - fgets读取换行符问题:fgets会把输入的换行符
\n存入字符串,导致strcmp匹配失败,需手动去除:nome[strcspn(nome, "\n")] = '\0'; - 未初始化变量:
int op未初始化,第一次进入while循环时判断条件为未定义行为,改为int op = 0;
完整修正后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct pessoa { char nome[40]; char telefone[15]; char celular[15]; char email[40]; struct pessoa *prox; } pessoa; pessoa * criarLista(){ return NULL; } pessoa * inserir(pessoa *lista,char nome[40],char telefone[15],char celular[15],char email[40]){ pessoa *novo = (pessoa *) malloc(sizeof(pessoa)); strcpy(novo -> nome, nome); strcpy(novo -> telefone, telefone); strcpy(novo -> celular, celular); strcpy(novo -> email, email); novo -> prox = lista; return novo; } pessoa * busca(pessoa*lista,char nome[40]){ pessoa *p = lista; while(p!=NULL){ if (strcmp(nome,p->nome) == 0){ return p; } else { p = p->prox; } } return NULL; } void exibir(pessoa * lista){ pessoa *p = lista; while(p!=NULL){ printf("\nNome: %s",p->nome); printf("\nEmail: %s",p->email); printf("\nTelefone: %s",p->telefone); printf("\nCelular: %s\n",p->celular); p = p->prox; } } pessoa* remover(pessoa **lista, char nome[40]){ pessoa *aux, *remover = NULL; if(*lista){ if(strcmp((*lista)->nome, nome) == 0){ remover = *lista; *lista = remover->prox; } else { aux = *lista; while(aux->prox != NULL && strcmp(aux->prox->nome, nome) != 0){ aux = aux->prox; } if(aux->prox != NULL){ remover = aux->prox; aux->prox = remover->prox; } } } return remover; } int main(void){ char nome[40]; char telefone[15]; char celular[15]; char email[40]; pessoa *lista = criarLista(); pessoa *b = criarLista(); int op = 0; while (op!=5){ printf("\n1- inserir contato \n2- listar contatos \n3- buscar contatos \n4- deletar contato\n5- sair\n"); scanf("%d", &op); setbuf(stdin, NULL); switch (op) { case 1: printf("Digite o nome: "); fgets(nome,sizeof(nome),stdin); nome[strcspn(nome, "\n")] = '\0'; printf("Digite o email: "); fgets(email,sizeof(email),stdin); email[strcspn(email, "\n")] = '\0'; printf("Digite o telefone: "); fgets(telefone,sizeof(telefone),stdin); telefone[strcspn(telefone, "\n")] = '\0'; printf("Digite o celular: "); fgets(celular,sizeof(celular),stdin); celular[strcspn(celular, "\n")] = '\0'; lista=inserir(lista,nome,telefone,celular,email); break; case 2: exibir(lista); break; case 3: printf("Digite o nome que deseja buscar: "); fgets(nome,sizeof(nome),stdin); nome[strcspn(nome, "\n")] = '\0'; b = busca(lista,nome); if (b != NULL){ printf("\nNome: %s",b->nome); printf("\nEmail: %s",b->email); printf("\nTelefone: %s",b->telefone); printf("\nCelular: %s\n",b->celular); } else { printf("Contato não encontrado!\n"); } break; case 4: printf("Digite o nome do contato que deseja excluir: "); fgets(nome,sizeof(nome),stdin); nome[strcspn(nome, "\n")] = '\0'; remover(&lista,nome); break; case 5: printf("Saindo...\n"); break; default: printf("Opção inválida!\n"); } } // 释放链表内存,避免泄漏 pessoa *temp; while(lista != NULL){ temp = lista; lista = lista->prox; free(temp); } return 0; }
内容的提问来源于stack exchange,提问作者Eduardo Paulino
相关产品推荐
相关产品推荐

