You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:05:22