1. 程式人生 > >C語言用結構體給另一個同類型結構體賦值: 用等號即可

C語言用結構體給另一個同類型結構體賦值: 用等號即可

看到很多C程式碼的結構體賦值都是用memcpy函式來拷貝,其實根本不需要,用等號直接賦值即可。結構體描述的是的一塊連續記憶體的記憶體佈局,同類型的一個結構體變數給另一個結構體變數賦值,使用等號編譯不會有任何問題,其效果顯然也和人直覺認為的一樣,拷貝對應記憶體。

通過反彙編看編譯器的行為,效果跟memcpy一樣,還省掉了函式呼叫開銷,程式碼更加的簡潔明瞭。

// @file: main.c
struct 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) disass Dump 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 <main+131> 0x00005555555546e8 <+126>: callq 0x555555554540 <[email protected]> 0x00005555555546ed <+131>: leaveq 0x00005555555546ee <+132>: retq End of assembler dump. */

而對於結構體的比較,是要具體到基本資料型別的結構體成員比較,因為有位元組對齊,用memcmp是不可靠。除非結構體顯示宣告單位元組對齊,如用__attribute__((packed))修飾了結構體定義。