如何理解strcpy函数中的赋值语句?

关于 strcpy 函数的赋值语句

如何理解while (*s++ = *t++)

void strcpy(char *s, char *t)
{ 
    while (*s++ = *t++);
}

该语句等价于while (*(s++) = *(t++))

赋值语句的结合方向是自右往左,所以从右往左读,可以将*(s++) = *(t++)拆成两条语句:

temp = *(t++);
*(s++) = temp;

也即代码段 A:

temp = *t;
t++;
*s = temp;
s++;

赋值语句实际上是一个表达式,等于赋值运算符右边表达式的结果,比如a = b的结果是b。这里右边表达式是*(t++),结果是*t先使用,后自增),因此原代码可等价于代码段 B:

while (*t != '\0'){
  *(s++) = *(t++);
}

代码段 A 和 B 结合在一起:

char temp = *t;
while (temp != '\0'){
    temp = *t;
    t++;
    *s = temp;
    s++;
}

需要提醒的是,平时不要写这样的代码,可读性较差。

一些汇编

*s++ = *t++的汇编:

mov     rdx, QWORD PTR [rbp-16]  ; t 存入 rdx
lea     rax, [rdx+1]             ; t+1,然后存入 rax
mov     QWORD PTR [rbp-16], rax  ; rax 再压回栈中,供函数使用
mov     rax, QWORD PTR [rbp-8]   ; s 存入 rax
lea     rcx, [rax+1]             ; s+1,然后存入 rcx
mov     QWORD PTR [rbp-8], rcx   ; rcx 再压回栈中,供函数使用
movzx   edx, BYTE PTR [rdx]      ; rdx 所指向的内容即 *t 存入 edx
mov     BYTE PTR [rax], dl       ; edx 的低 8 位内容存入 rax 所指向的内容即 *s

strcpy 的汇编:

strcpy(char*, char*):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     QWORD PTR [rbp-16], rsi  ; 以上均为调用函数前的操作,不用理会
.L3:
        mov     rdx, QWORD PTR [rbp-16]  ; t 存入 rdx
        lea     rax, [rdx+1]             ; t+1,然后存入 rax(rax = t+1)
        mov     QWORD PTR [rbp-16], rax  ; rax 再压回栈中,供函数使用
        mov     rax, QWORD PTR [rbp-8]   ; s 存入 rax
        lea     rcx, [rax+1]             ; s+1,然后存入 rcx(rcx = s+1)
        mov     QWORD PTR [rbp-8], rcx   ; rcx 再压回栈中,供函数使用
        movzx   edx, BYTE PTR [rdx]      ; rdx 所指向的内容即 *t 存入 edx
        mov     BYTE PTR [rax], dl       ; edx 的低 8 位内容存入 rax 所指向的内容即 *s(*s = *t)
        movzx   eax, BYTE PTR [rax]      ; rax 所指向的内容即 *t 存入 eax
        test    al, al                   ; 下面判断 eax 即 *t 是否为 0,test 指令是按位与运算
        setne   al
        test    al, al
        je      .L4
        jmp     .L3
.L4:
        nop
        pop     rbp
        ret
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值