《C++primer》v5 第3章 字符串、向量和数组 读书笔记 习题答案

3.1略

3.2

string str;

//读行
while(getline(cin,str))
cout<<str<<endl;

//读单个词

while(cin>>str)
cout<<str<<endl;

3.3

输入运算符读到空白符结束

getline读到换行符结束,并丢弃换行符

3.4

比较大小。

比较大小是比较的第一个不相同的字符的大小。

int main()
{
    string a,b;
    cin>>a>>b;
    if(a==b)
        cout<<a<<" "<<b<<endl;
    else if(a>b)
        cout<<a<<endl;
    else
        cout<<b<<endl;
    return 0;
}

比较长度。

int main()
{
    string a,b;
    cin>>a>>b;
    if(a.size()==b.size())
        cout<<a<<" "<<b<<endl;
    else if(a.size()>b.size())
        cout<<a<<endl;
    else
        cout<<b<<endl;
    return 0;
}

3.5

注意string类型的加法要求+两侧至少有一个是string类型。

int main()
{
    string a,str;
    while(cin>>a)
        str+=a;
    cout<<str<<endl;
    return 0;
}
int main()
{
    string a,str;
    while(cin>>a)
        str+=a+‘ ‘;
    cout<<str<<endl;
    return 0;
}

3.6

修改变量时,范围for循环要用引用

int main()
{
    string str;
    cin>>str;
    for(auto &c:str)
        c=‘X‘;
    cout<<str<<endl;
    return 0;
}

3.7

换成char&,结果似乎是一样的。。

int main()
{
    string str;
    cin>>str;
    for(char &c:str)
        c=‘X‘;
    cout<<str<<endl;
    return 0;
}

3.8

while

int main()
{
    string str;
    cin>>str;
    int i=0;
    while(i<str.size())
        str[i++]=‘X‘;
    cout<<str<<endl;
    return 0;
}

传统for循环

int main()
{
    string str;
    cin>>str;
    for(int i=0; i<str.size(); ++i)
        str[i]=‘X‘;
    cout<<str<<endl;
    return 0;
}

论方便程度:范围for>传统for>while。其实各有所长吧。

3.9

不合法。如果s为空则s[0]不存在,访问越界!

3.10

需要头文件cctype。第一个c表示从c语言继承而来。

int main()
{
    string str;
    cin>>str;
    for(auto c: str)
        if(!ispunct(c))
            cout<<c;
    return 0;
}

3.11

这是合法的。

auto &c,表示c是指向const char的引用,无法通过修改c来修改字符。

auto c,表示c是char字符的一个拷贝,因为auto不会保留顶层const,所以得到的不是常量。

3.12

(a)末尾的>>可能在旧的编译器中报错。本身定义无错。

(b)错,不同数据类型的vector不能赋值。任何不同的都不行!

(c)这个是对的。调用了vector的一个构造函数。

3.13

(a)空

(b)10个0

(c)10个42

(d)1个10

(e)1个10,1个42

(f)10个空string

(g)10个“hi”

3.14

int main()
{
    int num;
    vector<int> vec;
    while(cin>>num)
        vec.push_back(num);
    return 0;
}

3.15

int main()
{
    string str;
    vector<string> vec;
    while(cin>>str)
        vec.push_back(str);
    return 0;
}

3.16

int main()
{
    vector<int> vec;
    int val;
    while(cin>>val)
        vec.push_back(val);
    cout<<"size:"<<vec.size()<<endl;
    for(auto c:vec)
        cout<<c<<endl;
    return 0;
}

3.17、3.18

多重范围for循环除了最内层,其余都要用&,防止数组转化为指针。这里最内层用引用是因为要修改字符。

int main()
{
    vector<string> vec;
    string str;
    while(cin>>str)
        vec.push_back(str);
    for(auto &i:vec)
        for(auto &j:i)
            j=toupper(j);
    for(auto &i:vec)
        cout<<i<<endl;
    return 0;
}

3.19

int main()
{
    vector<int> a(10,42.5);
    vector<int> b={42,42,42,42,42,42,42,42,42,42};
    vector<int> c{42,42,42,42,42,42,42,42,42,42};
    return 0;
}

显然第一种方式最方便。但是第2、3种方式会提示精度损失的情况,但是第1种方式就不会。

3.20

int main()
{
    vector<int> vec;
    int val;
    while(cin>>val)
        vec.push_back(val);
    for(int i=1; i<vec.size(); ++i)
        cout<<vec[i]+vec[i-1]<<endl;
    for(int i=0; i<=(vec.size()-1)/2; ++i)
        cout<<vec[i]+vec[vec.size()-1-i]<<endl;
    return 0;
}

3.21

int main()
{
    vector<int> vec;
    int val;
    while(cin>>val)
        vec.push_back(val);
    for(vector<int>::iterator it=vec.begin(); it!=vec.end(); ++it)
        cout<<*it<<endl;
    return 0;
}

3.22

int main()
{
    string str;
    cin>>str;
    for(string::iterator it=str.begin(); it!=str.end(); ++it)
        *it=toupper(*it);
    cout<<str<<endl;
    return 0;
}

3.23

int main()
{
    vector<int> vec(10,66);
    for(vector<int>::iterator it=vec.begin();it!=vec.end();++it)
        *it*=2;
    for(auto i:vec)
        cout<<i<<endl;
    return 0;
}

3.24

经过测试,++vec.begin()返回第二个迭代器,但是vec.begin()仍然是第一个迭代器。

int main()
{
    vector<int> vec;
    int val;
    while(cin>>val)
        vec.push_back(val);
    for(vector<int>::iterator it=++vec.begin(); it!=vec.end(); ++it)
        cout<<*(it-1)+*it<<endl;
    for(vector<int>::iterator it=vec.begin(); it<=vec.begin()+(vec.end()-vec.begin()-1)/2; ++it)
        cout<<*it+*(vec.end()-1-(it-vec.begin()))<<endl;
    return 0;
}

3.25

*的优先级高于+-运算,因此需要先计算迭代器再解引用。而++优先级低于*,所以可以保证++的是解引用以后的值。

int main()
{
    vector<unsigned> scores(11,0);
    unsigned grade;
    while(cin>>grade)
        if(grade<=100)
            ++*(scores.begin()+grade/10);
    for(auto i:scores)
        cout<<i<<endl;
    return 0;
}

3.26

因为(beg+end)数值可能较大超出范围。

3.27

(a)合法

(b)合法

(c)可能非法。如果该函数返回非正数就会出现问题。

(d)非法,该字符串还有一个‘\0‘字符,所以需要至少12个元素来存放。

数组的下标是unsigned类型?

3.28

sa包含10个空的string,ia包含10个0。

sa2包含10个空的string,ia2包含10个未知数。

3.29

数组不能动态增长和添加删除元素。不能用数组直接赋值。。

3.30

不存在下标为array_size的元素,故访问越界

3.31

数组没有用括号初始化的方式,想想不奇怪,数组是内置数据类型,它不是类,没有构造函数。

int main()
{
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    return 0;
}

3.32

int main()
{
    int a[10]={0,1,2,3,4,5,6,7,8,9};
    vector<int> vec(begin(a),end(a));
    for(auto i:vec)
        cout<<i<<endl;
    return 0;
}

3.33

直接用下标访问将越界,因为不存在相应的元素。

3.34

将p1指向p2所在位置。

该式等价于p1=p1+p2-p1

如果p1+p2、p2-p1超出数组范围将非法。

3.35

int main()
{
    int a[10]= {0,1,2,3,4,5,6,7,8,9};
    for(int i=0; i<10; ++i)
        *(a+i)=0;
    for(auto i:a)
        cout<<i<<endl;
    return 0;
}

3.36

如果数组a小于数组b返回1,大于则返回-1,否则返回0。

int compareArray(int *a,int n1,int *b,int n2)
{
    int i=0;
    while(i<n1&&i<n2)
    {
        if(a[i]<b[i])
            return 1;
        else if(a[i]>b[i])
            return -1;
        i++;
    }
    if(n1==n2)
        return 0;
    else if(n1<n2)
        return 1;
    else
        return -1;
}
int compareVector(const vector<int> &a,const vector<int> &b)
{
    if(a==b)
        return 0;
    else if(a<b)
        return -1;
    else
        return 1;
}

3.37

代码原意是用一个指针指向了该常量字符数组,并遍历输出。

但是这个常量字符数组缺少了结束符,即‘\0‘。

所以遍历不会得到想要结果。

int main()
{
    const char ca[]={‘h‘,‘e‘,‘l‘,‘l‘,‘o‘};
    const char *cp=ca;
    while(*cp)
    {
        cout<<*cp<<endl;
        ++cp;
    }
    return 0;
}

3.38

两个指针就是两个地址(非空的情况下),请问两个地址相加有何意义?

3.39

int compareString(const string &a,const string &b)
{
    int i=0;
    while(i<a.size()&&i<b.size())
    {
        if(a[i]>b[i])
            return 1;
        else if(a[i]<b[i])
            return -1;
        i++;
    }
    if(a.size()==b.size())
        return 0;
    else if(a.size()>b.size())
        return 1;
    else
        return -1;
}
int compareChar(const char *a,const char *b)
{
    int i=0;
    while(a[i]&&b[i])
    {
        if(a[i]>b[i])
            return 1;
        else if(a[i]<b[i])
            return -1;
        i++;
    }
    if(!a[i]&&!b[i])
        return 0;
    else if(a[i])
        return 1;
    else
        return -1;
}

3.40

int main()
{
    char x[]="abc",y[]="xyz";
    char c[10];
    strcpy(c,x);
    strcat(c,y);
    puts(c);
    return 0;
}

3.41、3.42

int main()
{
    int a[5]= {0,1,2,3,4};
    vector<int> vec(begin(a),end(a));
    int b[5];
    for(int i=0; i<vec.size(); ++i)
        b[i]=vec[i];
    return 0;
}

3.43

这个题有点难度。值得研究一下。

int main()
{
    int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11};

    for(int (&i)[4]:ia)
        for(int j:i)
            cout<<j<<endl;

    for(int i=0; i<3; ++i)
        for(int j=0; j<4; ++j)
            cout<<ia[i][j]<<endl;

    for(int (*i)[4]=begin(ia); i!=end(ia); ++i)
        for(int *j=begin(*i); j!=end(*i); ++j)
            cout<<*j<<endl;
    return 0;
}

如果不用begin和end函数:

int main()
{
    int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11};
    for(int (*i)[4]=ia; i!=ia+3; ++i)
        for(int *j=*i; j!=*i+4; ++j)
            cout<<*j<<endl;
    return 0;
}

3.44

int main()
{
    int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11};
    using int_array =int[4];
    for(int_array &i:ia)
        for(int j:i)
            cout<<j<<endl;

    for(int_array *i=begin(ia); i!=end(ia); ++i)
        for(int *j=begin(*i); j!=end(*i); ++j)
            cout<<*j<<endl;
    return 0;
}

3.45

int main()
{
    int ia[3][4]= {0,1,2,3,6,5,4,7,8,9,10,11};
    for(auto &i:ia)
        for(auto j:i)
            cout<<j<<endl;

    for(auto i=begin(ia); i!=end(ia); ++i)
        for(auto *j=begin(*i); j!=end(*i); ++j)
            cout<<*j<<endl;
    return 0;
}

《C++primer》v5 第3章 字符串、向量和数组 读书笔记 习题答案,布布扣,bubuko.com

时间: 2024-10-14 22:22:19

《C++primer》v5 第3章 字符串、向量和数组 读书笔记 习题答案的相关文章

&lt;&lt;C++ Primer&gt;&gt; 第三章 字符串, 向量和数组 术语表

术语表 第 3 章 字符串, 向量和数组 begin: 是 string 和 vector 的成员,返回指向第一个元素的迭代器.也是一个标准库函数,输入一个数字,返回指向该数字首元素的指针. ?? 缓冲区溢出(buffer overflow): 一种严重的程序故障,主要的原因是试图通过一个越界的索引访问容器内容,容器类型包括 string,vector 和 数组等. ?? C 风格字符串(C-style string): 以空字符结束的字符数组.字符串字面值是 C 风格字符串,C风格字符串容易出

《C++primer》v5 第4章 表达式 读书笔记 习题答案

4.1 105 4.2 *vec.begin()=*(vec.begin())//先调用点运算符,再解引用 *vec.begin()+1=(*vec.begin())+1//先解引用,再加一 4.3略? 4.4 (12/3*4)+(5*15)+(24%4/2)=91 4.5 (a)-86(b)-16 (c)0 (d)0 4.6 n%2 4.7 溢出:计算结果超出该数据类型所能表示的范围 2147483647+1 1U-2 ... 4.8 比较低.. 4.9 首先判断cp是否为空指针,若非空指针则

《C++primer》v5 第2章 C++基础 读书笔记 习题答案

2.1 int,long long ,short 可表示范围和占用内存空间不同.具体与计算机有关. 无符号类型只能表示0和正数,带符号类型可以表示负数,0,正数. float是单精度,一般占用4个字节,double是双精度,一般占用8个字节,它们可表示的数据范围也不相同. 2.2 利率用double,本金和付款用int 2.3 unsigned u=10,u2=42; cout<<u2-u<<endl; cout<<u-u2<<endl; int i=10,

《C++primer》v5 第5章 语句 读书笔记 习题答案

5.1 空语句只有一个";".如果什么也不想做可以使用空语句. 5.2 用花括号{}括起来的叫块,也叫复合语句.有多条语句作用在同一个作用域时,需要用花括号括起来. 5.3 降低了. 5.4 (a)每次迭代时候会初始化iter,但是iter缺少初值,所以这段代码根本不会通过编译.另外这里的括号需要一个bool类型的,而定义迭代器根本不会返回一个bool类型.假如上面那些问题都可以通过,每次迭代都会初始化这个iter,会导致死循环. (b)我试了一下编译未通过是因为没找到适合的find函

《C++primer》v5 第1章 开始 读书笔记 习题答案

从今天开始在博客里写C++primer的文字.主要以后面的习题作业为主,会有必要的知识点补充. 本人也是菜鸟,可能有不对之处,还望指出. 前期内容可能会比较水. 1.1略 1.2略 1.3 cin和cout分别是istream和ostream的对象. #include<iostream> using namespace std; int main() { cout<<"Hello,world"<<endl; return 0; } 1.4 #incl

《C++primer》v5 第12章 动态内存 读书笔记 习题答案

这一章暂时没写完,先留着以后再写. 在C++程序中,程序员可以给手动开辟内存,但是这块内存需要手动释放,不便管理,因此新标准提供智能指针类型来管理动态对象.它负责自动释放所指向的对象. shared_prt允许多个指针指向同一个对象 unique_ptr独占所指向的对象 weak_ptr是一个弱引用,指向shared_ptr所管理的对象 一些操作: p=q;//递减p的引用计数,递增q的引用计数 shared_ptr<T> p(q);//p是q的拷贝,递增q的引用计数 通过make_share

《C++primer》v5 第10章 泛型算法 读书笔记 习题答案

10.1 using namespace std; int main() { vector<int> vec; int a; cin>>a; int v; while(cin>>v) vec.push_back(v); cout<<a<<" : "<<count(vec.begin(),vec.end(),a)<<endl; return 0; } 10.2 using namespace std; i

《C++primer》v5 第8章 IO库 读书笔记 习题答案

8.1.8.2 这一章不咋会啊.. istream &read(istream &is) { int a; auto old_state=is.rdstate(); is.clear(); is>>a; is.setstate(old_state); return is; } int main() { read(cin); return 0; } 8.3 读到eof或错误类型的时候 8.4 #include<fstream> using namespace std;

《C++primer》v5 第6章 函数 读书笔记 习题答案

6.1 实参是在函数调用处填写的参数.形参是在函数体使用的参数. 实参是形参的初始值. 具体参见:http://blog.163.com/zhengguo_li/blog/static/703014802013423501214/ 6.2 (a)该函数试图返回一个局部变量.当函数调用结束后,s所占内存将会被释放,所以返回s是无效的 (b)该函数缺少返回值 (c)定义了两个同名的形参 (d)后面的语句应该写在{}里 6.3.6.4 using namespace std; int fact(int