语言: C
我正在尝试声明并初始化结构中的数组并将其传递给指针,该指针本身在struct xD中声明
是的,我知道我的尝试是......让我们说“不正确”:D 但如果存在类似的东西,那将非常有用。任何想法?
struct structname {
int* section_A;
int* section_B;
};
static const struct structname structvariable_a = {
.section_A = (int[]) {
[0x01] = 1,
[0x02] = 2,
[0x03] = 3
},
.section_B = (int[]) {
[0x33] = 4,
[0x34] = 5
},
};
static const struct structname structvariable_b = {
.section_A = (int[]) {
[0x01] = 10,
[0x02] = 20,
[0x03] = 30
},
.section_B = (int[]) {
[0x33] = 7,
[0x34] = 8
},
};
稍后,我想访问值...
int main()
{
struct structname* structvariablepointer;
if(foo == 1){
structvariablepointer = &structvariable_a;
} else {
structvariablepointer = &structvariable_b;
}
printf("%i", ARRAY_SIZE(structvariablepointer->section_A)); // ARRAY_SIZE(arr) equals sizeof(arr) / sizeof(arr[0]));
int b = 2;
printf("%i", structvariablepointer->section_A[b]);
}
唯一的错误是
./include/linux/build_bug.h:29:45: Fehler: Negative Breite in Bitfeld »<anonym>«
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
^
./include/linux/compiler-gcc.h:64:28: Anmerkung: bei Substitution des Makros »BUILD_BUG_ON_ZERO«
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:60:59: Anmerkung: bei Substitution des Makros »__must_be_array«
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
^~~~~~~~~~~~~~~
答案 0 :(得分:1)
我正在尝试声明并初始化结构中的数组并将其传递给指针,该指针本身在struct xD中声明
这没有任何意义,但在C99及更高版本中,您的实际代码几乎完全正确。特别是:
(int[]) { [0x01] = 1, [0x02] = 2, [0x03] = 3 }
既不是数组的初始化声明也不是(相当)初始化;相反,它是int
数组类型的复合文字。因为数组在给定的上下文中衰减为指针,就像在大多数情况下一样,这样的复合文字确实可以用于初始化类型int *
的结构成员(指向数组的第一个元素)。成功初始化这两个struct structname
对象后,您当然可以获取它们的地址并将其记录在变量中。
但是,指向数组元素的指针不包含有关数组中元素数量的信息。如果你拥有的就是main()
函数中的情况,那么就无法确定数组元素的数量。您需要能够从内容中确定(这就是C字符串必须以空值终止的原因),或者您必须从其他来源获取该信息,例如函数参数,变量或透视。
是的,我知道我的尝试是......让我们说“不正确”:D但是如果存在类似的东西会非常有用。
如果您声明struct structname
的成员是真正的数组,那么您可以访问并使用其声明的长度。如果您愿意,可以将数组元素的数量存储在该结构的其他成员中。这两种方法都是在野外使用的,基于指向元素的内容的方法也是如此。但是我不认为C会像你想要的那样获得使你的ARRAY_SIZE()
宏用指针工作的工具。
答案 1 :(得分:0)
一旦指针指向数组的第一个元素,就无法再通过该指针找到数组的大小。因此,您还需要创建变量来保存数组大小。 (或者在数组末尾使用sentinel值。)
解决问题的一种方法是通过丑陋的宏:
#include <stddef.h>
#define ARRAY_SIZE(a) ( (sizeof(a)) / sizeof((a)[0]) )
struct structname {
int* section_A;
size_t A_len;
int* section_B;
size_t B_len;
};
#define A_INIT (int[]) { 0, 1, 2, 3 }
#define B_INIT (int[]) { [0x33] = 1, [0x34] = 2 }
static const struct structname structvariable_a =
{
.section_A = A_INIT,
.A_len = ARRAY_SIZE(A_INIT),
.section_B = B_INIT,
.B_len = ARRAY_SIZE(B_INIT)
};
#undef A_INIT
#undef B_INIT
还可以定义static
名为int
的数组,然后在structvariable_a
的初始值设定项中使用该数组的名称。
如果您不打算在运行时更改数组的内容,请分别考虑使用int const *
和int const[]
。请注意,如果此代码位于标题中,则每个翻译单元都将拥有自己的数组副本。
更新(根据评论建议):使用sentinel值看起来像:
struct structname {
int* section_A;
int* section_B;
};
static const struct structname structvariable_a =
{
.section_A = (int[]) { 0, 1, 2, 3, INT_MAX },
.section_B = (int[]) { [0x33] = 1, [0x34] = 2, INT_MAX }
};
和in main
或者其他什么,你找INT_MAX
来知道数组末尾的位置,例如:
size_t a_len;
for (a_len = 0; structvariable_a.section_A[a_len] != INT_MAX; ++a_len) { }
显然,这意味着数组的有效数据范围需要排除sentinel值。
答案 2 :(得分:0)
您获得的错误是因为ent
需要一个数组,ARRAY_SIZE
不是数组而是指针。
由于你的结构有效地具有固定大小的数组,只需将它们声明为数组而不是指针:
structvariablepointer->section_A
然后像这样初始化:
struct structname {
int section_A[4];
int section_B[0x35];
};