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

在C中的for循环中使用分号而不使用任何命令,c,C,这些代码做同样的工作。我不明白为什么 for ( ; *s1 = *s2; s1++, s2++ ) { ;} for ( ; *s1 = *s2; s1++, s2++ ) {*s1=*s2;} 循环的第二个子句将求值为赋值,然后使用此值确定是否继续循环,因此两个循环将s2复制到s1,直到*s1==0。如果s1和s2是同一类型的指针,则当*s2==0时会发生这种情况。如果它们不是相同的类型,那么这是一个很棘手的代码,很可能是不正确的 第二个循环包含一个完全冗余的主体,因为它只是重复循环的第

这些代码做同样的工作。我不明白为什么

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

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


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

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


第二个循环包含一个完全冗余的主体,因为它只是重复循环的第二个子句已经做过的事情。

您的意思是在循环条件中使用==吗?不管怎样

现在它执行赋值-表达式的结果是赋值,并且在值为0之前为“真”


由于分配是在循环条件下完成的,因此在每个循环的顶部,循环内的分配是冗余的,因为在循环体执行之前已经发生了相同的分配。

您的意思是在循环条件下使用==吗?不管怎样

现在它执行赋值-表达式的结果是赋值,并且在值为0之前为“真”


由于分配是在循环条件下完成的,因此在每个循环的顶部,循环内的分配是冗余的,因为在循环体执行之前已经发生了相同的分配。

两个代码都将s2引用的内存块复制到s1引用的内存块中,直到*s2不为零

它们与任务中的条件相同

大多数编译器都会优化
{*s1=*s2;}

例如,如果指针是
char*

int main()
{
  for ( ; *s1 = *s2; s1++, s2++ ) { ;}
  for ( ; *s3 = *s4; s3++, s4++ ) {*s3=*s4;} 
}
代码是(-O3,-O2,-O1)


两个循环完全相同

两个代码将s2引用的内存块复制到s1引用的内存块中,直到*s2不为零

它们与任务中的条件相同

大多数编译器都会优化
{*s1=*s2;}

例如,如果指针是
char*

int main()
{
  for ( ; *s1 = *s2; s1++, s2++ ) { ;}
  for ( ; *s3 = *s4; s3++, s4++ ) {*s3=*s4;} 
}
代码是(-O3,-O2,-O1)


两个循环完全相同

如果
s1
s2
属于
char*
类型,则代码实现一个
strcpy
strcpy
的结束条件是“在分配了
'\0'
-字符串终止字符后停止”

所以第三个版本是

for ( ; ; s1++, s2++ ) {
   *s1=*s2;
   if (!*s1) {
      break;
   }
} 
现在让我们深入研究一下像
*s1=*s2
这样的赋值的含义,它实际上做了两件事:(1)它将
*s2
赋值给
*s1
,以及(2)表达式结果是赋值后
*s1
的值

在(;*s1=*s2;s1++,s2++){;}的
中,循环结束条件中使用了
*s1=*s2
,发生了两件事(1)赋值和(2)检查
'\0'
是否被赋值(在这种情况下,循环结束)

在(;*s1=*s2;s1++,s2++){*s1=*s2;}
中,循环的主体是多余的;在评估“条件”时已经进行了赋值


顺便说一句:你也可以把它写成
而(*s1++=*s2++);
..

如果
s1
s2
char*
类型,那么代码实现了
strcpy
。strcpy
的结束条件是“在分配了
'\0'
-字符串终止字符后停止”

所以第三个版本是

for ( ; ; s1++, s2++ ) {
   *s1=*s2;
   if (!*s1) {
      break;
   }
} 
现在让我们深入研究一下像
*s1=*s2
这样的赋值的含义,它实际上做了两件事:(1)它将
*s2
赋值给
*s1
,以及(2)表达式结果是赋值后
*s1
的值

在(;*s1=*s2;s1++,s2++){;}的
中,循环结束条件中使用了
*s1=*s2
,发生了两件事(1)赋值和(2)检查
'\0'
是否被赋值(在这种情况下,循环结束)

在(;*s1=*s2;s1++,s2++){*s1=*s2;}
中,循环体是多余的;在评估“条件”时,任务已经发生


顺便说一句:你也可以把它写成
while(*s1++=*s2++)..

我推测OP在某处发现了此代码,并试图理解它。检查在循环结束时执行,因此检查中的赋值是多余的,不是循环中的赋值。我推测OP在某个地方发现了这段代码,并试图理解它。检查是在循环结束时执行的,因此检查中的赋值是多余的,而不是循环中的赋值。迭代在哪里结束?@DavidC.Rankin,如果
*s2==0
,它也会有。除了
s2
中有效的以nul结尾的字符串之外的任何内容,天空是限制。(或者是内存段…@P_uuuj_uuu):实际上,赋值后当
*s1
为零时,它停止<代码>*s2
仍可能为非零。例如,它可以是½。@EricPostpischil如果赋值后*s1为零*s2太多,因为*s1被赋值为*s2,迭代在哪里结束?@DavidC.Rankin当
*s2==0
时,它也会结束。
s2
中有效的以nul结尾的字符串以外的任何内容,以及