解除引用指针C时的类型不完整

时间:2018-02-28 00:10:29

标签: c pointers struct

我有一个头文件,它给出了定义

typedef struct dyn_array dyn_array_t

我有一个实现它的.c文件

struct dyn_array {
    size_t size;
    void* array;
};

在另一个.c文件中,我将这种类型的指针传递给一个函数。

bool first_come_first_serve(dyn_array_t* ready_queue){
    size_t limit = ready_queue->size; 
    //...
} 

我无法弄清楚我在这里做错了什么。

3 个答案:

答案 0 :(得分:2)

另一个.c文件没有看到struct dyn_array定义。它不了解像size这样的成员。

如果超过1 .c文件需要了解结构,请将下面的内容移到.h文件

struct dyn_array {
  size_t size;
  void* array;
};

另一种方法是创建一个函数来获取成员并在dyn_array_t中保持dyn_array.c本地的定义。这是information hiding - 一个很好的设计目标。

// in dyn_array.h
typedef struct dyn_array dyn_array_t;
size_t get_size(const dyn_array_t* ready_queue);

// in different.c
#include <dyn_array.h>
bool first_come_first_serve(dyn_array_t* ready_queue){
  size_t limit = get_size(ready_queue); 
  //...
}

// in dyn_array.c
#include <dyn_array.h>

struct dyn_array {
    size_t size;
    void* array;
};

size_t get_size(const dyn_array_t* ready_queue) {
   return ready_queue->size; 
}

答案 1 :(得分:1)

&#34;不完整类型&#34;意味着你只声明/使用了类型,而没有解释它。您的第二个.c文件可能为#include "a.h",但请注意dyn_array定义位于a.c而不是a.h

要解决此问题,请在dyn_array中声明并定义a.h

struct dyn_array {
    size_t size;
    void* array;
};

答案 2 :(得分:1)

编译器需要完成类型定义才能取消引用指向它的指针并访问其字段。您必须将类型定义放在标题中(可能与您用于放置typedef声明的标题不同)并将其包含在第二个文件中,以便能够访问指针。只要您不需要该类型的详细信息,编译器就允许您访问指向不完整类型定义的指针。与第二个文件一样,编译器对结构的构建方式一无所知,因此无法访问size字段。

如果您需要代码的某些部分无法访问数据类型的内部详细信息,而其他人完全了解它,那么请准备两个头文件(一个公共文件和其他私有文件),如下所示:

dynarry.h

typedef struct dyn_array dyn_array_t;
size_t get_size(const dyn_array_t* ready_queue);

dynarryP.h

#include "dynarry.h"
struct dyn_array {
    size_t size;
    void *array;
};

然后,在使用as客户端的模块中,库仅包含"dynarry.h",而在内部实现中则为#include "dynarryP.h"。这有点类似于面向对象的编程,与隐藏内部实现细节相关