C - 在结构中声明和初始化数组

标签 c arrays struct initialization declaration

语言:C

我正在尝试在结构中声明和初始化一个数组,并将其传递给一个指针,该指针本身在结构 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))
                                                           ^~~~~~~~~~~~~~~

最佳答案

一旦你拿了一个指向数组第一个元素的指针,你就不能再通过那个指针找到数组的大小了。因此,您还需要创建变量来保存数组大小。 (或者在数组的末尾使用标记值)。

解决问题的一种方法是通过丑陋的宏:

#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

还可以定义名为intstatic 数组,然后在structvariable_a 的初始化程序中使用该数组的名称。

如果您不打算在运行时更改数组的内容,请考虑分别使用 int const *int const[]。请注意,如果此代码位于 header 中,则每个翻译单元都将拥有自己的数组副本。


更新(如评论所建议):使用哨兵值看起来像:

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 }
};

main 或其他任何东西,你寻找 INT_MAX 来知道数组的末尾在哪里,例如:

size_t a_len;
for (a_len = 0; structvariable_a.section_A[a_len] != INT_MAX; ++a_len) { }

显然这意味着数组的有效数据范围需要排除标记值。

关于C - 在结构中声明和初始化数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47682745/

相关文章:

c++删除结构数组中的元素

c# - 如何在 C# 中声明一个包含固定数量固定大小字符串的数组?

c - 看来基于堆栈的变量在 C 函数之后没有被释放

c - 错误 : assignment of member ai_family in read-only object

javascript - 过滤[空]数组对象

数组作为哈希值 : get the 2 arrays with most elements

JavaScript:删除共享相同属性值的对象的重复项

c# - 具有引用类型和 GC 的结构?

c - 在 Linux 上以编程方式获取有关 ROM 内存类型和大小的信息

c - c中的反向字符串