确定C的打印

我正在审查关于C的材料。我不确定为什么答案是12和32.在第一个printf() ,我认为%d = 2( i ), %d = 2( j ), \n =新队。 有谁能解释一下?

 #include  int main(void) { int i,j; i=2 && (j=2); printf("%d%d\n",i,j); (i=3) || (j=3); printf("%d%d\n",i,j); } 

打印原因12而不是22是因为i被赋值为2 && (j=2) 。 第一个j被分配到2 。 然后(j=2)返回2 。 之后, 2 && 2被评估为true ,并返回true 。 这是因为&&检查双方是否为真, 2被解释为真。 由于双方都是真的,它返回true,即1。

|| 如果将left评估为true,则不评估右侧。 原因是没有必要。 如果至少有一个运算符求值为true,则它应该求值为true,而i = 3求值为3,这被解释为true。 这就是打印32而不是33的原因。

如果left评估为true,它不会评估右操作数的function可用于执行此操作:

 foo() || printf("foo() returned false\n"); 

和&&类似,但是如果左计算结果为false,则此运算符不会评估右操作数。

 foo() && printf("foo() returned true\n"); 

请注意,我并不是说应该使用这些技巧。 我只是用它们作为如何||的一个例子 和&&可能会跳过评估右操作数,具体取决于左侧的值。

对于第一个表达式, i=2 && (j=2); 被隐式评估为i = (2 && (j = 2)); 因为赋值运算符=与逻辑运算符相比具有较低的优先级。 在第一个条件中,2的真值为true ,逻辑AND &&导致所有条件被评估,意味着j = 2也被评估,将2分配给j并返回2,其值为true 。 所以现在要评估的实际表达式是i = 2 && 2; 这是true ,或者用C表示,1。因此, i被赋值为1,第一个输出为12

对于第二个表达式(i=3) || (j=3); (i=3) || (j=3); ,逻辑OR || 使用,并且短路确保如果第一个条件的计算结果为true ,则整体表达式为true ,因此不评估第二个条件。 因此,在评估i = 3之后, i被赋值为3并且整个表达式为真,因此不评估j = 3 。 所以第二个输出是32

基于优先级,第一个表达式被评估为

  i = (2 && (j=2)); 

所以i = 1(真),j = 2。 这就是为什么第一个输出是12。

第二个表达式是两个赋值的逻辑OR。

 (i=3) || (j=3); 

但由于左边的第一次评估是“真实的”(i = 3),所以第二次评估没有完成。 这就是为什么j的值保持为2而第二个输出是32(而不是33)的原因。