我有一个看起来像这样的结构。
struct MyStruct1 {
int (*fn)();
int b;
}
另一个结构看起来像这样。
struct MyStruct2 {
int a;
struct MyStruct1 b[0];
}
我想声明一个 MyStruct2 类型的全局变量,有点像这样。
int func1() { return 1; }
int func2() { return 2; }
struct MyStruct2 a = { 1, { func1, 5 }, { func2, 6 } };
但是,我收到“初始化程序元素不是编译时常量”。
我想知道(a)是否可以全局声明一个可变大小的结构(或者至少定义一 block 大小正确的空间,以便稍后插入值),以及(b )如果是的话,我做错了什么?
最佳答案
无论是本地还是全局,都不可能声明可变大小的struct
。每种类型都有一个在编译时确定的固定大小。
但是,您报告的错误消息令人惊讶。如果您给出的所有声明都在文件范围内,在同一个文件中,按照您给出的顺序,那么变量 a
的初始化器是编译时常量。但是,它不是 struct MyStruct2
的正确初始化程序,
- 因为它指定的元素多于
struct
类型拥有的成员, - 因为
a.b
的初始值设定项元素是struct MyStruct1
的初始值设定项,而不是此类数组的初始值设定项,并且 - 因为即使您将最后两个初始值设定项元素转换为一个数组初始值设定项,它的元素数量也会多于
a.b
中的元素数量(即大于零)。
如果您想要一个动态大小的数组,无论是作为其本身的变量还是作为struct
的成员,那么您必须声明一个指向它的指针,并为元素分配内存动态地。在这种情况下,元素本身并不是struct
的一部分;只有指向它们的指针是。 (顺便说一句,这与固定大小的数组不同,固定大小的数组的大小在其初始值设定项中是隐式的;不过,这些仅适用于独立类型,不适用于 struct
或 union< 的类型
成员)。
编辑: 正如 ShafikYaghmour 评论的那样,C99 灵活阵列是一种可能的替代方案。它们与作为指向动态分配数组的指针的 struct 元素类似,但不相同。但是,在这种情况下,您不仅无法静态声明数组元素,还无法静态声明 struct 本身的实例,因此这根本无法解决初始化程序问题。还有其他一些怪癖和限制。就我个人而言,我认为灵活数组没有什么优势,但它们确实使正确释放结构实例变得更容易。
关于c - 在 C 中声明具有可变大小的全局结构变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27807832/