《C语言解惑》一1.5 关系操作符和条件操作符

谜题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,所以这个条件表达式的值是“假”分支的值。

(3)

3

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

时间: 2024-11-03 17:18:45

《C语言解惑》一1.5 关系操作符和条件操作符的相关文章

《C语言解惑》一1.4 二进制位操作符

谜题1.4 二进制位操作符 请问,下面这个程序的输出是什么? define PRINT(int) printf(#int " = %d\n", int) main() { int x, y, z; x = 03; y = 02; z = 01; PRINT( x | Y & z ); (1.4.1) PRINT( x | y & ~ z ); (1.4.2) PRINT( x ^ y & ~ z ); (1.4.3) PRINT( x & y &

《C语言解惑》一1.3 逻辑操作符和增量操作符

谜题1.3 逻辑操作符和增量操作符 请问,下面这个程序的输出是什么? define PRINT(int) printf("%d\n",int) main() { int x, y, z; x = 2; y = 1; z = 0; x = x && y || z; PRINT(x); (1.3.1) PRINT( x || ! y && z ); (1.3.2) x = y = 1; z = x ++ - 1; PRINT(x); PRINT(z); (1

《C语言解惑》一导读

前言 C语言解惑 C语言并不大--如果以参考手册的篇幅作为衡量标准的话,C语言甚至可以归为一种"小"语言.不过,这种"小"并不意味着C语言的功能不够强大,而是说明了C语言里的限制性规则比较少.C语言本身的设计非常简洁精妙,这一点相信C语言的使用者早已有所体会. 不过,C语言的这种精妙对C语言的初学者来说,似乎是故作神秘.因为限制较少,C语言可以写成内容丰富的表达式,这可能会被初学者认为是输出错误.C语言的紧凑性允许以简洁凝炼的方式实现常见的编程任务. 学用C语言的过

《C语言解惑》一第1章 操作符1.1 基本算术操作符

第1章 操作符 C语言解惑 C语言程序由语句构成,而语句由表达式构成,表达式又由操作符和操作数构成.C语言中的操作符非常丰富--本书的附录B所给出的操作符汇总表就是最好的证据.正是因为这种丰富性,为操作符确定操作数的规则就成为了我们理解C语言表达式的核心和关键.那些规则--即所谓的"优先级"和"关联性"--汇总在本书附录A的操作符优先级表里.请使用该表格来解答本章中的谜题. 谜题1.1 基本算术操作符 请问,下面这个程序的输出是什么? main() { int x;

《C语言解惑》一1.6 操作符的优先级和求值顺序

谜题1.6 操作符的优先级和求值顺序 请问,下面这个程序的输出是什么? define PRINT3(x,y,z) \ printf(#x "=%d\t" #y "=%d\t" #z "=%d\n",x,y,z) main() { int x, y, z; x = y = z = 1; ++x || ++y && ++z; PRINT3(x,y,z); (1.6.1) x = y = z = 1; ++x && ++

《C语言解惑》—— 1.2 象形字体扰乱视听

1.2 象形字体扰乱视听 要特别注意形状相近的字母,最典型的是小写字母"l"和数字"1".以下面的程序为例. [例1.1]演示混淆字母"l"和数字"1"的错误程序. #include <stdio.h> void main() { double x=0; printf("输入x:"); scanf("%1f",&x); printf("输出x:%f\n&qu

《C语言解惑》—— 1.8 老大就是要在最前面

1.8 老大就是要在最前面 [例1.5]分析下面的程序错在哪里. #include <stdio.h> void main() { printf("输入n:"); int n; scanf("%d",&n); printf("%d\n",n); } 必须先声明变量n.C语言的变量声明必须在所有可执行语句之前,变量是老大,一定要在最前面.一定要牢记:变量必须先声明后使用.

《C语言解惑》—— 导读

前 言 C语言编程仍然是编程工作者必备的技能.目前有四类典型的学习C语言的教材:第一类是以讲授语法为主线,即流行的教科书方式,所涉及的例题均以正确的程序为主:第二类是以案例教学为主的教材,摆脱了语法的部分约束:第三类是以讲解编程技术为主的经验之作,主要针对已有编程基础的读者:第四类是针对编程容易产生错误的专题,对比正确与错误的程序以提高编程能力,涉及的内容比较专业.这些教材各有千秋,其共同的目的都是想教会读者如何编写正确.规范的程序.我们也曾在两部教材的每一章中尝试增加一节错误分析的内容,以期让

《C语言解惑》—— 第一篇 C语言编程中的对与错

第一篇 C语言编程中的对与错 本篇主要采用分析编程中存在的典型错误.对比正确与错误程序的方法,使读者加深印象并提高分辨语法对错及编程的能力,进而达到尽快掌握C语言编程基础知识的目的.