2017-02-14 149 views
3

的陣列我們大概知道C99 designated initializers,它們可以被用來初始化大常量數組的方式:指定初始化數組

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

哪個initalizes的vals指數010vals12指數10

我的問題是如何使用這種風格的指定初始化器陣列的數組。這裏是我的示例代碼:

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

回答

7

值的支撐列表無法初始化指針。你的錯誤是一樣的:

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

你可以使用一個複合文字來代替:

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

這是假定該代碼是在文件範圍內(即在任何函數之外),這意味着複合文字具有靜態存儲時間,因此指向它們是安全的。如果你的代碼實際上在一個函數內,你需要聲明單獨的靜態數組或者做一些其他修改。

+0

感謝您的回答!我不知何故錯過了它。我想知道如果我可以在沒有聲明單獨的靜態數組的情況下在函數範圍內擁有所有這些定義,我是否可以有你的意見。 我沒有其他理由讓它們成爲全局的,因爲在我的項目中有這樣的多個定義,它們都不需要在全局範圍內。 – milaniez

+1

@milaniez你可以刪除'static'(假設你的函數沒有返回指向複合文字的指針)。除此之外,如果保持代碼整潔,將它們移動到文件範圍並沒有什麼實際壞處。 –