谜题1.5 关系操作符和条件操作符
请问,下面这个程序的输出是什么?
#define PRINT(int) printf(#int " = %d\n",int)
main()
{
int x=1, y=1, z=1;
x += y += z;
PRINT( x < y ? y : x ); (1.5.1)
PRINT( x < y ? x ++ : y ++ );
PRINT(x); PRINT(y); (1.5.2)
PRINT( z += x < y ? x ++ : y ++ );
PRINT(y); PRINT(z); (1.5.3)
x = 3; y = z = 4;
PRINT( (z >= y >= x) ? 1 : 0 ); (1.5.4)
PRINT( z >= y && y >= x ); (1.5.5)
}

输出:
x < y ? y : x = 3 (1.5.1)
x < y ? x ++ : y ++ = 2 (1.5.2)
x = 3
y = 3
z += x < y ? x ++ : y ++ = 4 (1.5.3)
y = 4
z = 4
(z >= y >= x) ? 1 : 0 = 0 (1.5.4)
z >= y && y >= x = 1 (1.5.5)

解惑1.5 关系操作符和条件操作符
1.5.1
|
初始值:x=3,y=2,z=1 |
|
|
x < y ? y : x |
|
|
(x < y) ? (y) : (x) |
除了涉及三个操作数以外,条件操作符与其他操作符没什么区别。 |
|
((x < y) ? (y) : (x)) |
|
|
(FALSE ? (y) : (x)) |
先对条件求值,再根据其求值结果对“真”或“假”两个分支之一进行处理——这两种情况不可能同时发生。 |
|
((x)) |
在这道谜题里,条件的求值结果是FALSE,所以这个条件表达式的值是“假”分支的值。 |
1.5.2
|
初始值:x=3,y=2,z=1 |
|
|
x < y ? x++ : y++ |
|
|
(FALSE ? (x++) : (y++)) |
先对条件求值。 |
|
((y++)) |
条件的求值结果是FALSE,所以接下来要对“假”分支进行求值。 |
|
(2),此时y=3 |
|
|
2 |
(请注意:因为x++没有被求值,所以x的值仍是3) |
1.5.3
|
初始值:x=3,y=3,z=1 |
|
|
z += x < y ? x++ : y++ |
|
|
(z += ((y++))) |
条件表达式的结果成为赋值操作符右侧部分的值(右值)。 |
|
(z += (3)),此时y=4 |
1.5.4
|
初始值:x=3,y=4,z=4 |
|
|
(z >= y >= x) ? 1 : 0 |
|
|
((TRUE >= x ) ? (1) : (0)) |
按从内到外的顺序对条件求值。 |
|
((1 >= x) ? (1) : (0)) |
最内层的条件的求值结果是TRUE。这个结果将与整数x进行比较。这种比较在C语言里是允许的,因为C语言里的TRUE值其实就是整数1。不过,这种做法并不好——具体到这道谜题,我们想检查z是否比y和x都大,但最终的求值结果显然不符合事实。(谜题1.5.5给出了对三个数值进行比较的正确做法。) |
|
(FALSE ? (1) : (0)) |
1.5.5
|
初始值:x=3,y=4,z=4 |
|
|
z >= y && y >= x |
|
|
(TRUE&&(y>=x)) |
按从左到右的顺序求值。 |






