Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 结构成员[数组与指针]_C - Fatal编程技术网

C 结构成员[数组与指针]

C 结构成员[数组与指针],c,C,将C结构成员声明为大小为1的数组而不是指针有什么好处: struct { a_struct_t a_member[1]; ... }b_struct; 提前感谢这些是不同的东西 此类成员的名称是已分配内存的地址,分配在结构实例本身内部。您描述的是两个完全不同的东西。如果您有一个指针作为成员: a_struct_t* a_member; 那么它只是一个指针。结构内部没有分配内存来保存结构\u t。另一方面,如果您有一个大小为1的数组: a_struct_t a_member[1];

将C结构成员声明为大小为1的数组而不是指针有什么好处:

struct {
  a_struct_t a_member[1];
  ...
}b_struct;

提前感谢

这些是不同的东西


此类成员的名称是已分配内存的地址,分配在结构实例本身内部。

您描述的是两个完全不同的东西。如果您有一个指针作为成员:

a_struct_t* a_member;
那么它只是一个指针。结构内部没有分配内存来保存
结构\u t
。另一方面,如果您有一个大小为1的数组:

a_struct_t a_member[1];
然后,您的结构中实际上有一个
a\u struct
类型的对象。从内存的角度来看,它与将该类型的对象放入结构中没有太大区别:

a_struct_t a_member;
从使用角度来看,数组需要间接访问一个元素(即,您需要使用
*a_成员
而不是
a_成员
)。

“大小为1的数组而不是指针”?对不起,我不明白这种沉默有什么意义。如果您询问“大小为1的数组而不是普通成员(非数组)”,我会理解。但是“而不是指针”?指针与此有什么关系?它如何与数组互换,以证明问题的正确性

如果您真正想问的是为什么它被声明为大小为1的数组,而不是中的非数组

struct { 
  a_struct_t a_member; 
} b_struct; 
那么一个可能的解释就是著名的成语“struct hack”。您可能会看到这样的声明

struct { 
  ...
  a_struct_t a_member[1]; 
} b_struct; 
用于实现灵活大小的数组作为struct对象的最后一个成员。实际的struct对象稍后在一个足够大的内存块中创建,以容纳所需的任意多个数组元素。但是在本例中,数组必须是结构的最后一个成员,而不是像您的示例中那样的第一个成员


另外,有时您可能会看到“struct hack”是通过大小为0的数组实现的,这实际上是C中的一个约束冲突(即编译错误)。

在典型情况下,如果结构中的成员声明为一个项的数组,则该成员将作为结构中的最后一项。其目的是动态分配结构。分配时,代码将为该数组中您真正想要/需要的任意多个项目分配空间:

struct X {
    time_t birthday;
    char name[1];
};

struct X *x = malloc(sizeof(*x) + 35);
x->birthday = mktime(&t);
strcpy(x->name, "no more than 35 characters");
这对于字符串尤其有效——您在结构中分配的字符为NUL终止符提供了空间,因此,在进行分配时,您分配的字符数正好是您要放置在那里的字符串的
strlen()
。对于大多数其他类型的项目,您通常希望从分配大小中减去一个(或者只需将分配的空间设置为比严格要求的大一个项目)


您可以使用指针执行(某种程度上)相同的操作,但这会导致将结构体与通过指针引用的项分开分配。好的一点是(与上面的方法不同)可以动态分配多个项,而上面的方法只适用于结构的最后一个成员。

因此我认为有人指出,指针和数组之间的主要区别在于必须为指针分配内存

问题中棘手的部分是,即使在为结构分配空间时,如果结构包含指针,则必须为指针分配第二次空间,但指针本身将作为结构分配的一部分进行分配


如果您的结构包含一个1的数组,则不必分配任何额外的内存,它将存储在结构中(您仍然需要分配)。

否,它不是“分配内存的指针”。它是分配给内存本身的。这里没有“指针”,但正如Brian W.Kernighan和Dennis M.Ritchie在他们的《C编程语言》一书中所说:“没有变量列表的结构声明不会保留任何存储空间;它只描述了结构的模板或形状。”因此,我对结构定义中的声明和内存分配问题感到困惑。你能再解释一下吗。谢谢,但正如Brian W.Kernighan和Dennis M.Ritchie在他们的书《C编程语言》中所说:“没有变量列表的结构声明不会保留任何存储空间;它只描述了结构的模板或形状。”因此,我对结构定义中的声明和内存分配问题感到困惑。@Walidix:这允许您执行
struct thing{…}struct thing,something[thingCount]。无论哪种方式,
struct thing
的解释在将成员声明为数组或指针之间都有所不同。在处理数据通信数据包时,经常使用struct hack,其中“有效负载”(或“数据包的其余部分”)作为结构中的最后一个成员自然发生。仅举一个具体示例说明通常使用可变长度结构的位置。一点真实的上下文有助于解释struct hack的“好处”(用OP的话来说);在结构的末尾,gcc允许您使用char name[0];就为了这个目的,在一个结构的末尾有很长一段时间。