首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

谜题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))

(3)
3

在这道谜题里,条件的求值结果是FALSE,所以这个条件表达式的值是“假”分支的值。

1.5.2

初始值:x=3,y=2,z=1

x < y ? x++ : y++
((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 += ((x < y) ? (x++) : (y++)))
(z += (FALSE ? (x++) : (y++)))

(z += ((y++)))

条件表达式的结果成为赋值操作符右侧部分的值(右值)。

(z += (3)),此时y=4
(z = z + 3)
(z = 4)
4

1.5.4

初始值:x=3,y=4,z=4

(z >= y >= x) ? 1 : 0
(((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))
((0))
0

1.5.5

初始值:x=3,y=4,z=4

z >= y && y >= x
((z >= y)&&(y >= x))

(TRUE&&(y>=x))
(TRUE&&TRUE)
(TRUE)
1

按从左到右的顺序求值。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论