c语言 - 取消引用指向不完整类型 'struct ____' 的指针



我正在尝试在C中创建一个可以接受大多数原始类型的类型。我是 C 的新手,不太了解结构。我的错误发生在第 10 行(main.c),如果删除第 10 行(也是 main.c),它也会发生在第 11 行。如果有人有想法/指示,我将不胜感激!非常感谢!

主.c:

#include <stdio.h>
#include "modularType.h"
int main()
{
int data = 1;
PyType object = createPyObjectInt(data);
printf("Type of data:  %dn", object->typeOfData);
printf("Value of data: %dn", object->intData);
return 0;
}

模块化类型.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);

模块化类型:

#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.c modularType.c)产生以下警告:modularType.c:35:1:警告:结构或联合末尾没有分号。我以为我已经正确格式化了我的结构,但我也看到人们定义结构如下:

typedef struct pytype
{
//code here
}PyType;

这是一种更好的方法还是我的做法很好?

头文件中的结构定义不完整,因此不能在代码中引用任何结构成员。编译器抱怨它根本不知道任何结构成员。

不完整的结构定义是指未提供实现的成员列表。这样的定义允许您操作指向此类结构的指针,但不能访问任何成员,因为它们没有显式定义,并且编译器需要知道它们的类型和结构开头的偏移量以生成相应的代码。

也不是说 typedefPyType隐藏指向struct pytype的指针。 将指针隐藏在 typedef 后面很容易出错,从而导致程序员和读者都混淆代码。

您遇到的问题是范围问题之一。这是C语言有意和固有的部分。您尝试采用的方法是数据封装数据隐藏。您有意在modularType.c中声明struct,该为结构提供文件范围struct pytype永远不会公开main.c因此无法直接引用结构的成员(例如object->foo) 在main.c.这是设计使然。这就是您有意隐藏pytype成员不被直接访问的方式main.

要执行您正在尝试的操作,您需要通过从struct pytype object中检索所需信息的modularType.h公开函数。例如,您希望检索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:  %dn", getPyObjectType(object));
printf("Value of data: %dn", getDataInt(object));

您将能够返回所需的值,例如:

示例使用/输出

$ ./bin/main
Type of data:  3
Value of data: 1

脚注 1:虽然不是错误,但 C 的标准编码样式避免使用caMelCaseMixedCase变量名称,而支持所有写,同时保留大写名称以用于宏和常量。这是一个风格问题 - 所以它完全取决于你,但如果不遵循它可能会导致某些圈子中的第一印象错误。

你 2 个问题:


  1. modularType.c中的这一部分属于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;
    } ;
    // ^ you are missing a ';' here
    };
    

  1. 标头防护属于modularType.h而不是modularType.c

    #ifndef NEW_TYPE
    #define NEW_TYPE
    ... 
    #endif
    

    然而,这现在不是问题。它不会阻止您的文件编译,将标头保护放入 .c 文件中是完全没用的。

你这样做的方式很好,除了两件事。

1)你真的不应该把它变成一个结构的指针的typedef,除非你从名称中清楚地表明它是什么。将其更改为typedef struct pytype PyType;

2)你的标题还应该包括struct pytype和枚举的定义,以便任何包含它的文件都知道它们是什么。

相关内容

  • 没有找到相关文章

最新更新