结构体copy问题

结构体copy问题

c语言中,结构使用是非常频繁的,操作结构体时,我们一般使用memcpy对结构体进行copy赋值,其实我们忽略了一点,同一种类型结构体是可以直接进行赋值的。另外,本文介绍下使用memcpy copy结构体时的一些注意事项。

一.结构体内存对齐

使用memcpy对结构体进行内存copy,首先要知道结构体的大小计算,最简单的方法使用sizeof(结构体类型)进行计算。当然,本文也介绍下结构体所占空间大小计算方法。
主要有两原则:
1.对结构体成员进行存储时,要以自身为起始地址(相对地址),每个成员存放到地址要是自身大小的整数倍。
例如:(4+4+8)

#include<stdio.h>

typedef struct test
{
        char a;
        int b;
        double c;
}test_t;

int main(int argc, const char *argv[])
{
        test_t a;

        printf("sizeof:%d\n",(int)sizeof(test_t));

        return 0;
}

在这里插入图片描述
2.计算出来的结构体总大小要为其成员最大宽度的整数倍
例如:(8+8+8)

#include<stdio.h>

typedef struct test
{
        char a;
        double c;
        int b;
}test_t;

int main(int argc, const char *argv[])
{
        test_t a;

        printf("sizeof:%d\n",(int)sizeof(test_t));

        return 0;
}

在这里插入图片描述

二.结构体copy

使用memcpy对结构体进行内存拷贝,归根到底就是将内存的数据从一个地址复制到另一个地址上。
先贴上测试代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//无指针结构体
typedef struct test
{
        char str[16]; //name
        char s;           //sex
        int m;            //age
}test_t;

//有指针结构体
typedef struct tests
{
        test_t * atest;

        char job[20];
}tests_t;

//结构体成员定义存在差异
typedef struct testn
{
        char str[20]; //name
        char s;           //sex
        int m;            //age
}testn_t;

int main(int argc, const char *argv[])
{
        //测试1
        test_t nab1,nab2,nab3;

        strcpy(nab1.str,"tom");
        nab1.s = 'm';
        nab1.m = 20;

        memcpy(&nab2,&nab1,sizeof(test_t));

        nab3 = nab1;

        printf("nab1.name:%s,nab1.sex:%c,nab1.age:%d\n",nab1.str,nab1.s,nab1.m);
        printf("nab2.name:%s,nab2.sex:%c,nab2.age:%d\n",nab2.str,nab2.s,nab2.m);
        printf("nab3.name:%s,nab3.sex:%c,nab3.age:%d\n",nab3.str,nab3.s,nab3.m);

        //测试二
        tests_t nabs1,nabs2,nabs3;

        nabs1.atest = &nab1;
        strcpy(nabs1.job,"teacher");

        memcpy(&nabs2,&nabs1,sizeof(tests_t));

        nabs3 = nabs1;

        printf("%s,%c,%d,%s\n",nabs1.atest->str,nabs1.atest->s,nabs1.atest->m,nabs1.job);
        printf("%s,%c,%d,%s\n",nabs2.atest->str,nabs2.atest->s,nabs2.atest->m,nabs2.job);
        printf("%s,%c,%d,%s\n",nabs3.atest->str,nabs3.atest->s,nabs3.atest->m,nabs3.job);


        //测试三
        printf("test_t:%d,testn_t:%d\n",(int)sizeof(test_t),(int)sizeof(testn_t));
        testn_t nabn;
        nabn.m=8;
        memcpy(&nabn,&nab1,sizeof(test_t));
        printf("nab1.name:%s,nab1.sex:%c,nab1.age:%d\n",nabn.str,nabn.s,nabn.m);

        printf("nab1.name:%s,nab1.sex:%d,nab1.age:%d\n",nabn.str,nabn.s,nabn.m);

        return 0;
}

编译运行:
在这里插入图片描述
测试一:
对于同一种类型的结构体,内存拷贝与结构体直接赋值是等价的,至少在本例中等价。

测试二:
如果结构体中存在指针变量,其大小就是四个字节,并不影响结构体直接赋值或者使用memcpy。

测试三:
对于不同类型的结构体进行拷贝,会出现什么问题。
现在有test_t,testn_t两种类型的结构体,从log看test_t 占24个字节,testn_t占28个字节大小,实际计算也是如此。现在将test_t类型的结构体copy到testn_t类型的结构体,会出现什么结果。
在这里插入图片描述
由上图可以看出,直接内存拷贝。
在这里插入图片描述
由测试三最后一条log,可以看出,与上图是对应的,至于字符串打印没变,是因为%s打印遇到’\0’结束,我们也可以做个测试。

#include<stdio.h>


int main(int argc, const char *argv[])
{
        char str[20] ="12345678a\0 555";
        char string[20] = "123456789a 555";
        printf("str:%s\nstring:%s\n",str,string);

        return 0;
}

编译运行
在这里插入图片描述

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值