【问题标题】:How to initialize a a struct of structs inside a header file in C?如何在C的头文件中初始化一个结构结构?
【发布时间】:2010-12-20 15:16:51
【问题描述】:

我正在尝试将一些旧代码从 20 年前的 DOS 系统移植到 GNU Linux 系统。在它们的几个头文件中(到处都包含),它们具有声明和初始化的结构体。当我使用遗留代码的编写方式进行编译时,我收到了警告。关于如何让它在同一个头文件中工作的任何提示?

以下是我为他们所做的简化示例。

struct A
{

    struct B  temp1;
    struct C  temp2;
};

struct B
{

    int temp3;
    int temp4; 
    int temp5;
};

struct C
{

    int temp6;
    int temp7;
    int temp8;
};


//These are the variables in how they are related to the initialization below

//struct A test_one = {{temp3,temp4,temp5},{temp6,temp7,temp8}};

struct A test_one = {{1,2,3},{4,5,6}};

【问题讨论】:

    标签: c header struct initialization gnu


    【解决方案1】:

    您不应该在头文件中实例化任何结构。如果你在每个 C 文件中创建不同的实例,你会在其中包含通常不是所需效果的标题。

    要在 C 文件中执行此操作,您必须执行以下操作。

    void foo(){
    struct A parent;
    struct B child_b;
    struct C child_c;
    
    child_b.temp3 = 3;
    child_b.temp4 = 4;
    child_b.temp5 = 5;
    
    child_c.temp6 = 6;
    child_c.temp7 = 7;
    child_c.temp8 = 8;
    
    parent.temp1 = child_b;
    parent.temp2 = child_c;
    }
    

    我强烈考虑制作类似于此的辅助函数

    void initB(struct B* s, int x, int y, int z){
        s->temp3 = x;
        s->temp4 = y;
        s->temp5 = z;
    }
    

    如果您希望保留数组初始化语法,请考虑使用联合。

    【讨论】:

    • 尤其是它们没有被声明为静态的。我知道几年前有人做过类似的事情,而不是抱怨,对于每个对多重定义变量的引用,链接器似乎随机使用了其中一个实例。
    • @JeremyP:你必须在头文件中声明变量extern,并在一个编译单元中实例化和初始化它。
    • 我实际上尝试在 C 文件而不是头文件中做同样的事情,我得到了同样的警告。我想我应该将原始问题重新表述为“如何在 C 中初始化一个结构的结构?”。我收到的警告是“初始化程序周围缺少括号”警告以及“...的接近初始化”警告。
    • @ Jens Gustedt:我知道这就是你的本意,但这个人在标题中定义变量并将其包含在几个地方。这意味着链接的二进制文件中存在多个具有相同名称和外部链接的变量(在 C 中,没有存储说明符的变量默认被视为extern)。
    • 所以我再问一次,如果您正在初始化“struct A test_one”,您将如何实际写出它?因为这 -> "{{1,2,3},{4,5,6}}" 不起作用。
    【解决方案2】:

    在A之前声明结构B和C,即:

    struct B { int temp3; int temp4; int temp5; };
    struct C { int temp6; int temp7; int temp8; };
    struct A { struct B temp1; struct C temp2; };
    

    【讨论】:

    • 我的错,我只是在编一个简单的例子。在实际代码中,“struct A”是在 B 和 C 之后声明的。
    【解决方案3】:

    您发布的代码不可编译,因为使用不完整类型声明struct 成员是非法的。我假设您只是错误地安排了您的 struct 定义:BC 的定义应该放在第一位。

    话虽如此,如果头文件包含在多个翻译单元中,则此代码可以生成的唯一警告是来自链接器的“警告”,它可能会抱怨同一对象 test_one 的多个定义。在 C 中,这在技术上是非法的,尽管许多编译器允许它作为流行的编译器扩展。

    那么,你得到了什么“警告”?

    【讨论】:

    • 我收到“初始化程序周围缺少括号”警告以及“...的接近初始化”警告。
    猜你喜欢
    • 1970-01-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多