我有一个复杂的结构,看起来像这样。
struct a
{
struct b
{
int b_inner_int;
char b_inner_char;
}x;
struct c
{
int c_inner_int;
char c_inner_char;
}y;
}z;
我使用了一个函数,它接受" struct c"的地址。作为一个论点。现在我希望这个函数复制" struct c"的值。 to" struct b"。我在main函数中进行的函数调用可能如下所示。
copy_val(&z.y);
现在,我该如何定义copy_val?有什么建议? 如果我定义了一个类型为struct c的指针,如下所示它就不起作用了。
void copy_val(struct c *addr)
{
struct c *tmp=addr;
int tmp_int=tmp->c_inner_int;
int tmp_char=tmp->c_inner_char;
tmp=tmp-1; /** assuming that b and c are of same type and decrementing pointer by 1 takes to beginning of b **/
tmp->b_inner_int=tmp_int;
tmp->b_inner_char=tmp_char;
}
答案 0 :(得分:3)
#include <stdio.h>
#include <stddef.h>
struct a
{
struct b
{
int b_inner_int;
char b_inner_char;
}x;
struct c
{
int c_inner_int;
char c_inner_char;
}y;
}z;
void copy_val(struct c *addr){
size_t offset_c = offsetof(struct a, y);
size_t offset_b = offsetof(struct a, x);
struct b *bp = (struct b*)((char*)addr - offset_c + offset_b);
bp->b_inner_int = addr->c_inner_int;
bp->b_inner_char = addr->c_inner_char;
}
int main(void){
z.y.c_inner_int = 1;
z.y.c_inner_char = '1';
copy_val(&z.y);
printf("%d, %c\n", z.x.b_inner_int, z.x.b_inner_char);
return 0;
}
答案 1 :(得分:1)
您说您想要获取结构成员的地址,并根据该成员引用其他成员。
这有点不确定;自然要做的就是获取你想要使用其成员的顶级结构的地址,即struct a
。
此外,它可以简化:
struct a
{
struct b
{
int b_inner_int;
char b_inner_char;
} x, y;
} z;
完成后,你可以做到:
z.x = z.y;
复制struct b
类型的整个值。
答案 2 :(得分:1)
根据C标准第6.2.7节第1节(强调我的),您假设b
和c
属于同一类型是无效的:
...如果该对的一个成员用名称声明,则另一个成员被声明 同名。
因为结构使用不同的成员名称,所以它们不被认为是兼容的,因此您的假设无效。
此外,即使它们是完全相同的类型,tmp=tmp-1;
语句也无效:sizeof(struct b)
可能会报告类似8的内容,这并不意味着两个结构之间没有填充。
相反,您应该使用offsetof
宏来获取z
的地址,并指定z.y
的地址:
struct a *z = (struct a *)((char *)addr - offsetof(struct a, y));
但请注意,这可能会破坏别名假设,因为指向z
的对象的一部分也由y
指向,但指针不兼容。
答案 3 :(得分:0)
如果你像copy_val(&z.y);
这样通过,你就无法以正确的方式捕捉它,因为你有结构内部结构。所以尝试传递整个结构并复制它 -
copy_val(&z);
请尝试以下代码 -
void copy_val(struct z *addr)
{
addr->x.b_inner_int= addr->y.c_inner_int;
addr->x.b_inner_char= addr->y.c_inner_char;
}
答案 4 :(得分:-1)
include <stdio.h>
struct a
{
struct b
{
int b_inner_int;
char b_inner_char;
}x;
struct c
{
int c_inner_int;
char c_inner_char;
}y;
}z;
void copy_val(struct c *c_pointer)
{
struct b *tmp = (struct b *) (c_pointer-1);
tmp->b_inner_int = c_pointer->c_inner_int;
tmp->b_inner_char = c_pointer->c_inner_char;
}
int main(int argc, char **argv)
{
struct a test;
test.y.c_inner_int = 32;
test.y.c_inner_char = 'A';
copy_val(&test.y);
printf("b inner int : %d\n", test.x.b_inner_int);
printf("b inner char %c\n", test.x.b_inner_char);
return 0;
}