这些代码执行相同的工作。我不明白为什么
for ( ; *s1 = *s2; s1++, s2++ ) { ;}
for ( ; *s1 = *s2; s1++, s2++ ) {*s1=*s2;}
答案 0 :(得分:4)
循环的第二个子句将求值为赋值,然后使用该值确定是否继续循环,因此两个循环都将s2
复制到s1
直到{{1} }。如果*s1 == 0
和s1
是相同类型的指针,则在s2
时会发生这种情况。如果它们不是同一类型,则这是棘手的代码,很可能是错误的。
第二个循环包含一个完全冗余的主体,因为它仅重复循环的第二个子句已经执行的操作。
答案 1 :(得分:1)
如果s1
和s2
的类型为char*
,则代码实现strcpy
。 strcpy
的结束条件是“在分配了'\0'
字符串终止字符后停止。
第三个版本是...
for ( ; ; s1++, s2++ ) {
*s1=*s2;
if (!*s1) {
break;
}
}
现在,让我们深入了解*s1 = *s2
这样的赋值的含义,它实际上有两件事:(1)将*s2
赋给*s1
,(2)表达式结果是赋值后*s1
的值;
在for ( ; *s1 = *s2; s1++, s2++ ) { ;}
中,在循环结束条件中使用*s1 = *s2
时,会发生两件事:(1)分配和(2)检查'\0'
是否已分配(在循环结束的情况)。
在for ( ; *s1 = *s2; s1++, s2++ ) {*s1=*s2;}
中,循环的主体只是多余的;评估“条件”时已经进行了分配。
顺便说一句:您也可以将其写为while((*s1++=*s2++));
...
答案 2 :(得分:0)
您是要在循环条件中使用==吗?不管
现在它执行分配-表达式的结果是分配的值,直到值为0为止都是“ true”。
由于分配是在循环条件下完成的,因此在每个循环的顶部,循环内的分配都是多余的,因为在执行循环主体之前已经进行了相同的分配。
答案 3 :(得分:0)
两个代码都将s2引用的存储块复制到s1引用的存储块中,直到* s2不为零为止。
与您的条件和作业相同。
{*s1=*s2;}
将被大多数编译器优化。
例如,如果指针是char *
int main()
{
for ( ; *s1 = *s2; s1++, s2++ ) { ;}
for ( ; *s3 = *s4; s3++, s4++ ) {*s3=*s4;}
}
代码是(-O3,-O2,-O1)
main:
movzx eax, BYTE PTR ds:0
test al, al
je .L2
mov eax, 1
.L3:
movzx edx, BYTE PTR [rax]
add rax, 1
test dl, dl
jne .L3
.L2:
movzx eax, BYTE PTR ds:0
test al, al
je .L4
mov eax, 1
.L5:
movzx edx, BYTE PTR [rax]
add rax, 1
test dl, dl
jne .L5
.L4:
xor eax, eax
ret
两个循环完全相同