博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言用结构体给另一个同类型结构体赋值: 用等号即可
阅读量:4207 次
发布时间:2019-05-26

本文共 2591 字,大约阅读时间需要 8 分钟。

看到很多C代码的结构体赋值都是用memcpy函数来拷贝,其实根本不需要,用等号直接赋值即可。结构体描述的是的一块连续内存的内存布局,同类型的一个结构体变量给另一个结构体变量赋值,使用等号编译不会有任何问题,其效果显然也和人直觉认为的一样,拷贝对应内存。

通过反汇编看编译器的行为,效果跟memcpy一样,还省掉了函数调用开销,代码更加的简洁明了。

// @file: main.cstruct node {
long a; int b; char c; long array[3];}; int main() {
struct node n1; n1.a = 1; n1.b = 2; n1.c = 3; n1.array[0] = 10; n1.array[1] = 11; n1.array[2] = 12; struct node n2 = n1; return 0;}

运行查看其行为:

(gdb)Breakpoint 1, main () at main.c:17        17      return 0;(gdb) p n1$1 = {
a = 1, b = 2, c = 3 '\003', array = {
10, 11, 12}}(gdb) p n2$2 = {
a = 1, b = 2, c = 3 '\003', array = {
10, 11, 12}}(gdb) p &n1$3 = (struct node *) 0x7fffffffe2d0(gdb) p &n2$4 = (struct node *) 0x7fffffffe300(gdb) p sizeof(n1)$5 = 40(gdb) p $rbp$6 = (void *) 0x7fffffffe330(gdb) disassDump of assembler code for function main: 0x000055555555466a <+0>: push %rbp 0x000055555555466b <+1>: mov %rsp,%rbp 0x000055555555466e <+4>: sub $0x60,%rsp 0x0000555555554672 <+8>: mov %fs:0x28,%rax 0x000055555555467b <+17>: mov %rax,-0x8(%rbp) 0x000055555555467f <+21>: xor %eax,%eax 0x0000555555554681 <+23>: movq $0x1,-0x60(%rbp) // &n1 0x..2d0 0x0000555555554689 <+31>: movl $0x2,-0x58(%rbp) 0x0000555555554690 <+38>: movb $0x3,-0x54(%rbp) 0x0000555555554694 <+42>: movq $0xa,-0x50(%rbp) 0x000055555555469c <+50>: movq $0xb,-0x48(%rbp) 0x00005555555546a4 <+58>: movq $0xc,-0x40(%rbp) // n1.array[2] = 12; 0x00005555555546ac <+66>: mov -0x60(%rbp),%rax 0x00005555555546b0 <+70>: mov -0x58(%rbp),%rdx 0x00005555555546b4 <+74>: mov %rax,-0x30(%rbp) // &n2 0x..300 0x00005555555546b8 <+78>: mov %rdx,-0x28(%rbp) 0x00005555555546bc <+82>: mov -0x50(%rbp),%rax 0x00005555555546c0 <+86>: mov -0x48(%rbp),%rdx 0x00005555555546c4 <+90>: mov %rax,-0x20(%rbp) 0x00005555555546c8 <+94>: mov %rdx,-0x18(%rbp) 0x00005555555546cc <+98>: mov -0x40(%rbp),%rax 0x00005555555546d0 <+102>: mov %rax,-0x10(%rbp)=> 0x00005555555546d4 <+106>: mov $0x0,%eax 0x00005555555546d9 <+111>: mov -0x8(%rbp),%rdx 0x00005555555546dd <+115>: xor %fs:0x28,%rdx 0x00005555555546e6 <+124>: je 0x5555555546ed
0x00005555555546e8 <+126>: callq 0x555555554540 <__stack_chk_fail@plt> 0x00005555555546ed <+131>: leaveq 0x00005555555546ee <+132>: retqEnd of assembler dump.*/

而对于结构体的比较,是要具体到基本数据类型的结构体成员比较,因为有字节对齐,用memcmp是不可靠。除非结构体显示声明单字节对齐,如用__attribute__((packed))修饰了结构体定义。

补充两个资料:

转载地址:http://obqli.baihongyu.com/

你可能感兴趣的文章
【一天一道LeetCode】#115. Distinct Subsequences
查看>>
【一天一道LeetCode】#116. Populating Next Right Pointers in Each Node
查看>>
【一天一道LeetCode】#117. Populating Next Right Pointers in Each Node II
查看>>
【一天一道LeetCode】#118. Pascal's Triangle
查看>>
【一天一道LeetCode】#119. Pascal's Triangle II
查看>>
【unix网络编程第三版】ubuntu端口占用问题
查看>>
【一天一道LeetCode】#120. Triangle
查看>>
【unix网络编程第三版】阅读笔记(三):基本套接字编程
查看>>
同步与异步的区别
查看>>
IT行业--简历模板及就业秘籍
查看>>
JNI简介及实例
查看>>
DOM4J使用教程
查看>>
JAVA实现文件树
查看>>
linux -8 Linux磁盘与文件系统的管理
查看>>
linux 9 -文件系统的压缩与打包 -dump
查看>>
PHP在变量前面加&是什么意思?
查看>>
ebay api - GetUserDisputes 函数
查看>>
ebay api GetMyMessages 函数
查看>>
php加速器 - zendopcache
查看>>
手动12 - 安装php加速器 Zend OPcache
查看>>