C语言中*s++ = *t++ 是怎么一种赋值过程

发布于 2022-08-31 20:30:05 字数 131 浏览 34 评论 0

如题 K&R 中的 一个strcpy函数中出现的方式

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

时光清浅 2022-09-07 20:30:05

首先是

*s = *t;

然后判断整个表达式的值是否为真,即

*s != 0

满足,则继续循环,否则终止
不论循环继续与否,接下来要执行

s += 1; t += 1;  // s先自增还是t先自增在这里是无关紧要的

=================================

回答评论中补充的问题,程序怎么读

优先级表我就不贴了,百度一大堆 ,核心是你要理解下面流程中的5.2

  1. 编译器解析到*,判断为指针运算符号,需要一个标示符或者表达式
  2. 解析到s,是一个合法的标示符,继续搜索是否有更高优先级的运算符
  3. 继续解析到++,由于*++是同一优先级,结合性为右到左,所以等同于*(s++)
  4. 然后是=,判断为赋值运算符,优先级比++低,因此前面的部分可以直接进行计算
  5. 那么*(s++)怎么计算?
    1. 拆解成 expr1 = s++; expr2 = *expr1;
    2. 首先是expr1 = s++,后置++的含义是先使用变量/表达式的值、再自增,表达式s++的计算结果就是s的值,计算完毕后,s自增1,也就是说假如s = 1,那么s++这个表达式的计算结果就是1expr1 = 1,计算完毕后,s的值自增1变为2,但不影响之前已经计算完毕的表达式
    3. 然后计算expr2 = *expr1,按照上面所举的例子,此时s=2, expr2 = *1
  6. 然后继续=的计算,由于赋值运算符是双目运算,需要一个右目表达式,继续解析
  7. 后面*的优先级比=高,因此先计算*t++,原理同上
  8. 然后计算赋值表达式的值,没错!赋值表达式也是表达式,它也有计算结果,它的计算结果就是右边表达式计算结果,表达式a=b的值就是b
  9. 计算完毕后,执行while的功能,判断表达式计算结果是否为真,也就是是否非0
谁的新欢旧爱 2022-09-07 20:30:05
void v(char *s, char *t) {
    *s++ = *t++;
}

看一下对应指令

push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)   //参数1 s
mov    %rsi,-0x10(%rbp)  //参数2 t
mov    -0x10(%rbp),%rax  //t暂存%rax
movzbl (%rax),%edx       //*t放入%edx
mov    -0x8(%rbp),%rax   //s暂存%rax
mov    %dl,(%rax)        //*t的低8位,即一个字节,放入*s
addq   $0x1,-0x8(%rbp)   //s++
addq   $0x1,-0x10(%rbp)  //t++
leaveq 
retq

可以看到,先*s = *t,然后s和t各自加1

宛菡 2022-09-07 20:30:05

首先,楼主while里面是不是少了一个=号

其次 这个是运算符优先级的问题:++ > * > ==:

似梦非梦 2022-09-07 20:30:05

大体相当于下面的:

while(*s = *t)
{
    //your code here
    t++;
    s++
}
屌丝范 2022-09-07 20:30:05

这个是csdn上一个老问题吧:http://bbs.csdn.net/topics/330083449

我觉得里面9楼的就说得很详细了,对比一下很清晰。

萌辣 2022-09-07 20:30:05

以下来源《C程序设计现代方法》
图片描述

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文