c - 使结构对 main 可见
问题描述
我正在学习 C,目前正在学习如何使用一个统一的 c 文件之外的多个文件来实现抽象数据类型。我有一个项目,它在单独的头文件中定义客户和股票,其中行为在 c 文件中定义。最后,我将读取多个文件并使用客户和股票信息填充多个链接列表。但是,我在我的 main 函数中遇到了可见性问题,我尝试在 Client 结构上调用 sizeof()。
我所做的研究显示了类似的错误,因为不包括适当的头文件。我很肯定我包含了正确的头文件,并且我还尝试在头文件而不是 c 文件中定义结构。
老实说,我不确定结构的前向声明是什么意思,因为我认为当它在我的 main.js 之前包含头文件时,它会“拥有所有信息”。我可以采取哪些步骤来解决此问题?
这是我的编译器在我尝试编译我的 main 时给我的错误:
main.c:32:31: error: invalid application of 'sizeof' to an incomplete type
'Client' (aka 'struct client')
ListType clientList = create(sizeof(Client), compareClients);
^ ~~~~~~~~
./client.h:6:16: note: forward declaration of 'struct client'
typedef struct client Client;
^
1 error generated
我的主文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "client.h"
#include "stock.h"
#include "listADTgen.h"
/* Main function of the program. */
int main(int argc, char const *argv[]) {
if (argc > 5) { // Input validation on number of arguments.
printf("Invalid format. Exiting...\n");
return -1;
}
FILE *clientFile = fopen(argv[1], "r");
if (clientFile == NULL) { // Validate client file.
printf("Error opening client file. Exiting...\n");
return -1;
}
// Create a list of all clients, read from the client file.
int (*clientCompare) (Client *x, Client *y);
clientCompare = compareClients;
ListType clientList = create(sizeof(Client), compareClients);
FILE *stockFile = fopen(argv[2], "r");
if (stockFile == NULL) { // Validate stock file.
printf("Error opening stock file. Exiting...\n");
return -1;
}
// Create a list of all stocks, read from the stock file.
FILE *stockClientFile = fopen(argv[3], "r");
if (stockClientFile == NULL) { // Validate stock_client file.
printf("Error opening stock + client file. Exiting...\n");
return -1;
}
// Utilize previously built client and stock lists to put together the information
// given to use by the stock_client file.
printf("All good!\n");
return 0;
}
客户端.h:
typedef struct client Client;
Client* createClient(int id, char *name, int phone, char *email);
void deleteClient(Client *c);
int getId(Client *c);
void setId(Client *c, int x);
char* getName(Client *c);
void setName(Client *c, char *pointer);
int getPhone(Client *c);
void setPhone(Client *c, int x);
char* getEmail(Client *c);
void setEmail(Client *c, char *pointer);
int compareClients(Client *x, Client *y);
客户端.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "client.h"
struct client {
int id;
char name[30];
int phone;
char email[30];
};
/* Creates and returns a pointer to a Client object. */
Client* createClient(int id, char *name, int phone, char *email) {
Client *newClient = malloc(sizeof(Client));
setId(newClient, id);
setName(newClient, name);
setPhone(newClient, phone);
setEmail(newClient, email);
return newClient;
}
/* Deletes a given Client by freeing the memory address allocated to them. */
void deleteClient(Client *c) {
free(c);
}
/* Returns the id number of the given Client. */
int getId(Client *c) {
return c->id;
}
/* Sets the id to the given Client. */
void setId(Client *c, int x) {
c->id = x;
}
/* Returns the name of a given Client. */
char* getName(Client *c) {
char *p = c->name;
return p;
}
/* Sets the name of the given Client. */
void setName(Client *c, char *pointer) {
strcpy(c->name, pointer);
}
/* Returns the phone number of the given Client. */
int getPhone(Client *c) {
return c->phone;
}
/* Sets the phone of the given Client. */
void setPhone(Client *c, int x) {
c->phone = x;
}
/* Returns the email of a given Client. */
char* getEmail(Client *c) {
char *p = c->email;
return p;
}
/* Sets the email of the given Client. */
void setEmail(Client *c, char *pointer) {
strcpy(c->email, pointer);
}
/* Compares two clients based on their id number. */
int compareClients(Client *x, Client *y) {
int result = 0;
if (x->id > y->id) {
result = 1;
} else if (x->id < y->id) {
result = -1;
}
return result;
}
解决方案
要采用sizeof
a 结构,编译器需要已经“看到”该结构的完整定义。由于结构仅在 中定义client.c
,因此编译器无法在编译时判断结构的大小main.c
。
不过,在这种情况下,我认为您的问题是您clientList
使用错误的类型分配列表 ()。该列表需要包含指向Client
对象(Client *
)的指针,而不是实际Client
对象;它的元素将有大小sizeof(Client *)
,而不是sizeof(Client)
.
推荐阅读
- visual-studio - Glslang VS 项目设置
- c# - 在 C# 中跨多个类使用数组和插入排序将不起作用
- java - 对于一个可以改变的变量,你如何从 100 次中获得机会?
- java - 重命名包和更改主要活动后应用程序崩溃
- html - 如何删除数据列表条目?
- dart - 当我的键盘处于活动状态时,如何避免背景图像缩小?
- android - 如何在 RecyclerView ItemDecoration 中将 CardView 阴影绘制到画布上?
- node.js - 弃用警告:collection.findAndModify 已弃用。改用 findOneAndUpdate、findOneAndReplace 或 findOneAndDelete?
- java - `失败的完整性元数据检查。`在 JavaFX WebView 中,忽略 SystemProp
- php - 随机问题特定编号