在C语言的for循环中不使用任何命令就使用分号

时间:2019-01-05 22:39:34

标签: c

这些代码执行相同的工作。我不明白为什么

for ( ; *s1 = *s2; s1++, s2++ ) { ;}
for ( ; *s1 = *s2; s1++, s2++ ) {*s1=*s2;} 

4 个答案:

答案 0 :(得分:4)

循环的第二个子句将求值为赋值,然后使用该值确定是否继续循环,因此两个循环都将s2复制到s1直到{{1} }。如果*s1 == 0s1是相同类型的指针,则在s2时会发生这种情况。如果它们不是同一类型,则这是棘手的代码,很可能是错误的。

第二个循环包含一个完全冗余的主体,因为它仅重复循环的第二个子句已经执行的操作。

答案 1 :(得分:1)

如果s1s2的类型为char*,则代码实现strcpystrcpy的结束条件是“在分配了'\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

两个循环完全相同