题主的问题:
C语言中
inti=0,j;for(j=3;i=j=0;i++,j++){/* loop body */}循环多少次,这个循环条件到底是怎么判断的?其实是赋值表达式的问题吧。假定题主实际关心的代码的for循环的循环体没有做什么奇怪的事情来改变循环次数。
答案自然是0次。可以先把for循环解糖为while循环的形式:
inti=0,j;j=3;while(i=j=0){/* loop body */i++;j++;}所以循环条件就看"i = j = 0"这个表达式的值。
C语言里,赋值运算符("=")是右结合(right-associative)的双目运算符;赋值是一个表达式,可以用于其它表达式之中。所以
i=j=0等价于
i=(j=0)赋值表达式其实要完成两件事情:
赋值:将赋值运算符右边的表达式的值赋予左边的操作数将赋值后左边的操作数的值当作整个表达式的值。如评论里@Sunchy321指正的,左边与右边的类型未必一样,整个表达式的值是看左边操作数的。所以"j = 0"作为表达式的值是0,然后"i = (j = 0)"的值也是0。
所以题主的代码可以变为:
inti=0,j;j=3;while(0){/* loop body */i++;j++;}所以循环0次。
===========================================================
手闲,顺手dump个Clang给的AST好了。
对这段源码:
intmain(){inti=0,j;for(j=3;i=j=0;i++,j++){/* loop body */}return0;}Clang生成的AST形如:
TranslationUnitDecl 0x1028292d0 <<invalid sloc>>`-FunctionDecl 0x102829c20 <zzz.c:1:1, line:7:1> main 'int ()'`-CompoundStmt 0x10286ec90 <line:1:12, line:7:1>|-DeclStmt 0x102829dd0 <line:2:3, col:15>| |-VarDecl 0x102829cd0 <col:3, col:11> i 'int'| | `-IntegerLiteral 0x102829d28 <col:11> 'int' 0| `-VarDecl 0x102829d60 <col:3, col:14> j 'int'|-ForStmt 0x10286ec10 <line:3:3, line:5:3>| |-BinaryOperator 0x102829e30 <line:3:7, col:11> 'int' '='| | |-DeclRefExpr 0x102829de8 <col:7> 'int' lvalue Var 0x102829d60 'j' 'int'| | `-IntegerLiteral 0x102829e10 <col:11> 'int' 3| |-<<<NULL>>>| |-BinaryOperator 0x102829ef0 <col:14, col:22> 'int' '='| | |-DeclRefExpr 0x102829e58 <col:14> 'int' lvalue Var 0x102829cd0 'i' 'int'| | `-BinaryOperator 0x102829ec8 <col:18, col:22> 'int' '='| | |-DeclRefExpr 0x102829e80 <col:18> 'int' lvalue Var 0x102829d60 'j' 'int'| | `-IntegerLiteral 0x102829ea8 <col:22> 'int' 0| |-BinaryOperator 0x102829fa8 <col:25, col:31> 'int' ','| | |-UnaryOperator 0x102829f40 <col:25, col:26> 'int' postfix '++'| | | `-DeclRefExpr 0x102829f18 <col:25> 'int' lvalue Var 0x102829cd0 'i' 'int'| | `-UnaryOperator 0x102829f88 <col:30, col:31> 'int' postfix '++'| | `-DeclRefExpr 0x102829f60 <col:30> 'int' lvalue Var 0x102829d60 'j' 'int'| `-CompoundStmt 0x102829fd0 <col:35, line:5:3>`-ReturnStmt 0x10286ec70 <line:6:3, col:10>`-IntegerLiteral 0x10286ec50 <col:10> 'int' 0其中题主关心的循环条件部分是:
| |-BinaryOperator 0x102829ef0 <col:14, col:22> 'int' '='| | |-DeclRefExpr 0x102829e58 <col:14> 'int' lvalue Var 0x102829cd0 'i' 'int'| | `-BinaryOperator 0x102829ec8 <col:18, col:22> 'int' '='| | |-DeclRefExpr 0x102829e80 <col:18> 'int' lvalue Var 0x102829d60 'j' 'int'| | `-IntegerLiteral 0x102829ea8 <col:22> 'int' 0也就是跟i = (j = 0)等价的形式:
=/ \i =/ \j 0