结构中的一个元素可以访问C中的另一个元素吗?
我想在结构S中声明一个int num。那么同一个结构也应该有一个大小为num的数组B(因此结构中的一个元素可以访问C中的另一个元素吗?,c,pointers,struct,C,Pointers,Struct,我想在结构S中声明一个int num。那么同一个结构也应该有一个大小为num的数组B(因此B将从它自己的结构访问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
B
将从它自己的结构访问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
};
有什么方法可以做到这一点吗?使用灵活的数组成员:
struct S {
int num;
int data[];
};
int x = 42;
struct S *p = malloc(sizeof (struct S) + sizeof (int [x]));
p->num = x;
当您在全局内存中“灵活地声明”结构中的数组时,编译器会抱怨的原因是全局内存只能在编译时分配(声明),并且在编译时必须知道所有大小。(根据定义,在编译时变量的值是未知的。) 它在函数中接受灵活数组的原因是,函数的局部变量是在输入函数时创建的,然后编译器可以接受变量大小。(这归结为编译器在堆栈上分配更多内存,并用大小抵消对局部变量的所有访问,但不同的编译器可能有不同的方法。)
#包括
整数大小;
结构{
int-num;
int a[size];//非法:大小必须在编译时已知
};
整数f(整数大小)
{
int a[size];//合法,因为在堆栈上分配了
....
}
以下是合法的:
#include <stdio.h>
#define A_SIZE 10
struct S {
int num;
int a[A_SIZE]; // legal: A_SIZE is known at compile time
};
#包括
#定义一个大小为10的
结构{
int-num;
int a[a_SIZE];//合法:a_大小在编译时已知
};
注:我不是C99程序员;我在这里可能有一些错误。这方面有几个问题
struct S {
int num;
int data[num];
};
这导致它无法按您希望的方式工作
首先,数组成员声明中使用的num
与结构类型的成员num
不同;编译器将数组声明中的num
视为常规标识符(即,它假定与struct
声明在同一范围内有一个名为num
的不同变量)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 {
size_t num;
int *data;
};
然后为数据
分配内存,作为为结构对象本身分配内存的单独操作:
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
、union
或enum
关键字消除歧义)、struct
和union
成员名称消除歧义)(由
和->
组件选择运算符消除歧义)以及其他所有操作。由于数组声明中的num
不是
或->
的操作数,编译器将其视为正则变量名。2.6.7.2.1/9:“结构或联合体的成员可具有除可变修改类型以外的任何完整对象类型。”
2.6.2.7.1/3:结构或接头不得包含不完整或功能类型的构件(因此, 结构不应包含自身的实例,但可以包含指向实例的指针 除了具有多个命名成员的结构的最后一个成员 可能具有不完整的数组类型;这样的结构(以及任何包含 递归地,属于此类结构的构件)不得为结构或结构的构件 数组的元素。
首先,成员
num
直到结构定义结束时才声明,结构定义在最后一个}
结束
其次,将数组大小设置为未初始化变量的值有何意义
我认为您试图用int B[max]
创建一个可变长度数组(VLA)。但这也行不通,因为它们在结构中被明确禁止。6.7.2.1/9:
结构或联合的成员可以具有除
可变修改类型
相反,您可以声明一个灵活的数组成员,如Ouah的回答所示。对象无法访问C中的其他对象。这不是OOP。但您不是“访问”对象,而是使用可变数组大小的值。使用灵活数组成员并将其大小存储在“max”中(尽管我会称之为
length
或类似)…结构不能是动态的,它将具有固定的值..即使在结构之外,一个类似int data[num]的声明
并不意味着data
在您更改num
时将更改大小……它意味着data
将有一个固定的大小,这取决于num
在声明data
时的值。如果num
是数组的长度,最好使用该名称。其类型应为>size\u t
@Olaf我正在重用OP使用的成员名称,如果int
对于OP值来说足够宽,那么num
就不需要是size\u t
。OP的struct
没有定义对象。这只是struct
类型定义。但是,语法是不可能的,但是[]
(灵活的
struct S blah[10];
struct T {
struct S s;
...
};