【C语言】结构体赋值

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

//test.c

#include

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, eax rep 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值