确定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)的原因。