struct中的一个元素可以在C中访问其自身的另一个元素吗?

时间:2015-09-04 14:01:01

标签: c pointers struct

我想在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
};

我有什么方法可以做到这一点吗?

4 个答案:

答案 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

第二个问题是structunion类型可能没有可变长度数组作为成员 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关键字),enumstruct成员名称(由union.组件选择运算符消除歧义)以及其他所有内容。由于数组声明中的->不是num.的操作数,编译器会将其视为常规变量名。

2. 6.7.2.1/9:“结构或联合的成员可以具有除可变修改类型之外的任何完整对象类型。”

2. 6.2.7.1/3:结构或联合不得包含不完整或功能类型的成员(因此, 结构不应包含自身的实例,但可以包含指向实例的指针 它本身),除了具有多个命名成员的结构的最后一个成员 可能有不完整的数组类型;这样的结构(和任何包含的结合,可能 递归地,这种结构的成员不应该是结构的成员或者 数组的元素。

答案 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程序员;我可能在这里犯了一些错误。