【问题标题】:Using structs in multiple files在多个文件中使用结构
【发布时间】:2012-10-25 18:46:04
【问题描述】:

我试图从 io.h 调用 main.c 中的一个函数,该函数从文件中读取数据,将该数据存储到多个结构中,然后以某种方式让我将不同的结构作为参数传递给 main 中的后续函数。后面的函数将在其他文件中定义,例如 alg.h。

我该怎么做呢?我是否使用 extern 并使结构全局化并将它们放在单独的文件中?是否可以让 alg.h 中的函数具有其中一个结构的返回类型?这取决于我的包含顺序吗?

下面粘贴的代码符合并有效,但任何移动任何结构的尝试都会导致程序无法编译。

此外,是否可以在 alg.h 中声明一个结构,然后在 alg.h 中声明具有该结构作为参数的函数。然后在 main.c 中,初始化该结构并将其传递给在 io.h 中声明的函数,给该结构一些值,将其返回给 main.c,然后将其传递给在 alg.h 中声明的函数?我知道这听起来像是一个类,但我需要一个 C 解决方案,而且我只需要一个浮动的结构实例。

谢谢。

io.h

struct s1 {
    int num1;
    double num2;
};

struct s2 {
    int num3;
    double num4;
};

void io_init(struct s1*, struct s2*);

io.c

#include <stdio.h>
#include <stdlib.h>

#include "io.h"

void io_init(struct s1* s1i, struct s2* s2i)
{
    s1i->num1 = 5;
    s1i->num2 = 2.4;

    FILE *fp;
    char line[80];

    fp = fopen("input.txt","rt");

    fgets(line, 80, fp);
    sscanf(line,"%i",&s2i->num3);
    fgets(line, 80, fp);
    sscanf(line,"%i",&s2i->num4);

    fclose(fp);
}

alg.h

void ga_init(struct s1);

alg.c

#include <stdio.h>

#include "io.h"
#include "ga.h"

void ga_init(struct s1 s1i)
{
    printf("%i", s1i.val1);
}

main.c:

#include <stdio.h>

#include "io.h"
#include "ga.h"

int main() {
    struct s1 s1i;
    struct s2 s2i;

    io_init(&s1i, &s2i);
    ga_init(s1i);

    return 0;
}

【问题讨论】:

  • "任何移动结构的尝试都会导致程序无法编译" 您想将结构移动到哪里?他们在正确的地方,就在他们所在的地方:)
  • 要么全部在它们自己的文件中,例如全部在 structs.h 中,要么在每个文件中。我试图读入的数据是简单的配置数据,所以我想要一个包含 max_iter 的结构,然后将该结构传递给稍后声明的需要该变量的函数。

标签: c


【解决方案1】:

每个需要声明类型(即,想要使用它们)的文件都必须包含你的头文件(好的,所以前向声明和指针可以工作,但是如果没有定义,它们就不能被取消引用,这不是真的无论如何都适用于此。)

所以,详细地说,如果文件 X 需要使用struct Y,那么它需要包含包含其声明的头文件,就是这样。

/* X.c */
#include "Y.h"  /* <-- that's it! */

void foo(Y *obj) {
    /* ... */
}

【讨论】:

  • 所以我可以在我使用它们的文件中声明一堆结构,然后将它们全部包含在 io.h 文件中以最初从文件中设置它们的值?
  • 我认为您混淆了对象及其类型定义。下面声明了一个结构类型:struct x { int y; };。这将创建一个该类型的对象,您可以使用它来执行它的用途:struct x my_instance; my_instance.y = 10;
  • 那么我是在头文件中声明类型定义,在main中声明对象,还是在头文件中都声明?
  • 是的。声明(定义,虽然这些术语并不意味着相同的东西,它可以用于此目的)进入头文件。这告诉用户你的结构是什么样的。然后,在包含头文件(在本例中,在 main 函数中)之后,您可以在任何需要的地方创建该类型的对象。将声明视为模板,说明如何构建该类型的对象。
  • @user1801359:没问题。你觉得这一切都有意义吗?
【解决方案2】:

这里有一些建议。

  • 您的.h 文件未定义结构对象。它只是定义类型。它的方式很好。每个接触这些类型结构的人都应该包含这个文件。

  • 在调用ga_init 时,很少需要按值传递结构。您基本上总是希望通过引用进行调用,就像您对 io_init 所做的那样。

  • 是的,您可以返回一个结构,但同样,返回一个对结构的引用几乎总是更好。

  • 您当然可以共享全局定义的结构,并且不需要extern,除非您的链接器很糟糕。但是共享对在main() 中分配的结构的引用大致相同。

【讨论】:

    猜你喜欢
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多