使用将一个内部结构的地址作为参数的函数将一个内部结构的变量复制到另一个内部结构

时间:2014-08-13 13:49:27

标签: c struct structure

我有一个复杂的结构,看起来像这样。

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

5 个答案:

答案 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节(强调我的),您假设bc属于同一类型是无效的:

  

...如果该对的一个成员用名称声明,则另一个成员被声明   同名

因为结构使用不同的成员名称,所以它们被认为是兼容的,因此您的假设无效。

此外,即使它们是完全相同的类型,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;
}