[英]Dereferencing pointer to incomplete type 'struct ____'
我试图在C中创建一个可以接受大多数原始类型的类型。 我是C语言的新手,对结构的了解不深。 我的错误发生在(main.c的)第10行,并且如果删除了第10行(也是main.c的),也将在11行发生。 如果有人有想法/指针,我将不胜感激! 非常感谢!
main.c:
#include <stdio.h>
#include "modularType.h"
int main()
{
int data = 1;
PyType object = createPyObjectInt(data);
printf("Type of data: %d\n", object->typeOfData);
printf("Value of data: %d\n", object->intData);
return 0;
}
moduleType.h:
typedef struct pytype *PyType;
PyType createPyObjectEmpty(void);
PyType createPyObjectInt(int data);
void setDataInt(PyType, int data);
void setDataIntStar(PyType, int* data);
void freeMyType(PyType);
void freeCharStar(PyType);
void freeIntStar(PyType);
void freeFloatStar(PyType);
moduleType.c:
#include <stdlib.h>
#include <stdio.h>
#ifndef NEW_TYPE
#define NEW_TYPE
#include "modularType.h"
typedef enum
{
NO_DATA,
REG_CHAR,
CHAR_STAR,
REG_INT,
INT_STAR,
REG_FLOAT,
FLOAT_STAR,
}types;
struct pytype
{
//The number of data types i can hold here
unsigned char typeOfData: 3;
union
{
char charData;
char* charStarData;
int intData;
int* intStarData;
float floatData;
float* floatStarData;
}
};
PyType createPyObjectEmpty(void)
{
PyType object;
object = malloc(sizeof(*object));
object->typeOfData = NO_DATA;
return object;
}
PyType createPyObjectInt(int data)
{
PyType object;
object = malloc(sizeof(*object));
object->intData = data;
object->typeOfData = REG_INT;
return object;
}
void setDataInt(PyType object, int data)
{
object->intData = data;
object->typeOfData = REG_INT;
}
void setDataIntStar(PyType object, int* data)
{
object->intStarData = data;
object->typeOfData = INT_STAR;
}
#endif
顺带一提,我的编译命令(gcc -Wall -std = c99 -o modType main.cmodularType.c)产生以下警告: modularType.c:35:1:警告:struct或union末尾没有分号 。 我以为我已经正确格式化了结构,但我也看到人们将结构定义如下:
typedef struct pytype
{
//code here
}PyType;
这是更好的方法还是我做的很好?
您遇到的问题是范围之一 。 那是C的有意和固有的部分。您尝试采用的方法是数据封装或数据隐藏之一 。 您有意在modularType.c
声明了该struct
,该struct
提供了该结构的文件范围 。 struct pytype
从未暴露main.c
使得不可能直接引用该结构(例如成员object->foo
)在main.c
。 那是设计使然。 这就是您有意隐藏pytype
成员pytype
直接在main
访问的方式。
要执行您要尝试的操作,您需要通过modularType.h
公开函数,这些函数从struct pytype object
检索所需的信息。 例如,您要检索object->typeOfData
和object->intData
。 要做到这一点的main
,你只需要提供访问这些数据的功能。 在modularType.c
您可以添加:
int getPyObjectType (PyType object)
{
return object->typeOfData;
}
int getDataInt (PyType object)
{
return object->intData;
}
然后在modularType.h
您可以提供函数原型,以将函数公开给main
,例如
int getPyObjectType (PyType);
int getDataInt (PyType);
由于这两个函数都位于modularType.c
,因此它们可以访问struct pytype
的成员,而main
中的任何其他成员都不能。 对main.c
进行以下修改后
printf("Type of data: %d\n", getPyObjectType(object));
printf("Value of data: %d\n", getDataInt(object));
您将能够返回所需的值,例如:
使用/输出示例
$ ./bin/main
Type of data: 3
Value of data: 1
脚注1:尽管不是错误,但C的标准编码样式避免使用caMelCase
或MixedCase
变量名称,而支持所有小写字母,同时保留了大写字母名称以供宏和常量使用。 这是风格问题-因此完全取决于您,但是如果不遵循它,可能会在某些圈子中导致错误的第一印象。
头文件中的结构定义不完整,因此您不能在代码中引用任何结构成员。 编译器抱怨说它根本不了解任何结构成员。
不完整的结构定义是您不提供实现成员列表的结构。 这样的定义使您可以操纵指向此类结构的指针,但是由于没有明确定义它们,因此不能访问任何成员,并且编译器需要知道它们的类型和从结构开始的偏移量以生成相应的代码。
同样不是typedef PyType
隐藏指向struct pytype
的指针。 将指针隐藏在typedef后面很容易出错,从而导致程序员和阅读器的代码混乱。
您有2个问题:
这部分从modularType.c
属于年初modularType.h
和你缺少的;
(请参见下面的int片段注释)。
typedef enum { NO_DATA, REG_CHAR, CHAR_STAR, REG_INT, INT_STAR, REG_FLOAT, FLOAT_STAR, } types; struct pytype { //The number of data types i can hold here unsigned char typeOfData: 3; union { char charData; char* charStarData; int intData; int* intStarData; float floatData; float* floatStarData; } ; // ^ you are missing a ';' here };
标头保护modularType.h
属于modularType.h
,不属于modularType.c
#ifndef NEW_TYPE #define NEW_TYPE ... #endif
但是,这现在不是问题。 它不会阻止文件编译,只是将头文件保护放入.c文件中完全没有用。
除了两件事,您的操作方式还不错。
1)除非您从名称中明确指出它,否则实际上不应该将其定义为指向结构体指针的typedef。 将其更改为typedef struct pytype PyType;
2)您的标头还应该包括struct pytype
和枚举的定义,以便包含它的任何文件都知道它们是什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.