#define GET_STRUCT_ITEM(child, parent, index) ((child*) &(&parent)[0])[index]
typedef struct {
uint8_t val;
} key_child;
typedef struct {
key_child key_0;
key_child key_1;
key_child key_2;
key_child key_3;
} key_parent;
key_parent keys = {
.key_0.val = 11,
.key_1.val = 22,
.key_2.val = 33,
.key_3.val = 44
};
key_child key_a, key_b, key_c, key_d;
int main(void) {
key_a = GET_STRUCT_ITEM(key_child, keys, 0);
key_b = GET_STRUCT_ITEM(key_child, keys, 1);
key_c = GET_STRUCT_ITEM(key_child, keys, 2);
key_d = GET_STRUCT_ITEM(key_child, keys, 3);
}
经过几个小时的研究,我可以解决一个问题,用索引访问结构的任何子级,但我认为我没有以正确的方式做这件事。
据我所知,我通过指针选择父结构的第一个字节,将其转换为子结构,然后在那里选择子索引。
有没有更简单、更好、更干净的方法来做到这一点?
正如其他人所说,我认为当您从数组更改为命名项时,您进行了逆行。除此之外,与使用数组相比,它使元素之间的移动变得非常糟糕。
如果您认为必须执行命名版本,请在您的结构中使用来自 C11 的匿名联合(和匿名结构):
#include <stdint.h>
typedef struct
{
uint8_t val;
} key_child;
typedef struct
{
union
{
struct
{
key_child key_0;
key_child key_1;
key_child key_2;
key_child key_3;
};
key_child key[4];
};
} key_parent;
key_parent keys =
{
.key_0.val = 11,
.key_1.val = 22,
.key_2.val = 33,
.key_3.val = 44
};
key_parent quays =
{
.key =
{
[0] = { .val = 11 },
[1] = { .val = 22 },
[2] = { .val = 33 },
[3] = { .val = 44 },
}
};
// Global to avoid 'unused variable' warnings
key_child key_a, key_b, key_c, key_d;
key_child quay_e, quay_f, quay_g, quay_h;
int main(void)
{
key_a = keys.key[0];
key_b = keys.key[1];
key_c = keys.key[2];
key_d = keys.key[3];
quay_e = quays.key_0;
quay_f = quays.key_1;
quay_g = quays.key_2;
quay_h = quays.key_3;
}
使用以下命令(源文件au97.c
)使用 GCC 7.2.0(在运行 macOS High Sierra 10.13 的 Mac 上编译)干净利落地编译:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -pedantic -c au97.c
$
请注意,您可以通过任何一种方式访问结构。如果您没有可用的匿名联合和结构(C99 或更早版本),那么您必须命名联合(这u
是一个传统名称)和结构,并使用:
#include <stdint.h>
typedef struct
{
uint8_t val;
} key_child;
typedef struct
{
union
{
struct
{
key_child key_0;
key_child key_1;
key_child key_2;
key_child key_3;
} s;
key_child key[4];
} u;
} key_parent;
key_parent keys = { .u.key = { { 11 }, { 22 }, { 33 }, { 44 } } };
key_parent quays = { .u.s = { { 11 }, { 22 }, { 33 }, { 44 }, } };
// Global to avoid 'unused variable' warnings
key_child key_a, key_b, key_c, key_d;
key_child quay_e, quay_f, quay_g, quay_h;
int main(void)
{
key_a = keys.u.key[0];
key_b = keys.u.key[1];
key_c = keys.u.key[2];
key_d = keys.u.key[3];
quay_e = quays.u.s.key_0;
quay_f = quays.u.s.key_1;
quay_g = quays.u.s.key_2;
quay_h = quays.u.s.key_3;
}
这被保存au83.c
并使用以下命令干净地编译:
$ gcc -O3 -g -std=c99 -Wall -Wextra -Werror -pedantic -c au83.c
$
对于这两个编译,我省略了-Wmissing-prototypes -Wstrict-prototypes
我通常使用的标志,因为示例代码中除了 main 之外没有其他函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句