1. 程式人生 > >Linux GNU C結構體陣列初始化示例

Linux GNU C結構體陣列初始化示例

實然心血來潮,想學習一下結構體陣列的初始化方面的知識。

以下是GCC實然心血來潮,想學習一下結構體陣列的初始化方面的知識。特有的陣列初始化的風格:

// 陣列賦值另一種方式,但只在gcc下編譯通過,g++不能
enum {
    AAA = 0,
	BBB,
	CCC,
	DDD,
};
// 只對感興趣的索引值進行賦值,而不管下標的順序
static const int regs[] = {
    [DDD] = 250,
    [CCC] = 3,
    [AAA] = 180,
};

這種風格在kernel程式碼中經常看到。它不按照陣列下標順序,而是使用自定義的“索引”來賦值,比如Intel網絡卡igb驅動中一處程式碼:
static const struct e1000_info *igb_info_tbl[] = {
	[board_82575] = &e1000_82575_info,
};
從程式碼中可以清晰知道,這個結構體是針對82575的——board_82575比數字0更直觀易讀。

但是使用g++卻無法編譯,編譯錯誤提示如下:

sorry, unimplemented: non-trivial designated initializers not supported

下面再看看結構體陣列的初始化,先給出結構體的定義:

enum control_type
{
    TYPE_GPIO = 0,
    TYPE_IIC = 1,
    TYPE_SPI = 2,
};

typedef struct control_info_t {
    const char	*name;
    enum control_type type;
    int enable;
}control_info;

初始化方式一,依次給陣列內元素賦值,如下::
control_info control_info1[3] = 
    {
        {"FOO_GPIO", TYPE_GPIO, 1},
        {"FOO_IIC", TYPE_IIC, 0},
        {"FOO_SPI", TYPE_SPI, 1},
    };

方式二,先宣告再賦值,如下:

control_info control_info[3];
    control_info[TYPE_SPI].name = "FOO_SPI";
    control_info[TYPE_SPI].type = TYPE_SPI;
    control_info[TYPE_SPI].enable = 1;
方式三,不按照順序,只對感興趣幾項賦值,如下:
control_info control_info2[3] = 
    {
        [TYPE_SPI] = {"FOO_SPI", TYPE_SPI, 1},
        [TYPE_GPIO] = {"FOO_GPIO", TYPE_GPIO, 1},
    };
從這個方式上看,型別為SPI的“索引值”對應即為SPI,但無須理會型別SPI的具體值。

本文完整程式碼如下:

/**
結果:
struct test
250 0 180 3
111 name: FOO_IIC type: 1 enable: 0
222 name: FOO_GPIO type: 0 enable: 1
333 name: FOO_SPI type: 2 enable: 1
*/

#include <stdio.h>
#include <inttypes.h>

///////////////////////
// 簡單int型別的陣列
// 陣列賦值另一種方式,但只在gcc下編譯通過,g++不能
enum {
    AAA = 0,
	BBB,
	CCC,
	DDD,
};
// 只對感興趣的索引值進行賦值,而不管下標的順序
static const int regs[] = {
    [DDD] = 250,
    [CCC] = 3,
    [AAA] = 180,
};

void struct_test1()
{
    printf("%d %d %d %d\n", regs[DDD], regs[BBB], regs[AAA], regs[CCC]);
}

///////////////////////
// 結構體陣列初始化示例
enum control_type
{
    TYPE_GPIO = 0,
    TYPE_IIC = 1,
    TYPE_SPI = 2,
};

typedef struct control_info_t {
    const char	*name;
    enum control_type type;
    int enable;
}control_info;

void struct_test_2()
{
    // c++風格,用g++並使用 -std=c++11
    //control_info gcontrol_info0 {.name = "FOO", .type = TYPE_SPI, .enable=1};

    // 三個依次賦值
    control_info control_info1[3] = 
    {
        {"FOO_GPIO", TYPE_GPIO, 1},
        {"FOO_IIC", TYPE_IIC, 0},
        {"FOO_SPI", TYPE_SPI, 1},
    };
    printf("111 name: %s type: %d enable: %d\n", control_info1[TYPE_IIC].name, control_info1[TYPE_IIC].type, control_info1[TYPE_IIC].enable);
    
    // GNU風格賦值
    control_info control_info2[3] = 
    {
        [TYPE_SPI] = {"FOO_SPI", TYPE_SPI, 1},
        [TYPE_GPIO] = {"FOO_GPIO", TYPE_GPIO, 1},
    };
    printf("222 name: %s type: %d enable: %d\n", control_info2[TYPE_GPIO].name, control_info2[TYPE_GPIO].type, control_info2[TYPE_GPIO].enable);
    
    
    // 只有一個賦值
    control_info control_info[3];
    control_info[TYPE_SPI].name = "FOO_SPI";
    control_info[TYPE_SPI].type = TYPE_SPI;
    control_info[TYPE_SPI].enable = 1;
    
    printf("333 name: %s type: %d enable: %d\n", control_info[TYPE_SPI].name, control_info[TYPE_SPI].type, control_info[TYPE_SPI].enable);
}

int main(void)
{
    printf("struct test\n");

    struct_test1();
    struct_test_2();
    
    return 0;
}

李遲 2016.10.13 週四  中午午休前