我正在尝试编译这段代码,这给了我一个错误:灵活数组成员的静态初始化。我知道这是因为我正在将<figure> image1 </figure> <figcaption> <?php if(!empty($text1)) { echo $text1;} ?></figcaption>
<figure> image2 </figure> fig text2
<figure> image3 </figure> fig text3
和id
初始化为timestamp
,但是应该在运行时分配它们,而0直到那时都只是占位符
0
答案 0 :(得分:7)
您无法初始化灵活数组成员。根据C 2018 6.7.2.1 18,在大多数情况下,将忽略灵活数组成员。这是其中一种情况:在初始化中,就好像该成员不存在。
在声明语句中创建具有灵活数组成员的结构只能在数组中创建具有零成员的结构。要创建数组中具有更多成员的结构,应使用malloc
或类似的例程动态分配空间。一旦分配了足够的空间,就可以将指针转换为指向Category
的指针,然后为其成员分配(而不是初始化)值,包括其灵活数组成员的元素。
(可以想到,可能存在一种可怕的方式来定义包含具有可伸缩数组成员的结构的联合体,即通过用char
填充联合体,为数组的元素提供足够的空间。必要大小的数组。您仍然无法初始化这些元素,但可以分配给它们。请勿这样做。)
要设置一些原型Category
对象,可以使用:
static const Category category1 = {"Academic Registrar"};
static const Category category2 = {"Financial Services"};
static const Category category3 = {"IT Support", "IT"};
static const Category category4 = {"Parking Police", "PP"};
static const Category category5 = {"Coop Placement", "CP"};
稍后,要创建包含多个Category
元素的Ticket
,可以执行以下操作:
Category *C = malloc(sizeof *C + nTickets * sizeof(Ticket));
// Test C for NULL in case malloc failed.
// Copy initial data into new Category.
*C = category3;
// Assign values to Ticket elements.
for (int i = 0; i < nTickets; ++i)
{
C->ticket[i] = rand();
C->timestamp = 0;
}
请注意,您无法创建Category
对象的数组,因为它们具有灵活的大小,并且数组中的对象只能具有固定的大小。因此,一次只能使用一个Category
。上方的C
指针只能指向一个Category
,而不是它们的数组。但是C->ticket
成员是Ticket
的数组。
请注意,我不一定建议那样将数据从原型复制到Category
中。如果数据较短,则可以仅通过代码分配。如果数据很长,最好使用指向数据的指针,而不是将所有数据复制到每个数据中。好的解决方案取决于情况。上面的代码仅作为示例给出。
答案 1 :(得分:3)
对于静态持续时间的const
结构,在大多数情况下,一种可行的方法是声明一个结构,该结构的成员与FAM版本的成员相同,但将灵活数组成员替换为适当大小的数组,并且然后构造一个包含该类型的联合以及包含Flexible Array Member的联合。通用初始序列保证暗示可以使用这两种类型来检查通用成员,并且如果实现对C11草案(N1570)的脚注88有任何注意,则6.5p7的目的是指定情况可能是别名,它将避免使用该规则作为破坏此类代码的借口,因为对永不修改的存储的引用永远不会别名(别名涉及以下情况:对对象的重新排序访问会影响其语义;如果对象是永远不会修改,访问顺序永远不会有任何可观察到的效果。
从理论上讲,将允许将一个灵活的数组成员放置在与固定大小的数组不同的偏移量处,但是如果需要,代码可以使用静态断言来确保不会发生这种情况。故意钝化的解释可能会破坏事情,但是由于“一个程序规则”将允许故意钝化的实现破坏几乎任何程序,所以并没有说太多。
答案 2 :(得分:1)
此代码背叛了一些有关C的误解。以下是我认为是经过更正的版本,其中包含拼写和样式的修改:
#include <stdio.h>
#include <stdlib.h>
#include "input.h"
typedef struct Ticket {
int id;
long timestamp;
} Ticket;
typedef struct Categories {
char name[20];
char code[3];
// One ticket doesn't need an array.
Ticket ticket;
} Category;
void generateTickets(){
struct Ticket *ptr;
int nTickets = getNumTickets();
ptr = malloc(nTickets * sizeof(struct Ticket));
for(int i = 0; i < nTickets; i++)
{
// rand() % nTickets won't guarantee uniqueness
ptr[i].id = rand() % nTickets;
ptr[i].timestamp = 0;
}
}
void initializeCategories() {
// Nested initialisation for nested structs.
Category category1 = {"Academic Registrar", "AR", {0, 0}};
Category category2 = {"Financial Services", "FS", {0, 0}};
Category category3 = {"IT Support", "IT", {0, 0}};
Category category4 = {"Parking Police", "PP", {0, 0}};
Category category5 = {"Coop Placement", "CP", {0, 0}};
}