首页 > 解决方案 > 如何在结构中初始化指针但结构在模块中

问题描述

也许这是一个愚蠢的问题,但我找不到解决方案。我找到的大多数答案适用于主文件中的结构。我想在模块中定义结构(list),因为该模块中的某些函数与结构一起使用。稍后结构应该成为列表的根。

我的module.c是:

#include"modul.h"

struct date{
    int date_date;
};

struct list{
    date *first;
    date *last;
};

我的module.h是:

typedef struct date date;
typedef struct list list;

在 main.c 中,我尝试初始化结构列表的两个指针(第一个最后一个):

#include<stdio.h>
#include<stdlib.h>
#include"module.h"

int main(){
    
    list *mylist=malloc(sizeof(mylist));
    
    mylist->first=NULL;
    mylist->last=NULL;
    
    printf("test");
    
    return 0;
}

我尝试用gcc编译:

gcc -Wall -std=c99 main.c module.c -o main

并得到以下错误:

main.c: In function 'main':
main.c:9:11: error: dereferencing pointer to incomplete type 'list {aka struct list}'
     mylist->first=NULL;
           ^~

我做错什么了?我希望我使代码尽可能简单。随着mylist.first=NULL;我也得到一个错误。

标签: cstructlinked-listdeclarationincomplete-type

解决方案


对于初学者来说,这些声明

struct date{
    int date_date;
};

struct list{
    date *first;
    date *last;
};

是错误的,没有意义。

例如对于这个声明

struct list{
    date *first;
    date *last;
};

编译器将发出date未声明类型名称的错误。您声明了类型struct date,但没有声明date

但即使你会写正确

struct list{
    struct date *first;
    struct date *last;
};

您不会构建列表,因为该结构date没有指向该类型的先前对象的指针struct date

您可以像这样声明结构(对于单链表)

struct date{
    int date_date;
    struct date *next;
};

struct list{
    struct date *first;
    struct date *last;
};

或类似(对于双向链表)

struct date{
    int date_date;
    struct date *next;
    struct date *prev;
};

struct list{
    struct date *first;
    struct date *last;
};

具有函数 main 的文件仅包含module.h具有这些不完整类型声明的标头

typedef struct date date;
typedef struct list list;

所以编译器会发出一个错误,因为当它编译翻译单元时,它不知道声明的类型是否有数据成员firstlast.

您应该将完整的结构声明放在标题中。

例如

struct date{
    int date_date;
    struct date *next;
};

struct list{
    struct date *first;
    struct date *last;
};

typedef struct date date;
typedef struct list list;

同样,为 struct list 类型的对象动态分配内存也没有太大意义,例如

list *mylist=malloc(sizeof(mylist));

而且这是不正确的。

你可以写

list mylist = { .first = NULL, .last = NULL };

推荐阅读