我想在struct S中声明一个int num。然后同一个struct也应该有一个大小为num的数组B(So B
将从它自己的struct访问num
。
在函数中,我可以做到,
func(int A)
{
int max=A; //I could use A directly, I am just trying to explain my plan.
int B[max];
}
同样不适用于struct,
struct S {
int num;
int data[num]; //this is wrong, num is undeclared
};
我有什么方法可以做到这一点吗?
答案 0 :(得分:6)
使用灵活的阵列成员:
struct S {
int num;
int data[];
};
int x = 42;
struct S *p = malloc(sizeof (struct S) + sizeof (int [x]));
p->num = x;
答案 1 :(得分:4)
有几个问题
struct S {
int num;
int data[num];
};
导致它无法以您想要的方式工作。
第一个是数组成员声明中使用的num
与结构类型成员的num
不同;编译器将数组声明中的num
视为常规标识符(即,它假定在与num
相同的范围内有一个名为struct
的变量。声明) 1 。
第二个问题是struct
或union
类型可能没有可变长度数组作为成员 2 。但是,结构中的最后一个成员可能具有不完整的数组类型:
struct S {
int num;
int data[];
};
不幸的是,你仍然被困在这里;如果您创建struct S
的实例
struct S foo;
它实际上并没有为数组分配任何空间。您需要动态分配结构:
/**
* Note that sizeof doesn't try to actually dereference foo below
*/
struct S *foo = malloc( sizeof *foo + N * sizeof *foo->arr );
为数组本身分配空间。请注意,如果最后一个成员的数组类型不完整,则不能声明struct S
数组或将其用作其他结构或联合类型的成员。 3
老实说,您最好的选择是将结构定义为
struct S {
size_t num;
int *data;
};
然后为data
分配内存,作为为struct对象本身分配内存的单独操作:
struct S foo;
foo.num = some_value();
foo.data = malloc( sizeof *foo.data * foo.num );
由于struct S
现在具有已知大小,您可以声明它的数组,并且可以将其用作另一个结构或联合类型的成员:
struct S blah[10];
struct T {
struct S s;
...
};
<小时/> 1。 C支持四个不同的名称空间 - 标签名称(通过标签语法消除歧义),
struct
/ union
/ enum
标签名称(由于struct
的存在而消除歧义,{{ 1}},或union
关键字),enum
和struct
成员名称(由union
和.
组件选择运算符消除歧义)以及其他所有内容。由于数组声明中的->
不是num
或.
的操作数,编译器会将其视为常规变量名。
答案 2 :(得分:3)
首先,成员num
直到结构定义结束才被声明,结构定义在最后}
结束。
其次,将数组大小设置为未初始化变量的值有什么意义?
我认为您尝试使用int B[max]
创建一个可变长度数组(VLA)。但这也不会奏效,因为它们在结构中被明确禁止。 6.7.2.1/9:
结构或联合的成员可以具有除a之外的任何完整对象类型 可变修饰型。
你可以做的是声明一个灵活的数组成员,如Ouah的回答所示。
答案 3 :(得分:2)
当你&#34;灵活地宣布&#34;编译器抱怨的原因全局内存中struct的数组是因为全局内存只能在编译时分配(声明),在编译时必须知道所有大小。 (根据定义,在编译时不知道变量的值。)
它在函数中接受灵活数组的原因是因为函数的局部变量是在输入函数时创建的,然后编译器可以接受可变大小。 (归结为编译器在堆栈上分配更多内存并将所有对本地变量的访问抵消大小 - 但不同的编译器可能有不同的方法。)
<ul>
<li><b>My Title</b>:</li>
<li class="subtitle">Subtitle 1</li>
<li class="subtitle">Subtitle 2</li>
<li class="subtitle">Subtitle 3</li>
</ul>
以下是合法的:
#include <stdio.h>
int size;
struct S {
int num;
int a[size]; // illegal: size must be known at compile time
};
int f(int size)
{
int a[size]; // legal as a is allocated on the stack
....
}
P.s。:我不是C99程序员;我可能在这里犯了一些错误。