struct hello1 {
int64_t world1;
int64_t world2;
int64_t world3;
int64_t world4;
int64_t world5;
}
void something (struct hello1 *first) {
int64_t *foo1 = &first->world1;
for (int64_t i = 0; i < 0x30; i++) {
printf("Address: 0xllx", foo1);
foo1++;
}
}
我当前正在将地址&first->wordl1
分配给* foo1。
有没有一种更好的方法可以在不创建int64_t *foo1
的情况下递增到结构中的下一个指针?
答案 0 :(得分:3)
尝试通过指针算法从任何其他成员访问struct
的任何成员的行为是未定义。
更详细地讲,C标准允许您读取指针值&world1
(并对其取消引用)和指针值&world1 + 1
(但不将其延迟) 。但是它不允许您读取指针值&world1 + 2
及以上。
请考虑改用int64_t
数组。然后指针算术将是有效的,并且您将不需要这些额外的强制转换。
如果您仍然坚持使用hello1
,并且希望能够通过索引访问成员,请考虑
inline int64_t* getHello1Element(struct hello1* h, size_t i)
{
switch (i){
case 0:
return &h->world1;
case 1:
return &h->world2;
case 2:
return &h->world3;
case 3:
return &h->world4;
case 4:
return &h->world5;
}
}
它将是具有良好编译器的O(1)。
答案 1 :(得分:0)
您可以直接将.groupBy(x => x._1)
添加到i
。
&first->world1
请注意,这将调用未定义的行为,因为它将使生成的指针超出范围。
还请注意,struct hello1 {
int64_t world1;
int64_t world2;
int64_t world3;
int64_t world4;
int64_t world5;
}
void something (struct hello1 *first) {
for (int64_t i = 0; i < 0x30; i++) {
printf("Address: 0xllx", &first->world1 + i);
}
}
本身不会导致未定义的行为:格式中没有printf()
,并且允许在%
中使用多余的参数。 (多余的参数将被评估并忽略)
printf()
在典型环境中不会导致任何结果,因此让我们删除这种无用的未定义行为。
&first->world1 + i
也适合0x30
(保证最多可以存储int
),因此,32767
仅使用int
而不是int64_t
。
这是一种更好的方法:
i
答案 2 :(得分:0)
这是经典方式:
struct hello1 {
int64_t world[5];
}
void something (struct hello1 *first) {
for (int i = 0; i < 5; i++) {
printf("Address: %p\n", first->world + i);
}
}
void something_else(struct hello1 *first) {
int64_t *foo = first->world;
for (int i = 0; i < 5; i++) {
printf("Address: %p\n", foo++);
}
}
或者如果您想变得好玩:
struct hello1 {
union {
int64_t world[1];
int64_t world1;
};
int64_t world2, world3, world4, world5;
}
但是它具有更可疑的价值,除非您必须使用单独的访问器来支持大量遗留物。