如何在C中为匿名结构声明全局变量?

时间:2018-09-12 11:38:22

标签: c struct

我正在Windows 8.1上使用Pelles C。

如何在C语言中为结构声明单个全局变量?

代码1:它可以工作,但是我不希望创建任何其他相同类型的对象。如果代码2有问题,那么我将不得不使用此代码。

Single.h

struct single{
    int x;
};

extern struct single oneAndOnly;

void initSingle(void);
void printSingle(void);

Single.c

#include <stdio.h>
#include "Single.h"

struct single oneAndOnly;

void initSingle(void){
    oneAndOnly.x = 10;
}
void printSingle(void){
    printf("x = %d\n",oneAndOnly.x);
}

Main.c

#include "Single.h"
int main()
{
    initSingle();
    printSingle();
    return 0;
}

代码2:它可以工作,但是我不清楚在头文件中声明和定义变量的组合。会引起问题吗?我没错。

Single.h

struct{
    int x;
}oneAndOnly;

void initSingle(void);
void printSingle(void);

Single.c

#include <stdio.h>
#include "Single.h"

void initSingle(void){
    oneAndOnly.x = 10;
}
void printSingle(void){
    printf("x = %d\n",oneAndOnly.x);
}

Main.c与代码1中的相同。

我可以毫无问题地使用代码2吗?


当我和许多其他人认为代码2不能工作时,有人可以告诉我为什么代码2可以工作吗?


感谢大家的所有评论,想法和答案

3 个答案:

答案 0 :(得分:1)

您在其他编译单元中调用该函数。它使用全局变量而不是您的主程序。因此,您甚至不必知道数据结构和变量,因为您在新程序中会使用它们中的任何一个。

您可以将其缩减为:

void initSingle(void);
void printSingle(void);

int main()
{
    initSingle();
    printSingle();
    return 0;
}

#include <stdio.h>

struct{
    int x;
}oneAndOnly;

static struct single oneAndOnly;

void initSingle(void){
    oneAndOnly.x = 10;
}
void printSingle(void){
    printf("x = %d\n",oneAndOnly.x);
}

答案 1 :(得分:1)

您的任何尝试都不会付诸实践。

例如我可以做到的gcc或clang

typeof(oneAndOnly) secondInstance;

gcc也支持

__auto_type secondInstance = oneAndOnly;

(不确定c)。

即使有问题的编译器不支持这些扩展,我也可以从标头中复制/粘贴匿名结构声明。

也就是说,我看不出有什么方法可以阻止您购买其他相同类型的物品。在Java中,使构造函数private有意义,因为构造函数具有您可能希望限制其用途的行为,但是在C语言中,结构只是愚蠢的数据集合。

答案 2 :(得分:1)

可能有第三个变体。

它将struct single完全“隐藏”在Single.c中。因此,不可能意外访问。

Single.h

void initSingle(void);
void printSingle(void);

Single.c

#include <stdio.h>
#include "Single.h"

struct Single {
    int x;
};
static struct Single oneAndOnly;

void initSingle(void)
{
    oneAndOnly.x = 10;
}
void printSingle(void)
{
    printf("x = %d\n", oneAndOnly.x);
}

main.c

#include "Single.h"

int main()
{
    initSingle();
    printSingle();
    return 0;
}

Live Demo on Wandbox

实际上,这种方法类似于P__J__'s answer。我只是太慢了,无法按“发送”按钮。


我需要一些时间来认识到任务解决方案应该防止oneAndOnly类型的(偶然的)第二个变量。

使用静态实例“隐藏” C文件中的struct可能是C语言中最好的实例。即使在这种情况下,即使melpomene's answer中的计数器示例也无法使用。

如果需要对单个实例具有读/写访问权限,则可以添加“ getter” /“ setter”函数之类的东西。

这让我想起了Singleton pattern,尽管我不确定这对于非OO语言(例如C)是否合法使用。谷歌搜索了一下,我也发现How to create a Singleton in C?我值得一提。


我在OP的实际问题上搜索了一下她/他的代码2是否也有效。我怀疑类似重复的定义(可能是因为我在日常工作中使用C ++的时间太长了。)

实际上,我在Wandbox中尝试过OP的代码2 –没有重复的定义问题。最终,我发现Are the global variables extern by default or it is equivalent to declaring variable with extern in global?并得出结论,代码2也应该很好。

限制是代码2仅允许默认初始化(如果我没记错的话,请使用0填充)。添加初始化程序后,编译器会抱怨(如预期的那样),因为它多次被包含。