参考链接:https://blog.csdn.net/misayaaaaa/article/details/53786215
https://blog.csdn.net/column/details/14252.html?&page=4
第四章习题答案(1-10)
1:运算符优先级的问题
主要记住小括号的利用、算术>关系>逻辑。
求值结果为:105
2:括号是无视优先级和结合律的,加上括号意味着很大的改变
(a) 可改为 *(vec.begin()) (b)可改为 (*vec.begin()+1)
3:复合表达式的处理:使用括号强制达到目的、重复改变可能会导致错误。
当然是可以的啦,关键还是编程者自己对于程序的改写。
4:91,取余是:%,除以求商是:/(直接删除余数,没有四舍五入!!!)。
5:答案:
(a) -86
(b) -18
(c) 0
(d) -2
6:奇数偶数,对二取余判断是否为0即可。
- int a;
- if (a%2)
- {
- cout<<"奇数"
- }
- else
- {
- cout<<"偶数"
- }
7:溢出的定义:当计算的结果超出了该类型所能表示的最大范围时就会产生溢出。
8:对于各种运算符的理解还是比较基础的。
9:cp是一个指针,指向一个字符串,*cp是一个字符串
二者皆不为空,所以结果为真。
10:
- int a;
- while((cin>>a) && (a != 42))
- {
- }
11:
- (a>b) && (b>c) && (c>d)
12:记住:算数>关系>逻辑
所以该式等同于:
- i != (j<k)
13:不同类型的赋值,肯定是需要强制类型转换的。
赋值运算符满足右结合律。
所以结果为:
(1): d=3.0 i=3
(2): d=3.5 i=3
14:第一条语句,将变量赋给常量,判断肯定是假。
第二条语句,将42赋给变量i,本身没有问题,但是在此此处会检验赋值的结果是否为真,42非0,所以为真。
一定要注意赋值和相等运算符的差异
15:pi是一个指针,不可以被赋值为0。
可改为:
- dval = ival = *pi = 1;
修正:0可以赋值给任何对象,这里0隐式地转换为null_ptr,此题错在指针类型不能隐式地转换为int整形类型。感谢评论区的小伙伴指正~@baidu_26426581
改正的方法同上。
16:赋值语句在这里被当作条件。可改为:
- if ((p=getPtr()) != 0)
- if (i == 10)
17:前置的递增运算符:先算后用,后置的递增运算符:先用后算。递减一样。
18:那么程序会输出第二个元素,直到最后一个元素的后一个位置(未知的量,非常危险)
19:直接修改正确的形式如下:
(a):(*ptr != 0) && (*ptr++) 判断ptr指针指向的int值是否为0
(b):判断ival和ival+1两个值是否都非0
(c):感谢评论区的两位同学指出错误:因为求值顺序不一定P123页,所以会产生未定义行为,vec[ival] <= vec[ival+1];
20:箭头运算符也是非常的重要啊!
首先介绍下点运算符,用于获取类对象的一个成员。点运算符与箭头运算符之间的关系:
ptr—>mem 与 (*ptr).mem 等价。
(a):合法:先对iter加1,再返回iter指向的值
(b):不合法:返回iter指向的值为string ++操作无意义
(c):不合法:iter是一个指针,没有empty()的成员
(d):合法:判断iter所指向的值是否为空
(e):不合法:*iter可以得到iter所指的字符串,但是字符串并没有++操作。
(f):合法:首先判断iter所指向的值是否为空,再对iter加1
21:关于条件运算符最主要的两点:cond ? exp1 : exp2
条件运算符的优先级很低,嵌套使用时最好加上括号
两个表达式的类型需要相同
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- void main()
- {
- int a[10] = {0,1,2,3,6,5,4,7,8,9};
- vector<int> v1(a,a+10);
- cout<<"Original vector"<<"\t";
- for (int i=0;i<10;i++)
- {
- cout<<v1[i]<<" ";
- }
- cout<<endl;
- cout<<"After the change"<<" ";
- for (int i=0;i<10;i++)
- {
- int j = ((v1[i] %2 ) ? i*2 : i);//条件表达式的使用
- cout<<j<< " ";
- }
- }
22:简单的嵌套使用
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- void main()
- {
- int grade;
- cout << "Please Input the grade :";
- cin >> grade;
- string finalgrade;
- finalgrade = (grade > 90) ? "high" : (grade > 70) ? "pass" : (grade > 60) ? "Low pass" : "fail";//条件运算符的嵌套
- cout << finalgrade;
- }
if版本
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- void main()
- {
- int grade;
- cout << "Please Input the grade :";
- cin >> grade;
- if (grade <= 90)
- {
- if (grade <= 75)
- {
- if (grade > 60)
- {
- cout<<"low pass"<<endl;
- }
- else
- {
- cout<<"fail"<<endl;
- }
- }
- else
- {
- cout<<"pass"<<endl;
- }
- }
- else
- {
- cout<<"High pass"<<endl;
- }
- }
if语句虽然较为直观,但是不够简洁,而条件运算符的嵌套次数如果过多,则会影响到代码的可读性
23:此处即为条件运算符的优先级过低引起的问题
改为
- string pl = s + (s[s.size() - 1] == 's' ? "" : "s") ;
24:自己代如一个数验证一下就会发现,如果是左结合律会引起矛盾。
25:位运算符还是要搞清楚
>> 右移 ——对象是无符号数,左侧插入值为0的二进制位 ; 对象是有符号数,左侧插入符号位的副本或0,视情况而定。
<< 左移 —— 右侧插入值为0的二进制位
(箭头指向那边,就往哪运动)
~ 位求反
注意题目要求,最后问的是“值”而不是字符了。所以应该由8位转向32位
最后的结果为:1111 1111 1111 1111 1110 0011 1000 0000 值为:-7296
26:因为老师学生有31个,所使用的类型最少需要有32位吧,但是在某些机器上,unsigned int 可能就不是32位了
27:注意一个和两个符号的区别,单符号&、 | 指的是位运算与、或 。
(a) 3
(b) 7
(c) (d) true
28:
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- void main()
- {
- cout<<sizeof(int)<<endl;//其他的类型也就这样就好了,首先就是了解你的机器,防止以后出现意外~
- }
29:这里主要考察sizeof函数的使用辨析
在对数组使用时,返回的是数组的大小;
在对指针使用是,返回的是指针本身的大小,32位机器的话就是1;
所以输出结果为10 ; 1
30:主要就是使用运算符优先级的知识点
(a) (sizeof x) +y
(b) sizeof(p->mem[i])
(c) (sizeof a) < b
(d) 无需改变。
也没有必要背下整个优先级表,暂时记住一些常用的就够用
31:对于逗号运算符,运算顺序是从左到右。前置是先操作,后使用,后置是先使用后操作。
- #include <iostream>
- #include <string>
- #include <vector>
- using namespace std;
- void main()
- {
- int array1[10] = {0,1,2,3,4,5,6,7,8,9};
- vector<int> vec1(array1,array1+9) ;
- vector<int>::size_type cnt = vec1.size();
- for (vector<int>::size_type ix = 0; ix != vec1.size(); ix++,cnt--)
- {
- vec1[ix] = cnt;
- cout<<cnt<<endl;
- }
- }
其实前置和后置的结果是一样的,不影响。
32:作用就是遍历此数组,利用的是两种方式:1:指针,2:数组大小。constexpr:常量表达式
33:逗号的运算优先级是最低的,这题要记住的就是拿不准的运算记住要用小括号表达。
- (someValue ? ++x, ++y : --x), --y
等价
34:如果某个运算符的运算对象类型不一致,则会产生类型转换,标准:
第一点:转换后类型需要能容纳原类型的所有值。
第二点:有符号无符号情况,有符号类型大于无符号类型,转换结果依赖于机器类型,若无符号类型的值皆能存入有符号类型,则会转换为有符号类型,否则会转换为无符号类型。无符号类型大于等于有符号类型,转换为无符号类型。
(a) fval转换为bool类型
(b)ival首先转换为fval,结果再转换为dval
(c)cval首先转换为ival,再转换为dval
35:这里说的皆是隐式转换
(a)a首先转换为int类型,结果再转换为char类型
(b)ival首先转换为double,ui再转换为double,结果转换为float类型
(c)ui首先转换为float类型,结果在转换为double类型
(d)ival首先转换为float类型,结果转换为double类型,再转换为char类型
36:显示类型转换就是指强制类型转换:cast-name<type>(expression)
type指的是转换的类型,expression指的是要转换的值。cast-name分四种:
static_cast 任何不包含底层const的类型转换,都可以使用static_cast
const_cast 只能改变运算对象是底层的const
强制类型转换是不被建议的形式,尽量避免使用,以免造成不必要的错误。
- i *= static_cast<int>(d);
先将d强制转换为int类型即可。
37:注意const的出现
(a)pv = const_cast<string*>(ps)
(b)i = static_cast<int>(*pc)
(c)pv = static_cast<void*>(&d)
(d)pc = reinterpret_cast<char*>(pv)
38:即强制转换为double类型