c++ primer 题解 2020.1.10

265 阅读6分钟

3.1:使用恰当的using声明重做1.4.1节(第11页)和2.6.2节(第67页)的练习。

1.4.1
int main() {
    using namespace std;
    int i = 50;
    while (i <= 100) {
        cout << i << endl;
        i++;
    }
    return 0;
}
2.6.2
1.2.0
#include <iostream>

using namespace std;

struct Sale_data {
    string bookNo;
    string bookName;
    unsigned units_sold = 0; // 销售量
    double selling_price = 0.0; // selling
    double price = 0.0; // 定价
    double discount = 0.0; // 折扣
};

int main() {
    Sale_data sale;
    cerr << "请输入一组销售记录" << endl;
    cin >> sale.bookNo >> sale.units_sold >> sale.selling_price;
    cout << sale.bookNo << " " << sale.units_sold << sale.selling_price * sale.units_sold;
    return 0;
}
1.2.1
#include <iostream>

using namespace std;

struct Sale_data {
    string bookNo;
    string bookName;
    unsigned units_sold = 0; // 销售量
    double selling_price = 0.0; // selling
    double price = 0.0; // 定价
    double discount = 0.0; // 折扣
};

int main() {
    Sale_data sale1, sale2;
    cerr << "请输入两条 isbn 相同的销售记录" << endl;
    cin >> sale1.bookNo >> sale1.units_sold >> sale1.selling_price;
    cin >> sale2.bookNo >> sale2.units_sold >> sale2.selling_price;
    if (sale1.bookNo == sale2.bookNo) {
        cout << sale1.bookNo << " " << sale1.units_sold + sale2.units_sold
             << sale1.selling_price * sale1.units_sold + sale2.selling_price * sale2.units_sold;
    } else {
        cerr << "两条销售记录的 isbn 编号必须相同";
        return -1;
    }

    return 0;
}
1.2.2
#include <iostream>

using namespace std;

struct Sale_data {
    string bookNo;
    string bookName;
    unsigned units_sold = 0; // 销售量
    double selling_price = 0.0; // selling
    double price = 0.0; // 定价
    double discount = 0.0; // 折扣
};

int main() {
    Sale_data total, sale;
    cerr << "请输入多条 isbn 相同的销售记录" << std::endl;
    if (cin >> total.bookNo >> total.units_sold >> total.selling_price) {
        double revenue = total.selling_price * total.units_sold;
        while (cin >> sale.bookNo >> sale.units_sold >> sale.selling_price) {
            if (total.bookNo == sale.bookNo) {
                total.units_sold += sale.units_sold;
                revenue += sale.selling_price * sale.units_sold;
            } else {
                cerr << "输入了 isbn 不相同的销售记录";
                return -1;
            }
        }
        cout << total.bookNo << total.units_sold << revenue;
    } else {
        cerr << "错误的销售记录";
        return -1;
    }
    return 0;
}

3.2:编写一段程序从标准输入中一次读入一整行,然后修改该程序使其一次读入一个词。

读取一行
#include <iostream>
#include <string>

using namespace std;

int main() {
    string line;
    while (getline(cin, line)) {
        cout << line << endl;
    }
    return 0;
}
读取一个单词
#include <iostream>
#include <string>

using namespace std;

int main() {
    string word;
    while (cin >> word) {
        cout << word << endl;
    }
    return 0;
}

3.3:请说明string类的输入运算符和getline函数分别是如何处理空白字符的。

输入运算符会忽略开头的空白(即空格符,换行符,制表符等)并从第一个真正的字符开始读起,直到遇到下一处空白为止

getline函数从给定的输入流中读入内容,直到遇到换行符结束,且不会跳过空白符。getline函数会把结尾的换行符也读入,但是并不会把换行符存入string对象中

3.4:编写一段程序读入两个字符串,比较其是否相等并输出结果。如果不相等,输出较大的那个字符串。改写上述程序,比较输入的两个字符串是否等长,如果不等长,输出长度较大的那个字符串。

输出较大的字符串
#include <iostream>
#include <string>

using namespace std;

int main() {
    string first;
    string second;
    while (cin >> first >> second) {
        cout << (first > second ? first : second) << endl;
    }
    return 0;
}
输出较长的字符串
#include <iostream>
#include <string>

using namespace std;

int main() {
    string first;
    string second;
    while (cin >> first >> second) {
        cout << (first.size() > second.size() ? first : second) << endl;
    }
    return 0;
}

3.5:编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来。

直接连在一起输出
#include <iostream>
#include <string>

using namespace std;

int main() {
    string first;
    string second;
    if (cin >> first) {
        while (cin >> second) {
            first += second;
        }
    } else {
        cerr << "输入错误";
        return -1;
    }
    cout << first << endl;
    return 0;
}
用空格分隔开来输出
#include <iostream>
#include <string>

using namespace std;

int main() {
    string first;
    string second;
    if (cin >> first) {
        while (cin >> second) {
            first += " " + second;
        }
    } else {
        cerr << "输入错误";
        return -1;
    }
    cout << first << endl;
    return 0;
}

3.6:编写一段程序,使用范围for语句将字符串内的所有字符用X代替。

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "hello world";

    for (auto &item : str) {
        item = 'x';
    }
    cout << str << endl;
    return 0;
}

3.7:就上一题完成的程序而言,如果将循环控制变量的类型设为char将发生什么?先估计一下结果,然后实际编程进行验证。

结果不会有任何变化,因为string本身就是可变长字符序列,其中的每个元素自然都是char类型

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "hello world";

    for (char &item : str) {
        item = 'x';
    }
    cout << str << endl;
    return 0;
}
// xxxxxxxxxxx

3.8:分别用while循环和传统的for循环重写第一题的程序,你觉得哪种形式更好呢?为什么?

while 版本

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "hello world";

    decltype(str.size()) index = 0;

    while (index < str.size()) {
        str[index] = 'x';
        index++;
    }

    cout << str << endl;
    return 0;
}

传统 for 版本

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "hello world";
    for (decltype(str.size()) i = 0; i < str.size(); ++i) {
        str[i] = 'x';
    }
    cout << str << endl;
    return 0;
}

在这种不需要对某些元素特殊处理的情况下,范围for循环更好。不必额外定义变量,内容简洁明了

3.9:下面的程序有何作用?它合法吗?如果不合法,为什么?

string s;
cout << s[0] << endl;

输出字符串的首个元素,但是并不合法。因为 s 为空字符串,访问 s[0] 会造成越界

3.10:编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余的部分。

#include <iostream>
#include <string>

using namespace std;

int main() {
    string s;
    string res;
    if (cin >> s) {
        for (const auto &item : s) {
            if (!ispunct(item)) {
                res += item;
            }
        }
    } else {
        cerr << "输入错误";
        return -1;
    }
    cout << res << endl;
    return 0;
}

3.11:下面的范围for语句合法吗?如果合法,c的类型是什么?

const string s = "Keep out!";
for (auto &item : s) {/**/}

合法,s为字符串常量,则 c 为 const char & 类型,auto在推断时,保留了底层 const 属性

3.12:下列vector对象的定义有不正确的吗?如果有,请指出来。对于正确的,描述其执行结果;对于不正确的,说明其错误的原因。

(a) vector<vector<int>> ivec;
(b) vector<string> svec = ivec;
(c) vector<string> svec(10, "null");

(a)正确,ivec是一个空vector

(b)错误,执行向量拷贝时,两个向量的类型必须相同

(c)正确,svec中有10个元素,每个的值都是"null"

3.13:下列的vector对象各包含多少个元素?这些元素的值分别是多少?

(a) vector<int> v1;
(b) vector<int> v2(10);
(c) vector<int> v3(10, 42);
(d) vector<int> v4{10};
(e) vector<int> v5{10, 42};
(f) vector<string> v6{10};
(g) vector<string> v7{10, "hi"};

(a) 空vector

(b) 10个int元素,每个元素值都是0

(c) 10个int元素,每个的值都是42

(d) 1个元素,值为10

(e) 2个元素,10,42

(f) 10个元素,每个元素都为空字符串

(g) 10个元素,每个都是 “hi”

3.14:编写一段程序,用cin读入一组整数并把它们存入一个vector对象。

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

3.15:改写上题的程序,不过这次读入的是字符串。

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

3.16:编写一段程序,把练习3.13中vector对象的容量和具体内容输出出来。检验你之前的回答是否正确,如果不对,回过头重新学习3.3.1节(第87页)直到弄明白错在何处为止。

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

using namespace std;

int main() {
    vector<int> v1;
    vector<int> v2(10);
    vector<int> v3(10, 42);
    vector<int> v4{10};
    vector<int> v5{10, 42};
    vector<string> v6{10};
    vector<string> v7{10, "hi"};

    cout << "v1: ";
    for (const auto &item : v1) {
        cout << item << " , ";
    }
    cout << endl;

    cout << "v2: ";
    for (const auto &item : v2) {
        cout << item << " , ";
    }
    cout << endl;

    cout << "v3: ";
    for (const auto &item : v3) {
        cout << item << " , ";
    }
    cout << endl;

    cout << "v4: ";
    for (const auto &item : v4) {
        cout << item << " , ";
    }
    cout << endl;

    cout << "v5: ";
    for (const auto &item : v5) {
        cout << item << " , ";
    }
    cout << endl;

    cout << "v6: ";
    for (const auto &item : v6) {
        cout << item << " , ";
    }
    cout << endl;

    cout << "v7: ";
    for (const auto &item : v7) {
        cout << item << " , ";
    }
    return 0;
}
v1: 
v2: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 
v3: 42 , 42 , 42 , 42 , 42 , 42 , 42 , 42 , 42 , 42 , 
v4: 10 , 
v5: 10 , 42 , 
v6:  ,  ,  ,  ,  ,  ,  ,  ,  ,  , 
v7: hi , hi , hi , hi , hi , hi , hi , hi , hi , hi , 

3.17:从cin读入一组词并把它们存入一个vector对象,然后设法把所有词都改写为大写形式。输出改变后的结果,每个词占一行。

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

using namespace std;

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

3.18:下面的程序合法吗?如果不合法,你准备如何修改?

vector<int> ivec;
ivec[0] = 42;

不合法,因为 ivec 为空的 vecotr ,而在 c++ 中只能对已知存在的元素进行下标操作

改正:

vector<int> ivec;
ivec.push_back(42);

3.19:如果想定义一个含有10个元素的vector对象,所有元素的值都是42,请列举出三种不同的实现方法。哪种方法更好呢?为什么?

// 方式1
vector<int> ivec1 = {42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
// 方式2
vector<int> ivec2(10, 42);
// 方式3
vector<int> ivec3;
for (int i = 0; i < 10; ++i) {
  ivec3.push_back(42);
}
// 方式4
vector<int> ivec4(10);
for (int i = 0; i < ivec4.size(); ++i) {
  ivec4[i] = 42;
}

3.20:读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来。改写你的程序,这次要求先输出第1个和最后1个元素的和,接着输出第2个和倒数第2个元素的和,以此类推。

// 输出相邻两数的和
vector<int> vec;
int num;
while (cin >> num) {
  vec.push_back(num);
}
for (decltype(vec.size()) i = 0; i < vec.size(); ++i) {
  if (i % 2 != 0) {
    cout << vec[i - 1] << " + " << vec[i] << " = " << vec[i - 1] + vec[i] << endl;
  } else if (i == vec.size() - 1) {
    cout << vec[i];
  }
}

// 输出首位元素的和
vector<int> vec;
int num;
while (cin >> num) {
  vec.push_back(num);
}
for (decltype(vec.size()) i = 0, j = vec.size() - 1; i <= j; ++i, --j) {
  if (i != j) {
    cout << vec[i] << " + " << vec[j] << " = " << vec[i] + vec[j] << endl;
  } else {
    cout << vec[i];
  }
}

3.21:请使用迭代器重做3.3.3节(第94页)的第一个练习。

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

using namespace std;

int main() {
    vector<int> v1;
    vector<int> v2(10);
    vector<int> v3(10, 42);
    vector<int> v4{10};
    vector<int> v5{10, 42};
    vector<string> v6{10};
    vector<string> v7{10, "hi"};

    cout << "v1: ";
    for (auto iter = v1.begin(); iter != v1.end(); ++iter) {
        cout << *iter << " , ";
    }
    cout << endl;

    cout << "v2: ";
    for (auto iter = v2.begin(); iter != v2.end(); ++iter) {
        cout << *iter << " , ";
    }
    cout << endl;

    cout << "v3: ";
    for (auto iter = v3.begin(); iter != v3.end(); ++iter) {
        cout << *iter << " , ";
    }
    cout << endl;

    cout << "v4: ";
    for (auto iter = v4.begin(); iter != v4.end(); ++iter) {
        cout << *iter << " , ";
    }
    cout << endl;

    cout << "v5: ";
    for (auto iter = v5.begin(); iter != v5.end(); ++iter) {
        cout << *iter << " , ";
    }
    cout << endl;

    cout << "v6: ";
    for (auto iter = v6.begin(); iter != v6.end(); ++iter) {
        cout << *iter << " , ";
    }
    cout << endl;

    cout << "v7: ";
    for (auto iter = v7.begin(); iter != v7.end(); ++iter) {
        cout << *iter << " , ";
    }
    return 0;
}
v1: 
v2: 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 
v3: 42 , 42 , 42 , 42 , 42 , 42 , 42 , 42 , 42 , 42 , 
v4: 10 , 
v5: 10 , 42 , 
v6:  ,  ,  ,  ,  ,  ,  ,  ,  ,  , 
v7: hi , hi , hi , hi , hi , hi , hi , hi , hi , hi , 

3.22:修改之前那个输出text第一段的程序,首先把text的第一段全都改成大写形式,然后再输出它。

vector<string> text = {"hello", "world", "", "nice", "c++"};
for (auto tIter = text.begin(); tIter != text.end() && !tIter->empty(); ++tIter) {
  for (auto iIter = tIter->begin(); iIter != tIter->end(); ++iIter) {
    *iIter = toupper(*iIter);
  }
  cout << *tIter << endl;
}

3.23:编写一段程序,创建一个含有10个整数的vector对象,然后使用迭代器将所有元素的值都变成原来的两倍。输出vector对象的内容,检验程序是否正确。

vector<int> vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
  *iter *= 2;
}
for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
  cout << *iter << " , ";
}
2 , 4 , 6 , 8 , 10 , 12 , 14 , 16 , 18 , 20 , 

3.24:请使用迭代器重做3.3.3节(第94页)的最后一个练习。

int main() {
    vector<int> vec;
    int num;

    while (cin >> num) {
        vec.push_back(num);
    }

    for (auto i = vec.begin(), j = vec.end() - 1; i <= j; ++i, --j) {
        if (i != j) {
            cout << *i << " + " << *j << " = " << *i + *j << endl;
        } else {
            cout << *i << endl;
        }
    }
    
    return 0;
}

3.25:3.3.3节(第93页)划分分数段的程序是使用下标运算符实现的,请利用迭代器改写该程序并实现完全相同的功能。

int main() {
    vector<int> vec(10);
    auto beg = vec.begin();
    int score;
    while (cin >> score) {
        *(beg + score / 10) += 1;
    }
    for (const auto &item : vec) {
        cout << item << " , ";
    }
    return 0;
}

3.26:在100页的二分搜索程序中,为什么用的是mid =beg + (end - beg) / 2,而非mid = (beg + end) /2;?

迭代器不支持加法运算,所以 ( beg + end ) / 2 不合法

3.27:假设txt_size是一个无参数的函数,它的返回值是int。请回答下列哪个定义是非法的?为什么?

unsigned buf_size = 1024;
(a) int ia[buf_size];
(b) int ia[4 * 7 - 14];
(c) int ia [txt_size()];
(d) char st[11] = "fundamental";

(a) 不合法,bu f_size 为普通无符号数,不是常量

(b) 合法,4 * 7 - 14 是一个常量表达式

(c) 不合法,txt_size 并不是常量表达式函数

(d) 不合法,fundamental的长度为11,因此 st 的容量应至少为12

3.28:下列数组中元素的值是什么?

string sa[10];
int ia[10];

int main() {
    string sa2[10];
    int ia2[10];
    cout << "f" << endl;
}

sa 中有10个元素,每一个的值都为空字符串

ia 中有10个元素,每一个的值都为0

sa2 中有10个元素,每一个的值都没

ia2 中有10个元素,每一个元素都为定义

3.29:相比于vector来说,数组有哪些缺点,请列举一些。

1. 数组长度不可变,没有 vector 灵活

2. 如果在函数内部定义了某种内置类型的数组,那么默认初始化会令数组含有为定义的值,但是 vector 不会出现此类现象,vector中的内置类型元素如果不给定初始值,则会根据具体类型进行值初始化

3.30:指出下面代码中的索引错误。

constexpr size_t array_size = 10;
int ia[array_size];
for (int ix = 1; ix <= array_size; ++ix) {
  ia[ix] = ix;
}

数组下标从 0 开始,并且等于数组中元素的个数减一

3.31:编写一段程序,定义一个含有10个int的数组,令每个元素的值就是其下标值。

int arr[10];
for (int i = 0; i < 10; ++i) {
  arr[i] = i;
}

3.32:将上一题刚刚创建的数组拷贝给另外一个数组。利用vector重写程序,实现类似的功能。

数组版

constexpr int size = 10;
int origin[size];
for (int i = 0; i < size; ++i) {
  origin[i] = i;
}
int target[size];
for (int i = 0; i < size; ++i) {
  target[i] = origin[i];
}

vector 版

constexpr int size = 10;
vector<int> origin(size);
for (int i = 0; i < size; ++i) {
  origin[i] = i;
}
vector<int> target(origin);

3.33:对于104页的程序来说,如果不初始化scores将发生什么?

不初始化 scores,则数组 scores 中的元素均为未定义,对未定义的变量进行 ++ 操作,会引发不可预知的错误

3.34:假定p1和p2指向同一个数组中的元素,则下面程序的功能是什么?什么情况下该程序是非法的?

p1 += p2 - p1;

作用:让 p1 指向 p2 所指的位置,当 p1 或 p2 中任何一个是 void* 类型时,编译报错

3.35:编写一段程序,利用指针将数组中的元素置为0。

int arr[] = {1, 2, 3, 4, 5, 6};
auto beg = begin(arr);
auto last = end(arr);
while (beg != last) {
  *beg = 0;
  beg++;
}

3.36:编写一段程序,比较两个数组是否相等。再写一段程序,比较两个vector对象是否相等。

数组比较大小

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

using namespace std;

template<typename T>
int compareArray(T *beg1, T *end1, T *beg2, T *end2) {

    auto size1 = end1 - beg1;
    auto size2 = end2 - beg2;

    if (size1 > size2) {
        return 1;
    } else if (size1 < size1) {
        return -1;
    }

    while (beg1 != end1 && beg2 != end2) {
        if (*beg1 > *beg2) {
            return 1;
        } else if (*beg1 < *beg2) {
            return -1;
        }
        beg1++;
        beg2++;
    }
    return 0;
}

int main() {
    int arr1[] = {1, 2, 2, 4, 5};
    int arr2[] = {1, 2, 3, 4};

    auto res = compareArray<int>(begin(arr1), end(arr1), begin(arr2), end(arr2));

    switch (res) {
        case 0:
            cout << "arr1 = arr2";
            break;
        case 1:
            cout << "arr1 > arr2";
            break;
        default:
            cout << "arr1 < arr2";
    }

    return 0;
}

vector 比较大小

template<typename T>
int compareVector(vector<T> &vec1, vector<T> &vec2) {
    auto sz1 = vec1.size();
    auto sz2 = vec2.size();
    if (sz1 > sz2) {
        return 1;
    } else if (sz1 < sz2) {
        return -1;
    }

    auto beg1 = vec1.cbegin();
    auto end1 = vec1.cend();
    auto beg2 = vec2.cbegin();
    auto end2 = vec2.cend();

    while (beg1 != end1 && beg2 != end2) {
        if (*beg1 > *beg2) {
            return 1;
        } else if (*beg1 < *beg2) {
            return -1;
        }
        beg1++;
        beg2++;
    }

    return 0;
}

int main() {

    vector<int> vec1{1, 2, 3, 4, 5};
    vector<int> vec2{1, 2, 3, 4, 5, 6};

    int res = compareVector<int>(vec1, vec2);

    switch (res) {
        case 1:
            cout << "vec1 > vec2";
            break;
        case 0:
            cout << "vec1 = vec2";
            break;
        default:
            cout << "vec1 < vec2";
    }

    return 0;
}

3.37:下面的程序是何含义,程序的输出结果是什么?

const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca;
while (*cp) {
  cout << *cp << endl;
  ++cp;
}

打印输出 C 风格字符串 cp 中的每个字符,直到遇到 \0 结束

3.38:在本节中我们提到,将两个指针相加不但是非法的,而且也没什么意义。请问为什么两个指针相加没什么意义?

3.39:编写一段程序,比较两个string对象。再编写一段程序,比较两个C风格字符串的内容。

比较 string

int compareString(const string &str1, const string &str2) {
    if (str1 > str2) {
        return 1;
    } else if (str1 < str2) {
        return -1;
    }
    return 0;
};

int main() {

    string s1 = "hello world";
    string s2 = "hello world";

    int res = compareString(s1, s2);
    switch (res) {
        case 1:
            cout << "s1 > s2";
            break;
        case -1:
            cout << "s1 < s2";
            break;
        default:
            cout << "s1 = s2";
    }

    return 0;
}

比较 c 风格字符串

int compareString(const char *str1, const char *str2) {
    auto sz1 = strlen(str1);
    auto sz2 = strlen(str2);
    auto len = sz1 > sz2 ? sz2 : sz1;

    for (int i = 0; i < len; ++i) {
        if (*str1 > *str2) {
            return 1;
        } else if (*str1 < *str2) {
            return -1;
        }
        str1++;
        str2++;
    }

    if (sz1 > sz2) {
        return 1;
    } else if (sz1 < sz2) {
        return -1;
    } else {
        return 0;
    }
};

int main() {

    char *str1 = "hello world";
    char *str2 = "hello world";

    int res = compareString(str1, str2);

    switch (res) {
        case 1:
            cout << "s1 > s2";
            break;
        case -1:
            cout << "s1 < s2";
            break;
        default:
            cout << "s1 = s2";
    }

    return 0;
}

3.40:编写一段程序,定义两个字符数组并用字符串字面值初始化它们;接着再定义一个字符数组存放前两个数组连接后的结果。使用strcpy和strcat把前两个数组的内容拷贝到第三个数组中。

int main() {

    const char str1[] = "hello";
    const char str2[] = "world";
    char str3[1024];

    strcpy(str3, str1);

    strcat(str3, " ");

    strcat(str3, str2);

    cout << str3 << endl;

    return 0;
}

3.41:编写一段程序,用整型数组初始化一个vector对象。

int arr[] = {1, 2, 3, 4, 5, 6};

vector<int> vec(cbegin(arr), cend(arr));

for (const auto &item : vec) {
  cout << item << ",";
}

// 1,2,3,4,5,6,

3.42:编写一段程序,将含有整数元素的vector对象拷贝给一个整型数组。

vector<int> vec = {1, 2, 3, 4, 5, 6};

int arr[1024];

memcpy(arr, &vec[0], vec.size() * (sizeof vec[0]));

for (int i = 0; i < vec.size(); ++i) {
  cout << arr[i] << ",";
}

3.43:编写3个不同版本的程序,令其均能输出ia的元素。版本1使用范围for语句管理迭代过程;版本2和版本3都使用普通的for语句,其中版本2要求用下标运算符,版本3要求用指针。此外,在所有3个版本的程序中都要直接写出数据类型,而不能使用类型别名、auto关键字或decltype关键字。

int arr[3][4] = {
  {1, 2,  3,  4},
  {5, 6,  7,  8},
  {9, 10, 11, 12}
};

for (const auto &row : arr) {
  for (const auto &col : row) {
    cout << col << ",";
  }
  cout << endl;
}

for (int i = 0; i < 3; ++i) {
  for (int j = 0; j < 4; ++j) {
    cout << arr[i][j] << ",";
  }
  cout << endl;
}

for (int (*p)[4] = arr; p != arr + 3; ++p) {
  for (int *q = *p; q < *p + 4; ++q) {
    cout << *q << ",";
  }
  cout << endl;
}

3.44:改写上一个练习中的程序,使用类型别名来代替循环控制变量的类型。

using init_array = int (*)[4];

for (init_array p = arr; p != arr + 3; ++p) {
  for (int *q = *p; q < *p + 4; ++q) {
    cout << *q << ",";
  }
  cout << endl;
}

3.45:再一次改写程序,这次使用auto关键字。

for (auto p = arr; p != arr + 3; ++p) {
  for (auto q = *p; q < *p + 4; ++q) {
    cout << *q << ",";
  }
  cout << endl;
}