《C++ Primer》第五版课后习题解答_第六章(3)(16-26)

来源:互联网 发布:苹果系统装windows 编辑:程序博客网 时间:2024/06/07 10:03

系统环境: windows 10 1703

编译环境:Visual studio 2017


6.16

s 被定义成常量字符串引用会更好,否则只能和非常量字符串以及非字面量绑定,很有局限性。可以修改为:

bool is_empty(const string& s) { return s.empty(); }

6.17

(1) 判断是否有大写字母


ExamUpper.h

#pragma once#include <iostream>#include <string>using std::string;bool ExamUpper(const string &s);
ExamUpper.cpp

#include "ExamUpper.h"bool ExamUpper(const string &s){    for (decltype(s.size()) i = 0; i != s.size(); ++i)    {        if (isupper(s[i]))        {            return isupper(s[i]);        }        else if (i != s.size())        {            continue;        }    }    return isupper(s[0]);}
ExamMain.cpp

#include "ExamUpper.h"int main(){    string s;    getline(std::cin, s);    int a = ExamUpper(s);    std::cout << a << std::endl;    return 0;}
输入:love leonie 输出:0

输入:Love Leonie 输出:1


(2) 把 string 对象全部改成小写形式


s2lower.h

#pragma once#include <iostream>#include <string>using std::string;string s2lower( string &s);
s2lower.cpp

#include "s2lower.h"string s2lower(string &s){    for (auto &a : s)    {        a = tolower(a);    }    return s;}
s2lowerMain.cpp

#include "s2lower.h"int main(){    string s;    getline(std::cin, s);    s = s2lower(s);    std::cout << s << std::endl;    return 0;}
输入:LOVE LEONIE

输出:love leonie


(3) 在两个函数中我是用的形参类型不同。

  检查字符串中是否有大写的函数,形参类型是常量引用。原因有二:1. 避免拷贝大字符串造成的效率降低而是用引用类型;2. 无需在函数中改变原字符串的值,所以使用常量引用类型。

  改写字符串为小写形式的函数,形参类型为引用。原因有二:1.避免拷贝大字符串造成的效率降低而是用引用类型;2. 需要在函数中改变原字符串的值,所以使用非常量引用类型。


6.18

(a) 

    bool compare(matrix &matrix1, matrix &matrix2) { /*...*/ }
比较两个矩阵的内容是否相同,并返回一个布尔值。


(b)

    vector<int>::iterator change_val(int i, vector<int>::iterator j) { /*...*/ }

6.19

(a) 不合法,形参是有一个,却传入了两个参数;

(b) 合法;

(c) 合法;

(d) 合法(传入的浮点数 3.8 会先被强制转换成 int 类型,再参与函数运算)。


6.20

(1) 当传入的实参为常数,或者传入的实参的值不需要被改变,或者需要传入一个字符串字面值以初始化字符串引用时,需要用常量引用;

(2) 如果形参应该是常量引用,却设为了普通引用,会出现一些出人意料的后果。比如在用字符串字面值初始化引用时,会出现编译错误。或者当其他函数(正确地)将 string 类型的形参定义为常量引用,则错误定义的函数则不能在此类函数中正常使用(见教材 p192)。


6.21

compare.h

#pragma once#include <iostream>using std::cout;using std::cin;using std::endl;int compare(int ival, const int *ip);
compare.cpp

#include "compare.h"int compare(int ival, const int *ip){    int ans = (ival >= *ip) ? ival : *ip;    return ans;}
compareMain.cpp

#include "compare.h"int main(){    int i = 0;    int j = 0;    cout << "Enter two integers: " << endl;    cin >> i >> j;    int ans = compare(i, &j);    cout << "The bigger number is: " << ans << endl;    return 0;}
因为不需要更改实参的值,指针的类型应为常量整型指针。


6.22

swap.h

#pragma once#include <iostream>using std::cout;using std::cin;using std::endl;void swap(int *&ip1, int *&ip2);
swap.cpp

#include "swap.h"void swap(int *&ip1, int *&ip2){    int *temp;    temp = ip1;    ip1 = ip2;    ip2 = temp;}
swapMain.cpp

#include "swap.h"int main(){    int i = 0;    int j = 0;    int *ip = &i;    int *jp = &j;    cout << "Enter two integers: " << endl;    cin >> i >> j;    swap(ip, jp);    cout << "ip " << *ip << " jp " << *jp << endl;    return 0;}
输入 5 6

输出 ip 6 jp 5


6.23

print.h

#pragma once#include <iostream>using std::cout;using std::endl;using std::begin;using std::end;void print(const int *ip); // 函数 1void print(const int *beg, const int *end);// 函数 2void print(const int *ip, size_t size);// 函数 3void print(int(&ip)[2]);// 函数 4
print.cpp

#include "print.h"void print(const int *ip)// 函数 1{    if (ip)    {        while (*ip)        {            cout << *ip << endl;            ++ip;        }    }}void print(const int *beg, const int *end)// 函数 2{    while (beg != end)    {        cout << *beg++ << endl;        ++beg;    }}void print(const int *ip, size_t size)// 函数 3{    for (size_t i = 0; i != size; ++i)    {        cout << ip[0] << endl;    }}void print(int(&ip)[2])// 函数 4{    for (auto a : ip)    {        cout << a << endl;    }}
printMain.cpp

#include "print.h"int main(){    int i = 0, j[2] = { 0, 1 }, k[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};    print(&i); print(k); // 调用了函数 1,如果在这里选择 print(j),则会报错。                         // 因为函数 1,函数 4 同时可被此语句调用。而因为函数 4 规定了大小,所以 print(k) 只能被函数 1 调用    print(begin(j), end(j)); print(begin(k), end(k)); // 调用函数 2        print(j, end(j) - begin(j)); //调用函数 3    //函数 4 不能被调用,因为能满足函数 4 的实参类型,必定能满足函数 1。故尝试使用符合函数 4 要求的实参调用函数,必定会发生重载错误。    return 0;}

6.24

  函数想要输出一个长度为 10 的数组。但是,因为数组不能被拷贝,所以传入一个数组时,实际上传入的是指向该数组第一个元素的指针。所以如题所示定义函数,其实定义的形参是一个指针,不包含数组的长度信息,因此会出现错误。

  如果要想在传入的实参中包含数组的长度信息,应该采用数组引用形参,如下:

void print(const int (&ia)[10]){    for (size_t i = 0; i != 10; ++i)    {        cout << ia[i] << endl;    }}

6.25

#include <iostream>#include <string>using std::cout;using std::endl;using std::string;int main(int argc, char* argv[]){    string ans;    argc = 3;    argv[3] = 0; // 保证最后一个指针之后的元素为 0    ans = static_cast<string>(argv[1]) + " " + argv[2]; // 只有参数中存在字符串类型,才能使用加号连接,故用强制类型转换将其中一个参数转换成字符串类型    cout << ans << endl;    return 0;}
运行可执行文件时键入 Project1.exe Love Leonie

输出 Love Leonie


6.26

#include <iostream>#include <string>using std::cout;using std::endl;using std::string;int main(int argc, char* argv[]){    string ans;    argc = 5;    argv[5] = 0; // 保证最后一个指针之后的元素为 0    ans = static_cast<string>(argv[1]) + " " + argv[2] + " " + argv[3] + " " + argv[4];    cout << ans << endl;    return 0;}
运行可执行文件时键入 Project1.exe -d -o ofile data0

输出 -d -o ofile data0

阅读全文
0 0