我在C中处理以下问题。我在代码中使用全局变量来定义一些全局参数。我希望这样的全局变量是常量,即使它们必须在从输入数据文件读取值的例程中初始化。简而言之,我正在寻找一种在C中初始化变量时"消除"常量的好方法(我想在C++中,由于const_cast
,这不会是一个问题)
我想出了一个基于宏的模式来做到这一点,如下所示。它似乎很好用,但我有以下问题。有人在下面的程序中看到任何隐藏的缺陷或潜在的危险吗?有人会反对下面的方法而选择更简单的方法吗?
我的方法:
我有一个主头文件,其中包含我的全局变量(int N
)的定义,就像一样
/* main_header.h */
#ifdef global_params_reader
#define __TYPE__QUAL__
#else
#define __TYPE__QUAL__ const
#endif
__TYPE__QUAL__ int N;
我有一个实现N初始化的文件"get_global_params.c",它将N视为"int N
"(因为它在定义global_params_reader
后包括"main_header.h")
/* get_global_params.c */
#define global_params_reader
#include get_global_params.h
void get_global_params(char* filename){
N = ... ; // calling some function that reads the value of N from
// the datafile "filename" and returns it
}
以及相应的头文件"get_global_params.h"
/* get_global_params.h */
#include "main_header.h"
void get_global_params(char* filename);
最后,我有一个main.c,它将N视为"const int N
"(因为它包括"main_header.h"而没有定义global_params_reader
):
/* main.c */
#include "main_header.h"
#include "get_global_params.h"
int main(int argc, char **argv){
// setting up input data file //
...
// initialize N //
get_global_params(datafile);
// do things with N //
...
}
我希望我的解释足够清楚。感谢您的反馈。
只需将全局变量包含在一个单独的文件中。
globl.h:
struct Globals{
int N;
//...
};
extern const struct Globals *const globals;
init_globl.h:
init_globals(/*Init Params*/);
globl.c
#include globl.h
#include init_globl.h
static struct Globals _globals;
const struct Globals *const globals = &_globals;
init_globals(/*Init Params*/){
// Initialize _globals;
//...
}
现在,您可以在启动时通过在任何需要访问该功能的文件中包含init_globl.h来初始化全局变量,其他人只需包含globl.h并使用符号globals->N
就可以直接访问全局变量。
如果我是你,我会简单地避免这种全局变量。相反,我将用所有这些程序参数定义一个struct
,并定义一个函数,该函数返回指向该struct
(singleton模式)的唯一实例的const
指针。这样,返回指针的函数可以非常量地访问singleton,而程序的整个其余部分则不能。这正是您所需要的,它干净且面向对象,因此没有理由乱用宏和强制转换。
实例可以声明为函数中的静态变量,也可以malloc‘ed为静态指针。这其实并不重要,因为这是该函数的实现细节,永远不会泄露给外部。代码的其余部分也不需要知道参数何时被实际读取,它只调用函数,并获得唯一一个具有所有有效参数的对象。
"我希望这样的全局变量是常量,即使它们必须在从输入数据文件读取值的例程中初始化。"
在运行时无法在c中初始化const
。在c中,值有或没有const
限定符,并且它是在声明时定义的。c不支持更改它。语义是固定的。但一些引用该标准的专家会更好、更可靠。
我认为这在c++中也不可能,但我不会打赌,因为c++可以在这里和那里发挥一些魔力。