重新审视C中的字符串初始化数组

时间:2013-12-18 09:31:19

标签: c arrays string initialization

我想在普通C中初始化一个具有以下要求的字符串数组:

(A)我需要头文件中的字符串,因为其他一些模块使用它们作为普通字符串,所以我在头文件中声明:

extern const char* const ERRMSG_VM_0001;
extern const char* const ERRMSG_VM_0002;
extern const char* const ERRMSG_VM_0003;
extern const char* const ERRMSG_VM_0004;

并在源文件中:

const char* const ERRMSG_VM_0001 = "[VM-001] some text ";
const char* const ERRMSG_VM_0002 = "[VM-002] more text ";
const char* const ERRMSG_VM_0003 = "[VM-003] other text ";
const char* const ERRMSG_VM_0004 = "[VM-003] and even more";

(B)我在数组中也需要这些字符串,所以我尝试了(相同)源代码(如上所述):

static const char* error_table[4] =
{
    ERRMSG_VM_0001,
    ERRMSG_VM_0002,
    ERRMSG_VM_0003,
    ERRMSG_VM_0004
};

显然,编译器抱怨error: initializer element is not constant ...所以现在我想知道如何以纯C的方式实现这一点,而不是C++(这类似于{{3}但它不一样)。

4 个答案:

答案 0 :(得分:3)

编译器能够找到匹配的字符串文字并优化二进制文件。 (可能是一种选择)

我建议只声明定义并创建一个const

#define ERRMSG_VM_0001 "[VM-001] some text "
...

static const char* error_table[4] =
{
    ERRMSG_VM_0001,
    ERRMSG_VM_0002,
    ERRMSG_VM_0003,
    ERRMSG_VM_0004
};

现在好了。 生成的二进制代码将是您想要的代码。

答案 1 :(得分:1)

static const char* error_table[4] =
{
    "[VM-001] some text ",
    "[VM-002] some text ",
    "[VM-003] some text ",
    "[VM-004] some text ",
};

然后

ERRMSG_VM_0001 = error_table[0];

答案 2 :(得分:0)

ERRMSG_VM_0001是一个变量。但在C ++中它将是一个常量表达式。这就是为什么C ++允许相同但C不允许的原因。 你不能用C语言做到这一点。

const int a = 10;
const int arr[] = { a };

你可以这样做......

//Is in header.h
extern const char* const ERRMSG_VM_0001;
extern const char* const ERRMSG_VM_0002;
extern const char* const ERRMSG_VM_0003;
extern const char* const ERRMSG_VM_0004;

//This is in main.c
#include "header.h" 
static const char* error_table[4] =
{
    "[VM-001] some text ",
    "[VM-002] some text ",
    "[VM-003] some text ",
    "[VM-004] some text ",
};

int main(void)
{
    const char* const ERRMSG_VM_0001 = error_table[0]; // Works fine
    return 0;
}

答案 3 :(得分:0)

如果可以将数组元素的类型从char *更改为char **,则可以对数组进行初始化:

static const char* const* const error_table[4] =
{
    &ERRMSG_VM_0001,
    &ERRMSG_VM_0002,
    &ERRMSG_VM_0003,
    &ERRMSG_VM_0004
};