我正在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可以工作吗?
感谢大家的所有评论,想法和答案
答案 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;
}
实际上,这种方法类似于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填充)。添加初始化程序后,编译器会抱怨(如预期的那样),因为它多次被包含。