【问题标题】:Making a struct visible to a main使结构对 main 可见
【发布时间】:2018-05-19 11:22:27
【问题描述】:

我正在学习 C,目前正在学习如何使用一个统一 c 文件之外的多个文件来实现抽象数据类型。我有一个项目,它在单独的头文件中定义客户和股票,其中行为在 c 文件中定义。最后,我将读取多个文件并使用客户和股票信息填充多个链接列表。但是,我的主函数中存在可见性问题,我尝试在客户端结构上调用 sizeof()。

我所做的研究表明,由于不包含适当的头文件,出现了类似的错误。我很肯定我包含了正确的头文件,并且我还尝试在头文件而不是 c 文件中定义结构。

老实说,我不确定结构的前向声明是什么意思,因为我认为当它在我的 main.xml 之前包含头文件时,它会“拥有所有信息”。我可以采取哪些步骤来解决此问题?

这是我在尝试编译我的 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;
}

client.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);

client.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;

}

【问题讨论】:

    标签: c


    【解决方案1】:

    要采用sizeof 结构,编译器需要已经“看到”该结构的完整定义。由于结构仅在client.c 中定义,因此编译器在编译main.c 时无法判断结构的大小。

    不过,在这种情况下,我认为您的问题是您分配列表 (clientList) 时使用了错误的类型。该列表需要包含指向Client 对象(Client *)的指针,而不是实际的Client 对象;它的元素大小为sizeof(Client *),而不是sizeof(Client)

    【讨论】:

    • 是的,先生!就是这样。从字面上看,离大部分工作只有一个星号...谢谢您的帮助。 C 是完全无情和具有挑战性的 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-19
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    • 2023-03-19
    相关资源
    最近更新 更多