关于语句 while((*s++ = *t++) != '\0') 运算顺序的疑问

字符串拷贝操作test1

void test1(char *s, char *t) 

{

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

;

}

void test2(char *s, char *t)

{

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

;

}

01 这两个函数都可以完成操作,但是test2中(s++)和(t++)为什么没有在 (*s = *t) 之前执行?(如果在赋值之前执行应该第一个字符无法被复制才对吧)

02 网上有对test1做出解释

void test3(char *s, char *t) 

{

while(*t != 0)

{

*s = *t;

s++;

t++;

}

}

为什么是先判断 (t != 0) 之后,再进行赋值操作,再进行自增运算 (不是先赋值再判断s的值是否等于0?)

03 自己理解的test1执行顺序,这样理解是否正确

void test4(char *s, char *t) 

{

while(1)

{

*s = *t;

s++;

t++;

if(*s != 0)

break;

}

}

回答:

谢邀

01 参考我的这个回答 C语言中*s++ = *t++ 是怎么一种赋值过程

02 这个不完全等效,你的理解是对的

03 你的这个写法也是不对的,你给出的逻辑是s++之后再判断*s == 0(你原文写的!=应该是写错了),这与原代码逻辑不同

等效test1的逻辑是

void test5(char *s, char *t)

{

char *temp;

while(1) {

*temp = (*s = *t); // 赋值表达式 '*s = *t' 也是表达式,其计算结果等于'*t',

s += 1;

t += 1;

if(*temp != '\0')

;

else

break;

}

}

回答:

<c和指针中>是这么写的:
图片描述

所以按这种解释的话,不管s++t++有没有括号,都是一样的.

但是根据@spacelan的运行结果,不知道现代编译器是不是简化步骤了,总之效果是一样的,讨论下去没啥意思

回答:

同初学者,一起讨论下。

在我看来循环条件里面的++运算都是相当于循环语句执行完之后执行,所以你的if要写在两个++的前面。

不过一点,'\0'不要总写成0, 类型不一样,会有个强制转换的过程,当你真的希望转换的时候就写出来,这种隐式转换有时候会出现意想不到的问题的。

其实有debug工具可以看每一步执行之后各个变量的值,可以帮助判断。

回答:

  1. 自增运算符前置,在表达式计算之前先自增;自增运算符后置,在表达式计算结束后自增。

    自减同理。。。

  2. 没有拷贝到'\0'

  3. 同样没有拷贝到'\0'

回答:

关于test1,为什么先while(*t != '\0'):

这样应该是为了避免当t是一个空字符串的情况。如果是个空字符串,*t++的值是一个不确定的值。

*s++*(s++) 的结合顺序都是从右到左。 所以()可以忽略。
欢迎斧正

以上是 关于语句 while((*s++ = *t++) != &#x27;\0&#x27;) 运算顺序的疑问 的全部内容, 来源链接: utcz.com/p/195908.html

回到顶部