[英]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.