我该如何进行全局常量初始化?有可能吗?还是有另一种方法可以做我想要的?我的意思是我需要从main()
获得的全局参数,并且它们必须是常量。
#include <stdio.h>
#include <stdlib.h>
const int var;
int main(int argc, char *argv[]) {
var = atoi(argv[1]);
/* ... */
return 0;
}
答案 0 :(得分:3)
我需要从main()获取的全局参数,并且它们必须是常量。
没有OP想要的直接执行的便携式方法。
代码需要不同的读取和写入权限。有效地隐藏了对真实数据的访问。
一种封闭的解决方案,它可以通过另一个文件中定义的函数来设置和获取数据。那么一旦设置就无法更改数据,只能设置一次。
main_var.h
int main_var_get(void);
void main_var_set(int v);
main_var.c
#include <stdlib.h>
#include "main_var.h"
static int var; // This could instead be a struct of many members.
// Or a pointer to a struct with many members.
static int var_init;
int main_var_get(void) {
if (!var_init) {
// Handle call of get before set, perhaps exit or return default value
exit(EXIT_FAILURE);
}
return var;
}
void main_var_set(int v) {
if (var_init) {
// Handle 2nd set, perhaps exit or ignore
exit(EXIT_FAILURE);
}
var = v;
var_init = 1;
}
main.c
#include <stdio.h>
#include "main_var.h"
int main(void) {
main_var_set(42);
...
printf("%d\n", main_var_get());
}
另一种方法是使用const int *
。设置之前的访问与取消引用NULL
相同,即为否。尝试写*main_var_addr
是UB,就像写任何const
对象一样。
main_var.h
extern const int *main_var_addr;
void main_var_set(int v);
main_var.c
#include <stdlib.h>
#include "main_var.h"
const int *main_var_addr = NULL;
static int var;
void main_var_set(int v) {
if (main_var_addr) {
// Handle 2nd set attempt, perhaps exit or ignore
exit(EXIT_FAILURE);
}
var = v;
main_var_addr = &var
}
main.c
#include <stdio.h>
#include "main_var.h"
int main(void) {
main_var_set(42);
...
printf("%d\n", *main_var_addr);
}
答案 1 :(得分:1)
我不认为C允许您在其他地方初始化常量。但是,您可以将var从const更改为static。
答案 2 :(得分:0)
这是不可能的,实际上const
并不意味着变量在C中是恒定的,仅意味着不允许您更改变量的值,但是其他人可以。
全局值是在主运行之前初始化的,这意味着您无法在运行时进行初始化,这种初始化是如何实现的,因此是实现行为,因此没有“纯C”的方式来完成您要的操作。
但是,我不明白为什么不能封装全局变量:
my_var.h:
int init_my_var(int argc, char **argv);
int get_my_var(void);
my_var.c
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
static int var;
int init_my_var(int argc, char **argv) {
#ifndef NDEBUG
#include <stdbool.h>
#include <assert.h>
{
static bool first = true;
assert(first);
first = false;
}
#endif
if (argc < 2) {
return 1;
}
errno = 0;
long ret = strtol(argv[1], NULL, 10);
if (errno || (ret < INT_MIN || ret > INT_MAX)) {
return 2;
}
var = (int)ret;
return 0;
}
int get_my_var(void) {
return var;
}
main.c:
#include <stdio.h>
int main(void) {
printf("%d\n", get_my_var());
if (init_my_var(2, (char *[]){"", "42"})) {
return EXIT_FAILURE;
}
printf("%d\n", get_my_var());
if (init_my_var(2, (char *[]){"", "0"})) {
return EXIT_FAILURE;
}
}