在C中定义常量数组

时间:2017-06-23 17:50:09

标签: c linux

我知道,在SO中有一些类似主题的问题,但没有一个真正回答这个问题。

通常您按如下方式定义常量数组:

const char arr[] = {0x00, 0x01, 0x02, 0x03}

问题“我可以使用#define指令执行完全相同的操作吗?”主要通过一个简单的 no 来回答,但我偶然发现了一个头文件lxr,寻找结构。那是我发现的时候:

extern const struct in6_addr in6addr_any;
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
extern const struct in6_addr in6addr_loopback;
#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
extern const struct in6_addr in6addr_linklocal_allnodes;
#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
    { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
extern const struct in6_addr in6addr_linklocal_allrouters;
#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
    { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } }
extern const struct in6_addr in6addr_interfacelocal_allnodes;
#define IN6ADDR_INTERFACELOCAL_ALLNODES_INIT \
    { { { 0xff,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
extern const struct in6_addr in6addr_interfacelocal_allrouters;
#define IN6ADDR_INTERFACELOCAL_ALLROUTERS_INIT \
    { { { 0xff,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } }
extern const struct in6_addr in6addr_sitelocal_allrouters;
#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT \
    { { { 0xff,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } }
#endif

(见http://elixir.free-electrons.com/linux/v4.12-rc6/source/include/linux/in6.h

这只能在内核中运行,还是有特定方法可以为任何阵列实现这一目标?

3 个答案:

答案 0 :(得分:2)

上面显示的#defines用作初始化特定类型结构的简写。

使用您提供的示例:

const char arr[] = {0x00, 0x01, 0x02, 0x03}

您还可以执行以下操作:

#define ARR_INIT {0x00, 0x01, 0x02, 0x03}
const char arr[] = ARR_INIT;

答案 1 :(得分:0)

您可以使用C99 / C11复合文字:

#define MY_ARR (const char []){0x00, 0x01, 0x02, 0x03}

定义没有“type-cast”(初始化器宏)只有在左侧是预期的情况下才能正常工作。

答案 2 :(得分:0)

您引用的是初始值设定项,它们旨在用作

struct in6_addr addr_any = IN6ADDR_ANY_INIT;

这些初始化程序不能在C中形成自给自足的表达式,不能用于任何其他角色。所以,不,它们本身不是#define版本arr。您无法使用它们,例如IN6ADDR_ANY_INIT[5]

使用arr替换#define需要使用复合文字(C99及更高版本的功能)

#define arr (const char []) {0x00, 0x01, 0x02, 0x03}

您可以使用这些初始值设定项来构建复合文字,例如

(struct in6_addr) IN6ADDR_ANY_INIT.s6_addr[8]

但目前尚不清楚这是否是您想要做的。