【C语言基础】结构体赋值

结构体在 C 程序中使用的较为频繁,能对数据有一定的封装的作用。对一个结构体赋值时,经常采用的方式是,分别对其成员变量赋值。那么能否将一个结构体用赋值号(“=”)直接赋值给另一个结构体呢?网上的答案不一,有说可以的,有说不可以的,有说这样的话两个结构体共用一块内存空间。我们可以从汇编语言的角度来看这个问题,测试程序:

//test.c

#include <stdio.h>

int

main(){    

struct

foo    {        

int

a;        

             int

b[

5

];        

            int

*c;    } x, y;    x.a =

666

;    x.b[

0

] =

555

;    x.c = NULL;    y = x;    

    return

0

;}

程序定义了结构体 foo,它有3个成员变量:int 型数据 a、int 数组 b、int 指针 c,以观察是否对不同类型的成员有不同的处理。使用 gcc 将其编译:

gcc -S -masm=intel test.c

编译时并没有报错,说明编译器接受这种赋值方式,但赋值时具体发生了什么?打开其输出的汇编文件,关键部分为:

mov

    DWORD PTR [esp+

36

],

666

mov

    DWORD PTR [esp+

40

],

555

mov

    DWORD PTR [esp+

60

],

0

lea     edx, [esp+

8

]lea     ebx, [esp+

36

]

mov

    eax,

7

mov

    edi, edx

mov

    esi, ebx

mov

    ecx, eaxrep movsd

前面3条 mov 语句为给成员变量赋值的语句;中间两条 lea 语句得到了两块内存空间的偏移地址,第一块为新的内存空间,第二块为结构体 x 占有的内存空间;后面4条 mov 语句,第1、4条作用为把7赋给 ecx,第2条为把新内存空间地址赋给 edi,第3条为把 x 内存空间地址赋给 esi。关键在于最后一条语句:rep movsd。 

movsd 是一个串传送指令,其英文为 move string dword,具体作用为以 esi(Source Index)为源地址,以 edi(destination Index)为目的地址,将源地址处一个双字(dword)内容复制到目的地址。然后根据方向标志位 DF 的值,DF = 0,esi 与 edi 自增4,DF = 1,esi与edi自减4(dword 占用4个字节)。(但此处并没有使用 CLD 设置 DF 值,默认为0?)rep 可以根据 ecx 的值,重复执行 ecx 次 movsd 指令。 

这样的话,rep movsd 指令的作用是,将 esi 处的7个 dword 复制到 edi 处,而 foo 结构体正好占用4*7个字节(此处没有对齐的问题)。于是,x 的内容便被复制到了另一块相同大小的内存中,我们基本可以确定,这块空间就是 y 所占的空间。 

因此,我们可以得出结论,结构体可以直接赋值,且赋值的结果是将赋值号左边的结构体中的内容原原本本的复制到赋值号右边的结构体中,并没有共用同一块内存空间。



转自:http://blog.csdn.net/imred/article/details/45588477

分享自己的编程故事

,直接加小编微信号:coderonline

关注微信公众号:程序员互动联盟(

coder_online

)



  • 入关键字

     

    自学

     

    获取编程自学手册

  • 输入关键字

     程序人生

     了解码农生活

  • 更有(java/C/C++/Linux/Android)高手帮你解决难题,一起互动

    图片来自互联网如有侵权请联系小编立即删除

    【C语言基础】结构体赋值