C++ Primer(第四版)答案之第五章

5.1

 (12/3)*4+(5*15)+24%(4/2)==16+75+0=91

 

5.2

-30*3+21/5=-90+4=-86,不依赖于机器

-30+3*21/5=-30+12=-18,不依赖于机器

30/3*21%5=0,不依赖于机器

-30/3*21%4=-2,依赖于机器

 

5.3

#include <iostream>

using namespace std;

int main() {
    int i;
    cin >> i;
    if (i%2)
        printf("odd number");
    else
        printf("even number");

    return 0;
}

 

5.4

溢出指的是计算出的数值超出了数据类型能够表示的范围。常见的溢出如下:

// 数组越界
int a[3];
a[4]=1;

// 除0
int a = 2/0;

// 赋值超过范围
unsigned short a = 65536;

 

5.5

逻辑与,短路求值,如果第一个操作数为true,才计算第二个操作数。

逻辑或,短路求值,如果第一操作数为false,才计算第二个操作数。

相等操作符的操作数,不论什么情况,都需要计算。

 

5.6

如果指针非空且不是'\0',那么执行循环体,用于遍历字符串。

 

5.7

#include <iostream>

using namespace std;

int main() {
    int a;
    while (cin >> a)
        if (a == 42)
            break;

    return 0;
}

 

5.8

if(a>b && b>c && c>d)
    // process code

 

5.9

ul  0011

ul2 0111

(a) 位运算,与,0011

(b) 逻辑运算,与,true

(c) 位运算,或,0111

(d) 逻辑运算,或,true

 

5.10

bitset<30> a;

a[3] = 1; // set()
a[3] = 0; // reset()

 

5.11

d=i=3.5, 则i=3, d=3.0

i = d = 3.5, 则i=3, d=3.5

 

5.12

第一行编译错误,42是字面值常量,不能赋值

第二行是true,先给变量i赋值42,然后测试i的值,非0表示true。

 

5.13

pi是指针类型,ival是整型,类型不一致,不能相互赋值。

dval = ival = *pi = 0;

 

5.14

(a) 赋值操作符的优先级低于比较操作符的优先级,修改为 if((ptr=retrieve_pointer()) != 0)

(b) 赋值操作符,不是比较操作符,赋值操作符,先赋值ival为1024,然后测试ival的值。改为:if(ival==1024)

(c) 赋值操作符的优先级低于 +操作符,先执行ival+1

 

5.15

前自增操作符,先自增,再返回自增后的值,返回左值,可以被赋值,效率更高。

后自增操作符,先用临时变量保存自增前的值,然后自增,然后返回临时副本,返回的是右值,不能被赋值。

 

5.16

因为,首先是继承C语言,然后添加了类特性,以及后来的模板、函数式编程等。

 

5.17

以迭代器的方式遍历,通常会忽略掉vector的第一个元素,而试图访问最后一个元素的下一个位置。

 

5.18

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main() {
    vector<string*> a;
    a.push_back(new string("C++"));
    a.push_back(new string("operator"));
    a.push_back(new string("over"));

    vector<string*>::iterator iter = a.begin();
    while (iter != a.end()) {
        printf("%s, %d\n", (*iter)->c_str(), (*iter)->size());
        iter++;
    }

    return 0;
}

 

5.19

(a) 合法,输出iter指向的string,之后iter指向下一个string

(b) 非法,string对象没有++操作

(c) 非法,iter是迭代器,也就是指针,没有empty成员函数。这是由于解引用操作符的优先级低于点操作符。

(d) 合法,获取iter指向的string是否为空。

(e) 非法,自增运算的优先级高于解引用运算符。

(f) 合法,虽然形式很诡异。

 

5.20

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main() {
    int a, b;
    cin >> a >> b;
    printf("max=%d, min=%d\n", a>b?a:b, a>b?b:a);

    return 0;
}

 

5.21

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main() {
    vector<int> a;
    for(size_t i=0; i<5; ++i)
        a.push_back(i);

    for(auto i=0; i<5; ++i)
        a[i] = a[i]%2?2*a[i]:a[i];

    for(auto iter=a.begin(); iter!=a.end(); ++iter)
        cout << *iter << endl;

    return 0;
}

 

5.22

#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>

using namespace std;

int main() {
    printf("%s=%d\n", typeid(int).name(), sizeof(int));
    printf("%s=%d\n", typeid(float).name(), sizeof(float));
    printf("%s=%d\n", typeid(double).name(), sizeof(double));
    printf("%s=%d\n", typeid(short).name(), sizeof(short));
    printf("%s=%d\n", typeid(bool).name(), sizeof(bool));
    printf("%s=%d\n", typeid(short).name(), sizeof(short));
    printf("%s=%d\n", typeid(long).name(), sizeof(long));

    return 0;
}

 

5.23

第一个输出是10,也就是数组的长度。x是数组名,不是指针,虽然在数组名当参数进行传递的时候,会转化成指针进行传递。同时数组名也是第一个元素的首地址。

第二个输出1。sizeof(p)=4,sizeof(*p)=4。

 

5.24

后自减操作,先使用变量的当前值,下一轮loop的时候,使用自减之后的值。

前自减操作,先使变量自减,然后使用变量的值。

本程序,想在ivec[ix]中存储,ix之后的元素个数。而5.5节存储着元素个数是包括当前元素的。

 

5.25

(a) (!ptr) == (ptr->next)

(b) ch = (buf[bp++]!='\n')

 

5.26

(a) !(ptr == ptr->next)

(b) (ch=buf[bp++]) != '\n'

 

5.27

string p1 = s + (s[s.size()-1]=='s'?'':'s')

 

5.28

我认为不可以接受,这是C++自由性泛滥的表现之一。实现效率和可维护性相比根本不值一提,尤其是C++这种表现能力极强的语言。减少潜在的缺陷应该优于实现效率。

 

5.29

(a) 判断ptr所指对象的ival是否为0

(b) 先判断jval<kval,其结果判断是否!= ival

(c) &&的优先级最低,先判断ptr是否空指针,然后判断ptr所指向的值是否为0

(d) 先执行ival++,判断ival原始的值,然后判断ival自加后的值

(e) 非法,未定义,C++对于2目运算符,只有&&,||,定义了计算顺序(从左至右),其余的2目运算符都没有定义。该表达式行为未定义。

 

5.30

(a) 合法,svec初始化10个元素,每个元素都是空字符串(string类型)

(b) 合法,在堆上创建vector,10个元素,元素的类型是string,默认空字符串。

(c) 非法,new 数组,数组元素个数10,每个元素都是一个vector<string>, pvec2应该是 vector<string>类型的指针,而不是指针的指针。

(d) 合法,pv1是vector<string>类型的指针

(e) 合法,pv2也是vector<string>类型的指针

(f) 非法,svec不是指针

(g) 合法

(g) 合法

(i) 非法,pv1指向非动态变量

(j) 合法。

 

5.31

(a) fval转换为bool类型

(b) ival转换为float类型,相加的结果,转换为double类型

(c) 通通转换为double类型

 

5.32

(a) 'a'转化为int

(b) ival转化为float,ui转化为float

(c) ui转化为float,结果转化为double

(d) ival先转化为float,相加的结果转化为double,最后的结果转化为char。

 

5.33

int ival;
double dval;
const string *ps;
char *pc;
void *pv;

pv = static_cast<void *>(const_cast<string*>(ps));
ival = static_cast<int>(*pc);
pv = static_cast<void*>(&dval);
pc = static_cast<char*>(pv);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值