4.13
详解:
- 赋值运算符遵循右结合律,从右侧开始计算
- 表达式(1)中先将
3.5
赋值给i
,在将i赋值给d
,因此d
与i
的结果是一致的 - 表达式(2)中先将
3.5
赋值给d
,此时不会发生精度损失,当把d
赋值给i
时,此时精度损失,所以i的值为3
int i;
double d;
d = i = 3.5; // d: 3 i: 3 (1)
i = d = 3.5; // i: 3.5 d: 3 (2)
4.14
执行下列if语句后将会发生什么情况?
int i = 0;
if (42 = i) // 报错
if (i = 42)
解:
- 第一条语句会发生编译错误,因为
42
为字面值,为右值。 - 第二条是正确的,执行的实际操作为先将
42
赋值给i
,然后if
语句对i
的值进行判断.
注意:因尽量避免在if语句中出现赋值语句!!
4.15
下面的赋值是非法的,为什么?应该怎么修改?
double dVal;
int iVal;
int *pi;
dVal = iVal = pi = 0;
解:
首先我们应该明确,当使用多重赋值语句时,每个对象类型应该一致或可以相互转换,而int
与int*
类型无法转换,因此会有编译问题.
dVal = iVal;
pi = nullptr;
4.16
下面的语句是合法的,但并不符合预期,为什么?应该怎么修改?
if (p = getPtr() != 0)
if (i = 42)
// 修改之后
if ((p = getPtr()) != 0)
if (i == 42)
详解:
- 第一条语句本意是想先将获取的指针赋值给
p
,然后在进行判断;但实际运算时,因为!=
的优先级大于=
,因此会先比较,后赋值。 - 第二条语句本意是判断
i
与42
是否相等,但在错误使用赋值运算符后,整个语句语义变为:将42
赋值给i
,然后判断i
。
4.17
说明前置递增与后置递增运算符的区别.
答:前置递增与后置递增运算符都会是运算对象+1,但区别在于:前置递增为先增加后运算,后置递增为先运算后递增。后置递增因为还要存储递增之前的值,造成不必要的资源浪费。
4.18
如果p132的那个输出vector对象的while循环使用前置递增运算符会造成什么样的后果?
答:当改为前置运算符后,迭代器会先++后执行解引用运算,当遍历到最后一项时,此时迭代器会指向一个根本不存在的值,此时解引用会导致程序崩溃。
std::vector<std::string > vec = {
"Hello",