C++ Primer第五版 第四章习题答案

参考链接: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即可。

[cpp]  view plain  copy
  1. int a;  
  2. if (a%2)  
  3. {  
  4.     cout<<"奇数"  
  5. }  
  6. else  
  7. {  
  8.     cout<<"偶数"  
  9. }  


7:溢出的定义:当计算的结果超出了该类型所能表示的最大范围时就会产生溢出


8:对于各种运算符的理解还是比较基础的。


9:cp是一个指针,指向一个字符串,*cp是一个字符串

二者皆不为空,所以结果为真。


10:

[cpp]  view plain  copy
  1. int a;  
  2. while((cin>>a) && (a != 42))  
  3. {  
  4. }  

11:

[cpp]  view plain  copy
  1. (a>b) && (b>c) && (c>d)  

12:记住:算数>关系>逻辑

所以该式等同于:

[cpp]  view plain  copy
  1. i != (j<k)  

13:不同类型的赋值,肯定是需要强制类型转换的。

赋值运算符满足右结合律。

所以结果为:

(1): d=3.0  i=3

(2): d=3.5  i=3


14:第一条语句,将变量赋给常量,判断肯定是假。

第二条语句,将42赋给变量i,本身没有问题,但是在此此处会检验赋值的结果是否为真,42非0,所以为真。

一定要注意赋值和相等运算符的差异


15:pi是一个指针,不可以被赋值为0。

可改为:

[cpp]  view plain  copy
  1. dval = ival = *pi = 1;  

修正:0可以赋值给任何对象,这里0隐式地转换为null_ptr,此题错在指针类型不能隐式地转换为int整形类型。感谢评论区的小伙伴指正~@baidu_26426581

改正的方法同上。


16:赋值语句在这里被当作条件。可改为:

[cpp]  view plain  copy
  1. if ((p=getPtr()) != 0)  
  2.   
  3. 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

条件运算符的优先级很低,嵌套使用时最好加上括号

两个表达式的类型需要相同

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. using namespace std;  
  5. void main()  
  6. {     
  7.     int a[10] = {0,1,2,3,6,5,4,7,8,9};  
  8.     vector<int> v1(a,a+10);  
  9.     cout<<"Original vector"<<"\t";  
  10.     for (int i=0;i<10;i++)  
  11.     {  
  12.         cout<<v1[i]<<" ";  
  13.     }  
  14.     cout<<endl;  
  15.     cout<<"After the change"<<" ";  
  16.     for (int i=0;i<10;i++)  
  17.     {  
  18.         int j = ((v1[i] %2 ) ? i*2 : i);//条件表达式的使用  
  19.         cout<<j<< " ";  
  20.     }  
  21. }  


22:简单的嵌套使用

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. using namespace std;  
  5. void main()  
  6. {     
  7.     int grade;  
  8.     cout << "Please Input the grade :";  
  9.     cin >> grade;  
  10.     string finalgrade;  
  11.     finalgrade = (grade > 90) ? "high" : (grade > 70) ? "pass" : (grade > 60) ? "Low pass" : "fail";//条件运算符的嵌套  
  12.     cout << finalgrade;  
  13. }  

if版本

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. using namespace std;  
  5. void main()  
  6. {     
  7.     int grade;  
  8.     cout << "Please Input the grade :";  
  9.     cin >> grade;  
  10.     if (grade <= 90)  
  11.     {  
  12.         if (grade <= 75)  
  13.         {  
  14.             if (grade > 60)  
  15.             {  
  16.                 cout<<"low pass"<<endl;  
  17.             }  
  18.             else  
  19.             {  
  20.                 cout<<"fail"<<endl;  
  21.             }  
  22.         }  
  23.         else  
  24.         {  
  25.             cout<<"pass"<<endl;  
  26.         }  
  27.     }  
  28.     else  
  29.     {  
  30.         cout<<"High pass"<<endl;  
  31.     }  
  32. }  

if语句虽然较为直观,但是不够简洁,而条件运算符的嵌套次数如果过多,则会影响到代码的可读性


23:此处即为条件运算符的优先级过低引起的问题

改为

[cpp]  view plain  copy
  1. 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:

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. using namespace std;  
  5. void main()  
  6. {     
  7.     cout<<sizeof(int)<<endl;//其他的类型也就这样就好了,首先就是了解你的机器,防止以后出现意外~  
  8. }  

29:这里主要考察sizeof函数的使用辨析

在对数组使用时,返回的是数组的大小;

在对指针使用是,返回的是指针本身的大小,32位机器的话就是1;

所以输出结果为10 ; 1


30:主要就是使用运算符优先级的知识点

(a)  (sizeof x) +y

(b)  sizeof(p->mem[i])

(c)  (sizeof a) < b

(d)  无需改变。


也没有必要背下整个优先级表,暂时记住一些常用的就够用


31:对于逗号运算符,运算顺序是从左到右。前置是先操作,后使用,后置是先使用后操作。

[cpp]  view plain  copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <vector>  
  4. using namespace std;  
  5. void main()  
  6. {     
  7.     int array1[10] = {0,1,2,3,4,5,6,7,8,9};  
  8.     vector<int> vec1(array1,array1+9) ;  
  9.     vector<int>::size_type cnt = vec1.size();  
  10.     for (vector<int>::size_type ix = 0; ix != vec1.size(); ix++,cnt--)  
  11.     {  
  12.         vec1[ix] = cnt;  
  13.         cout<<cnt<<endl;  
  14.     }  
  15. }  

其实前置和后置的结果是一样的,不影响。


32:作用就是遍历此数组,利用的是两种方式:1:指针,2:数组大小。constexpr:常量表达式


33:逗号的运算优先级是最低的,这题要记住的就是拿不准的运算记住要用小括号表达。

[cpp]  view plain  copy
  1. (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


强制类型转换是不被建议的形式,尽量避免使用,以免造成不必要的错误。

[cpp]  view plain  copy
  1. 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类型



猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/80196630