我遇到了以下代码,它以非标准方式在char *
中声明C
数组:
/* Message Type description array */
char *msgType[M_LAST_MSG] =
{
[M_INIT_MSG] "Init",
[M_RESET_MSG] "Serdes Reset"
};
M_INIT_MSG
,M_RESET_MSG
和M_LAST_MSG
是枚举,其对应值为0,1和2。
根据正式的C
文档,这个数组中的变量是字符串(文字),那么以这种方式使用这些枚举的目的是什么,是否有任何文档备份它?
使用ARM gcc
编译器gcc-arm-none-eabi
编译。
答案 0 :(得分:6)
此语法允许您通过索引初始化数组的特定元素。您可以使用int
或enum
值来指定要初始化的数组元素。这样,您指定的值不需要是连续的。
例如,如果你有这个:
int x[5] = { [2] 3, [4] 7 };
这相当于:
int x[5] = { 0, 0, 3, 0, 7 };
在上面的示例中,枚举值指定数组的元素0和1初始化为"Init"
和"Serdes Reset"
。
来自C99 standard的第6.7.8节:
18每个指定者名单都以其开头描述 当前对象与最近的周围支撑相关联 对。指定符列表中的每个项目(按顺序)指定 它当前对象的一个特定成员并改变了 下一个指示符(如果有)的当前对象是该成员。 在指定符列表末尾生成的当前对象是 要由以下初始化程序初始化的子对象。
33示例9可以初始化阵列以对应于 使用指示符进行枚举的元素:
enum { member_one, member_two }; const char *nm[] = { [member_two] = "member two", [member_one] = "member one", };
编辑:
请注意,标准中的语法包含=
,而OP的示例则不包括=
。没有head -1 filename | awk -F "\t" '{i=0;med=0;for(i=2;i<=NF;i++) array[i]=$i;asort(array);print length(array)}'
的语法显然是GCC支持的旧语法。编译OP的示例会发出以下警告:
警告:过时使用没有'='的指定初始化程序
GCC documentation声明如下:
自GCC 2.5以来已经过时的替代语法已经过时,但GCC仍然接受的是在元素值之前写'[index]',没有'='。
答案 1 :(得分:3)
那是GNU extension。它在C99中标准化,语法略有不同,即[index]和值之间的等号,无法指定索引范围。它们被称为指定的初始化器。
C标准显示了可能最广泛使用的示例,为枚举提供字符串描述:
33示例9 可以使用指示符初始化数组以对应枚举元素:
enum { member_one, member_two };
const char *nm[] = {
[member_two] = "member two",
[member_one] = "member one",
};
它甚至允许像
这样的漂亮东西示例11 当未经修饰的初始化列表可能被误解时,可以使用指示符提供显式初始化:
struct { int a[3], b; } w[] =
{ [0].a = {1}, [1].a[0] = 2 };