【问题标题】:Revisiting the array of strings initialization in C重新审视 C 中的字符串数组初始化
【发布时间】:2013-12-18 09:31:18
【问题描述】:

我想用普通的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++(这类似于Tricky array Initialization,但不一样) .

【问题讨论】:

    标签: c arrays string initialization


    【解决方案1】:

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

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

    #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
    };
    

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

    【讨论】:

      【解决方案2】:
      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];
      

      【讨论】:

      • 奇怪的是,现在它抱怨:const char* ERRMSG_VM_0001 = error_table[0]; as initializer element is not constant ... 甚至剥离所有 const 都不起作用
      【解决方案3】:

      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;
      }
      

      【讨论】:

      • 但是在这种情况下其他使用ERRMSG_VM_0001的模块将看不到它的定义...
      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 2015-07-25
        • 2019-12-08
        • 2014-10-16
        • 1970-01-01
        • 2010-11-25
        相关资源
        最近更新 更多