【C++ Primer】Part1·Day3 第四章 笔记及练习作答

学一门新的程序设计语言的最好方法就是不断地写代码。

基础

  一元运算符:作用于一个运算对象的运算符,如取地址符(&)和解引用符(*);
  二元运算符,三元运算符,重载运算符。函数调用是一种特殊的运算符,对运算对象的数量没有限制。

  C++的表达式要不然是左值,要不然是右值。当一个对象被用作左值时,用的是对象在内存中的位置;被用作右值时,用的对象的值(内容)。
  取地址符(&)作用于一个左值运算对象,返回一个指向该运算对象的指针,这个指针是右值。对于关键字decltype而言,如果表达式的求值结果是左值,decltype作用于该表达式得到一个引用类型;右值则得到一个指针类型。

  算术运算符的运算结果和求值结果都是右值。
  除法(/)运算中,符号相同商为正,否则商为负。C++早期版本允许结果为负值的商向上或向下取整,C++11规定商一律直接切除小数部分。取余(%)运算中,如果 m%n 不等于 0 则结果符号和 m 相同。除去 -m 导致溢出的情况,(-m) / n == m / (-n) == -(m / n)m % (-n) == m % n(-m) % (n) == -(m % n)

逻辑和关系运算符

  逻辑和关系运算符的运算结果和求值结果都是右值。
  逻辑与(&&)、逻辑非(||)、条件(?:)和逗号(,)运算符明确规定了求值顺序。短路求值,先求左侧运算对象的值再求右侧运算对象的值,当且仅当做出无法确定结果才会计算右侧。

递增和递减运算符

  ++i 前置版本 :将对象本身作为左值返回;
  i++ 后置版本 :将对象原始值的副本作为右值返回。尽量不使用后置++。

  后置++的优先级高于解引用运算符(*),可以用于迭代器循环。

成员访问运算符

  获取类对象的一个成员,如 p->num 等价于 (*p).num。
  箭头运算符(->)作用于一个指针类型的运算对象,结果是左值;点运算符中,成员所属对象为左值结果为左值,反之右值。
  点运算符优先级高于解引用运算符。

条件运算符

  好用简易版的 if-else。即 cond ? expr1 : expr2;。可以嵌套使用。
  当两个表达式都是左值或能转换成同一种左值类型时,运算结果是左值;否则都是右值。

位运算符

  作用于整数类型的运算对象,可能会发生类型提升。
  尽量将位运算符用于处理无符号类型。

移位运算符

  左移运算符(<<):在右侧插入值为 0 的二进制位。
  右移运算符(>>):运算对象为无符号类型,在左侧插入值为 0 的二进制位;为带符号类型,在左侧插入符号位的副本或值为 0 的二进制位。
  具体操作:令左侧运算对象的内容按照右侧运算对象的要求移动位数,然后将移动后的(可能进行了类型提升的)左侧运算对象的拷贝作为求值结果。右侧运算对象一定不能为负,且值严格小于结果的位数。移出边界之外的位会被舍弃掉。

  移位运算符进行IO操作时(重载版本)又称IO运算符,满足左结合律。比算术运算符的优先级低,比关系运算符、赋值运算符和条件运算符的优先级高。

其他位运算符

  位求反(~):将运算对象逐位求反后生成新值,即将1置0、将0置1。

  位与(&):两个运算对象对应位置都为 1 则运算结果该位为 1 ,否则为0;
  位或(|):两个运算对象对应位置至少有一个为 1 则运算结果该位为 1 ,否则为0;
  位异或(^):两个运算对象对应位置有且只有一个为 1 则运算结果该位为 1 ,否则为0;

sizeof运算符

  返回一条表达式或一个类型名字所占的字节数的值,size_t 类型的常量表达式。
  满足右结合律(表达式按照从右到左的顺序组合)。不会把数组转换成指针来处理。对string、vector对象执行只返回该类型固定部分的大小,不计算对象中元素占用空间。

逗号运算符

  含两个运算对象,从左到右依次求值。
  先左侧求值并丢弃求值结果,右侧求值并返回求值结果。

类型转换

隐式转换

  算术转换:把一种算术类型转换成另一种算术类型。运算符的运算对象将转换成最宽的类型。当表达式中既有浮点类型也有整数类型,整数转成浮点数。整数提升:把小整数类型转换成较大整数类型。
  指针转换:大多数情况,数组自动转换成指向数组首元素的指针。常量整数值 0 或字面值nullptr能转换成任意指针类型,指向任意非常量的指针能转换成 void*,指向任意对象的指针能转换成 const void*。允许将指向非常量类型的指针转换成指向相应的常量类型的指针,引用也是。

显式转换

  强制转换类型。转换的目标类型为引用类型则结果为左值。

  static_cast:除包含底层 const 外的任何具有明确定义的类型转换都可以使用。
  const_cast:改变表达式的常量属性。
  reinterpret_cast:为运算对象的位模式提供较低层次上的重新解释。(不会)
  dynamic_cast:支持允许时类型识别。(不懂)


---------------------------------------------------------- \我 是 分 割 线/ ----------------------------------------------------------

小昭 の 练习作答

4.1 105。
4.2 (a) *( vec.begin() ) ;(b) *( vec.begin() )+1。(没看懂这题)
4.3 可以接受。理由阿巴阿巴。
4.4 略
4.5 -86,-18,0,-2。
4.6 (i % 2 == 0) ? 偶数 : 奇数。
4.7 溢出是指求值结果超出该类型的最大值或最小值。

int a = 2147483647;a++;
int b = 2000000000;cout << b*b << endl;
int c = -2147483647;c--;

4.8 略。
4.9 先判断指针cp内是否存放有地址,若为真,再判断指针cp指向的对象是否有值。
4.10~4.11

int value;
while(cin >> value && value != 42) cout << "hhh" << endl;

int a, b, c, d;
cin >> a >> b >> c >> d;
if(d < c && c < b && b < a) cout << "满足了" << endl;
else cout << "不满足" << endl;

4.12 先计算 j < k 的运算结果,再进行 i != 运算结果 的运算,即 ( i != (j < k) )。考虑运算符优先级。
4.13 (a) 3,3;(b)3,3.5。
4.14 第一行报错。第二行括号内返回true,会执行下面的语句。
4.15 int* 类型不能转换成int 类型。dval = ival = 0;pi = &ival;
4.16 例题都有。
4.17 略
4.18 报错。
4.19

(a) 指针不为空且指针指向的对象不为空,并向前走一步;
(b) ?(也不能说不正确?)
(c) 两个相邻元素的大小比较。

4.20

(b) 不合法。iter指向的元素自增1,但元素的类型是string。
(c) 不合法。指针iter没有成员empty()

4.21~4.22

for(auto v : vector) v = (v % 2 == 1) ? v*2 : v;

final = (grade > 90) ? "high pass" 
	  : (grade > 75) ? "low pass"
	  : (grade > 60) ? "pass" : "fail";
	  
if(grade > 90) final = "high pass";
else if(grade > 75) final = "low pass";
else if(grade > 60) final = "pass";
else final = "fail"; 

4.23 string p1 = s + (s[s.size() - 1] == 's' ? "" : "s"); 加法优先级大于条件优先级。
4.24 可能会将 “high pass” 作为下一个条件表达式的判断条件,报错。
4.25 -7296。

一种解法
~(01110001) = 10001110(142),而char只占8位即-128127,计算机补码得11110010(-114)-114 << 6 == -114 * 2 ^ 6 。

计算机进行补码(10001110,142)转真值(11110010,-114)过程
1,0001110 第一位为符号位
1,1110001 除符号位全部取反
1,1110010 末尾加一 
1,1110010 七位二进制数值114,符号位为1,结果为-114

4.26 int类型只能确保占用16位,不足以容纳所有结果。
4.27 3,7,1(true),1(true)。
4.28 略
4.29 10,1。第一行输出数组x的元素数量;第二行输出中,sizeof§计算的是指针p所占内存空间,sizeof(*p)是指针p指向的对象所占内存空间,实际上是相同的。
4.30

 (a) (sizeof(x) + y
 (b) sizeof(p->mem[i])
 (c) (sizeof(a)) < b
 (d) sizeof(f())

4.31 后置版本会产生副本拷贝,消耗没必要的性能。

vector<int>::size_type cnt = ivec.size();
for (vector<int>::size_type ix = 0; ix != ivec.size(); ix++, cnt--)
		ivec[ix] = cnt;

4.32 数组的值与下标同时遍历。
4.33 逗号优先级最低,等价于(someValue ?(++x , ++y) :--x) , --y;
4.34

(a) float -> bool ; 
(b) int -> float , float -> double ; 
(c) char -> int , int -> double.

4.35

(a) 'a'提升为 int3 相加,转成 char(b) ival 转成 double 乘以 1.0 再转成 unsigned int ,与 ui 相减,转成 float(c) unsigned int 转成 float,与 fval 相乘,转成 double(d) ival 转成 float 与 fval 相加, 加法结果转成 double 与 dval 相加,转成 char

4.36 i *= static_cast<int>(d);
4.37

(a) pv = const_cast<string *>(ps);
(b) i = static_cast<int>(*pc);
(c) pv = static_cast<void *>(&d);
(d) pc = static_cast<char *>(pv);

4.38 将 j / i 的计算结果强制转换成 double类型并赋值给变量 slope,等价于 double slope = j / i。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值