ato*_*her 5 c arrays syntax structure initialization
为什么有人会这样做?更好的是,这甚至如何工作?我会假设这将以某种方式创建一个三个结构的数组,只定义了第一个成员.我意识到一个指针指向数组的第一个元素,我看到它是如何工作的,但是如何定义它会让我失望!(gcc 4.8.4)
void do_something(const void *);
typedef struct{
int a;
char b;
int c;
} the_data_t;
int main(int argc, char *argv[])
{
the_data_t my_data[] = {10, 'a', 30};
do_something((const void *)my_data);
}
void do_something(const void *data)
{
printf("data a: %d\ndata b: %c\ndata c: %d\n", ((the_data_t*)data)->a,
((the_data_t*)data)->b, ((the_data_t*)data)->c);
}
Run Code Online (Sandbox Code Playgroud)
产量
数据a:10个
数据b:
数据c:30
无论如何,我把它改成了..
int main(int argc, char *argv[])
{
the_data_t my_data = {10, 'a', 30};
do_something(&my_data);
}
Run Code Online (Sandbox Code Playgroud)
我会假设这将以某种方式创建一个三个结构的数组,只定义了第一个成员
不,不是那样的.基本上它创建了一个元素的数组,所有成员都是初始化的.
引用C11,章节§6.7.9
每个大括号括起的初始化列表都有一个关联的当前对象.当没有指定时,根据当前对象的类型按顺序初始化当前对象的子对象:增加下标顺序的数组元素,声明顺序中的结构成员,以及union的第一个命名成员.[...]
和
每个指示符列表以与最近的周围括号对相关联的当前对象开始其描述.指定符列表中的每个项目(按顺序)指定其当前对象的特定成员,并将下一个指示符(如果有)的当前对象更改为该成员.150)在指定符列表末尾产生的当前对象是由以下初始化程序初始化的子对象.
和
[...]如果子聚合或包含联合的初始值设定项以左括号开头,则由该括号括起的初始值设定项及其匹配的右括号初始化子聚合或包含的联合的元素或成员.否则,仅从列表中获取足够的初始值设定项以考虑子集合的元素或成员或所包含的并集的第一个成员; [...]
基本上,你的代码应该非常像
the_data_t my_data[] = {{10, 'a', 30}};
Run Code Online (Sandbox Code Playgroud)
可视化初始化一个元素.
OTOH,你期望的可能是通过
the_data_t my_data[] = {{10}, {'a'}, {30}};
Run Code Online (Sandbox Code Playgroud)
它创建一个包含3个元素的数组,所有元素都a 初始化成员变量.
那说,
the_data_t my_data[] = {{10, 'a', 30}};
Run Code Online (Sandbox Code Playgroud)
相当于写作
the_data_t my_data = {10, 'a', 30};
Run Code Online (Sandbox Code Playgroud)
除了部分之外,my_data将不再是一个数组(但是一般来说,一个元素数组有什么用呢?).