📄 习题5.1.txt
字号:
习题5.1
在下列表达式中,加入适当的圆括号以标明其计算顺序。编译该表达式并输出其值,从而检查你的回答是否正确。
12 / 3 * 4 + 5 * 15 + 24 % 4 / 2
【解答】
加入如下所示的圆括号以标明该表达式的计算顺序:
(((12 / 3) * 4) + (5 * 15)) + ((24 % 4) / 2)
习题5.2
计算下列表达式的值,并指出哪些结果值依赖于机器?
-30 * 3 + 21 / 5
-30 + 3 * 21 / 5
30 / 3 * 21 % 5
-30 / 3 * 21 % 4
【解答】
各表达式的值分别为-86、-18、0、-2。其中,最后一个表达式的结果值依赖于机器,因为该表达式中除操作只有一个操作数为负数。
习题5.3
编写一个表达式判断一个int型数值是偶数还是奇数。
【解答】
如下表达式可以判断一个int型数值(假设为ival)是偶数还是奇数:
ival % 2 == 0
若ival是偶数,则该表达式的值为真(true),否则为假(false)。
习题5.4
定义术语“溢出”的含义,并给出导致溢出的三个表达式。
【解答】
溢出:表达式的求值结果超出了其类型的表示范围。
如下表达式会导致溢出(假设int类型为16位):
1000 * 1000
32766 + 5
3276 * 20
在这些表达式中,各操作数均为int类型,因此这些表达式的类型也是int,但它们的计算结果均超出了16位int型的表示范围(-32768~32767),导致溢出。
习题5.5
解释逻辑与操作符、逻辑或操作符以及相等操作符的操作数在什么时候计算。
【解答】
逻辑与、逻辑或操作符采用称为“短路求值”(short-circuit evaluation)的求值策略,即先计算左操作数,再计算右操作数,且只有当仅靠左操作数的值无法确定该逻辑运算的结果时,才会计算右操作数。
相等操作符的左右操作数均需进行计算。
习题5.6
解释下列while循环条件的行为:
char *cp = "Hello World" ;
while ( cp && *cp )
【解答】
该while循环的条件为:当指针cp为非空指针并且cp所指向的字符不为空字符null('\0')时执行循环体。即该循环可以对字符串"Hello World"中的字符进行逐个处理。
习题5.7
编写while循环条件从标准输入设备读入整型(int)数据,当读入值为42时循环结束。
【解答】
int val;
cin >> val;
while (val != 42)
或者,while循环条件也可以写成
while (cin >> ival && ival != 42)
习题5.8
编写表达式判断4个值a、b、c和d是否满足a大于b、b大于c而且c大于d的条件。
【解答】
表达式如下:
a > b && b > c && c > d
习题5.9
假设有下面两个定义:
unsigned long ul1 =3, ul2 = 7;
下列表达式的结果是什么?
(a) ul1 & ul2 (b) ul1 && ul2
(c) ul1 | ul2 (d) ul1 || ul2
【解答】
各表达式的结果分别为3、true、7、true。
习题5.10
重写bitset表达式:使用下标操作符对测验结果进行置位(置1)和复位(置0)。
【解答】
bitset<30> bitset_quiz1;
bitset_quiz1[27] = 1;
bitset_quiz1[27] = 0;
习题5.11
请问每次赋值操作完成后,i和d的值分别是多少?
int i; double d;
d = i = 3.5;
i = d = 3.5;
【解答】
赋值语句d=i=3.5;完成后,i和d的值均为3。因为赋值操作具有右结合性,所以首先将3.5赋给i(此时发生隐式类型转换,将double型字面值3.5转换为int型值3,赋给i),然后将表达式i=3.5的值(即赋值后i所具有的值3)赋给d。
赋值语句i=d=3.5;完成后,d的值为3.5,i的值为3。因为先将字面值3.5赋给d,然后将表达式d=3.5的值(即赋值后d所具有的值3.5)赋给i(这时也同样发生隐式类型转换)。
习题5.12
解释每个if条件判断产生什么结果?
if ( 42 = i ) // ...
if ( i = 42 ) // ...
【解答】
前者发生语法错误,因为其条件表达式42=i是一个赋值表达式,赋值操作符的左操作数必须为一个左值,而字面值42不能作为左值使用。
后者代码合法,但其条件表达式i=42是一个永真式(即其逻辑值在任何情况下都为true),因为该赋值表达式的值为赋值操作完成后的i值(42),而42为非零值,解释为逻辑值true。
习题5.13
下列赋值操作是不合法的,为什么?怎样改正?
double dval; int ival; int *pi;
dval = ival = pi = 0;
【解答】
该赋值语句不合法,因为该语句首先将0值赋给pi,然后将pi的值赋给ival,再将ival的值赋给dval。pi、ival和dval的类型各不相同,因此要完成赋值必须进行隐式类型转换,但系统无法将int型指针pi的值隐式转换为ival所需的int型值。
可改正如下:
double dval; int ival; int *pi;
dval = ival = 0;
pi = 0;
习题5.14
虽然下列表达式都是合法的,但并不是程序员期望的操作,为什么?怎样修改这些表达式以使其能反映程序员的意图?
(a) if ( ptr = retrieve_pointer() != 0 )
(b) if ( ival = 1024 )
(c) ival += ival + 1;
【解答】
对于表达式(a),程序员的意图应该是将retrieve_pointer()的值赋给ptr,然后判断ptr的值是否为0,但因为操作符“=”的优先级比“!=”低,所以该表达式实际上是将retrieve_pointer()是否为0的判断结果true或false赋给ptr,因此不是程序员期望的操作。
对于表达式(b),程序员的意图应该是判断ival的值是否与1024相等,但误用了赋值操作符。
对于表达式(c),程序员的意图应该是使ival的值增加1,但误用了操作符“+=”。
各表达式可修改如下:
(a) if ( (ptr = retrieve_pointer()) != 0 )
(b) if ( ival == 1024 )
(c) ival += 1; 或 ival++; 或 ++ival;
习题5.15
解释前自增操作和后自增操作的差别。
【解答】
前自增操作和后自增操作都使其操作数加1,二者的差别在于:前自增操作将修改后操作数的值作为表达式的结果值;而后自增操作将操作数原来的、未修改的值作为表达式的结果值。
习题5.16
你认为为什么C++不叫作++C?
【解答】
C++之名是Rick Mascitti在1983年夏天定名的(参见The C++ Programming Language(Special Edition) 1.4节),C说明它本质上是从C语言演化而来的,“++”是C语言的自增操作符。C++语言是C语言的超集,是在C语言基础上进行的扩展(引入了new、delete等C语言中没有的操作符,增加了对面向对象程序设计的直接支持,等等),是先有C语言,再进行++。根据自增操作符前、后置形式的差别(参见习题5.15的解答),C++表示对C语言进行扩展之后,还可以使用C语言的内容;而写成++C则表示无法再使用C的原始值了,也就是说C++不能向下兼容C了,这与实际情况不符。
习题5.17
如果输出vector内容的while循环使用前自增操作符,那会怎么样?
【解答】
将导致错误的结果:ivec的第一个元素没有输出,并企图对一个多余的元素进行解引用。
上一页 首页 下一页
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -