【问题标题】:Designated Initializer for array of arrays数组数组的指定初始化器
【发布时间】:2017-02-14 20:28:21
【问题描述】:

我们可能知道 c99 中的 designated initializers 以及它们可用于初始化大型 const 数组的方式:

const int vals[] = {
    [0] = 10,
    [10] = 12
}

vals 的索引0 初始化为10 并将vals 的索引10 初始化为12

我的问题是如何将这种风格的指定初始化程序用于数组数组。这是我的示例代码:

typedef enum {
    COMMON = 0,
    STRINGS,
    KEY,
    PRECUSSIVE,
    GUITAR,
    KEYBOARD,
    BASS,
    PIANO,
    DRUMS,
    _INST_MAX
} instrument_classification_t;
static const int * const instrument_class_hierarchy[] = {
    [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
    [STRINGS] = {GUITAR, BASS, _INST_MAX},
    [KEY] = {PIANO, KEYBOARD, _INST_MAX},
    [PRECUSSIVE] = {DRUMS, _INST_MAX},
    [GUITAR] = NULL,
    [KEYBOARD] = NULL,
    [BASS] = NULL,
    [PIANO] = NULL,
    [DRUMS] = NULL
};

但我收到这些警告,暗示初始化仅使用第一个元素。

main.c:166:3: warning: braces around scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
   ^
main.c:166:3: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:15: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
           ^
main.c:166:15: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:24: warning: excess elements in scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
                    ^
main.c:166:24: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:29: warning: excess elements in scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
                         ^
main.c:166:29: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:166:41: warning: excess elements in scalar initializer
   [COMMON] = {STRINGS, KEY, PRECUSSIVE, _INST_MAX},
                                     ^
main.c:166:41: note: (near initialization for 'instrument_class_hierarchy[0]')
main.c:167:3: warning: braces around scalar initializer
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
   ^
main.c:167:3: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:167:16: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
            ^
main.c:167:16: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:167:24: warning: excess elements in scalar initializer
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
                    ^
main.c:167:24: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:167:30: warning: excess elements in scalar initializer
   [STRINGS] = {GUITAR, BASS, _INST_MAX},
                          ^
main.c:167:30: note: (near initialization for 'instrument_class_hierarchy[1]')
main.c:168:3: warning: braces around scalar initializer
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
   ^
main.c:168:3: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:168:12: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
        ^
main.c:168:12: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:168:19: warning: excess elements in scalar initializer
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
               ^
main.c:168:19: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:168:29: warning: excess elements in scalar initializer
   [KEY] = {PIANO, KEYBOARD, _INST_MAX},
                         ^
main.c:168:29: note: (near initialization for 'instrument_class_hierarchy[2]')
main.c:169:3: warning: braces around scalar initializer
   [PRECUSSIVE] = {DRUMS, _INST_MAX},
   ^
main.c:169:3: note: (near initialization for 'instrument_class_hierarchy[3]')
main.c:169:19: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
   [PRECUSSIVE] = {DRUMS, _INST_MAX},
               ^
main.c:169:19: note: (near initialization for 'instrument_class_hierarchy[3]')
main.c:169:26: warning: excess elements in scalar initializer
   [PRECUSSIVE] = {DRUMS, _INST_MAX},

【问题讨论】:

    标签: c c99


    【解决方案1】:

    花括号的值列表不能初始化指针。您的错误与以下相同:

    int *p = { 1, 2, 3 };
    

    您可以改用复合文字:

    // ...
    [COMMON] = (const int[]){STRINGS, KEY, PRECUSSIVE, _INST_MAX},
    

    这假定代码在文件范围内(即在任何函数之外),这意味着复合文字具有静态存储持续时间,因此指向它们是安全的。如果您的代码实际上是在函数内部,则需要声明单独的静态数组或进行一些其他修改。

    【讨论】:

    • 感谢您的回答!我不知何故错过了它。我想知道我是否可以就如何在函数范围内拥有所有这些定义而不声明单独的静态数组有你的意见。我没有其他理由将它们设为全局,因为在我的项目中有多个这样的定义,它们都不需要在全局范围内。
    • @milaniez 您可以删除 static (假设您的函数不返回指向复合文字的指针)。除此之外,如果您保持代码整洁,将它们移动到文件范围并没有真正的危害。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多