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

练习3.2

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

      读入一整行,使用方法:getline(cin , stringname)

#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{	
    string input;
    while (getline(cin , input))
    {
        cout << input << endl;
    }

    return 0;
}

      读入一个词

#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{	
    string input;
    while (cin >> input)
    {
        cout << input << endl;
    }

    return 0;
}

练习3.3

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

      对于string类的输入函数,它会自动忽略开头的空白(空格、制表符、换行等等),从第一个真正的字符开始直到下一个空白。

      对于getline()函数,它会保存字符串中的空白符,它读入数据,直到遇到换行符位置。

练习3.4

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

#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{
    string str1, str2;
    while (cin >> str1 >> str2) {
        if (str1 == str2)
            cout << "The two strings are equal." << endl;
        else
            cout << "The larger string is " << ((str1 > str2) ? str1 : str2);
    }

    return 0;
}
#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{
    string str1, str2;
    while (cin >> str1 >> str2) {
        if (str1.size() == str2.size())
            cout << "The two strings have the same length." << endl;
        else
            cout << "The longer string is "
                 << ((str1.size() > str2.size()) ? str1 : str2);
    }

    return 0;
}

练习3.5

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

#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{
    string largeStr;
    string str;
    while (cin >> str) {
        largeStr += str;
    }

    cout << "The concatenated string is " << largeStr << endl;

    return 0;
}
#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{
    string largeStr;
    string str;
    while (cin >> str) {
        if (largeStr.empty())
            largeStr += str;
        else
            largeStr += " " + str;
    }

    cout << "The concatenated string is " << largeStr << endl;

    return 0;
}

练习3.6

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

#include <iostream>
#include <string>

using std::string;
using std::cin;
using std::cout;
using std::endl;

int main()
{
    string str("a simple string");
    for (auto& c : str) c = 'X';
    cout << str << endl;

    return 0;
}

练习3.7

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

      没有不同,使用auto是让编译器确定c的类型,设为char后是char &c。

练习3.8

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

#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::endl;

int main()
{
    string str("a simple string");
    // 使用 while
    decltype(str.size()) i = 0;
    while (i < str.size()) {
        str[i] = 'X';
        ++i;
    }
    cout << str << endl;

    // 使用 for
    for (i = 0; i < str.size(); ++i) str[i] = 'Y';
    cout << str << endl;

    return 0;
}

练习3.9

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

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

      合法,定义后就占用一个字节,包含’\0’。

练习3.10

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

      ispunct(c):当c时标点符号时为真。

#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::cin;
using std::endl;

int main()
{
    string s;
    cout << "Enter a string of characters including punctuation." << endl;
    while (getline(cin, s)) {
        for (auto i : s)
        {
            if (!ispunct(i))
            {
                cout << i;
            }
            cout << endl;
        }
    }

    return 0;
}

练习3.11

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

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

      此处c是一个const char&,只可读变量不可赋值,所以当不改变c的值时,是合法的,否则就是不合法的。

练习3.12

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

      引用不可以成为vector的元素,因为其不是对象。

vector<vector<int>> ivec;             // 合法,创建了一个元素为vector的vector对象
vector<string> svec = ivec;           // 不合法,类型不一致
vector<string> svec(10, "null");      // 合法, 有10个string: "null".

练习3.13

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

vector<int> v1;                       // 个数:0,  没有值
vector<int> v2(10);                   // 个数:10, 值: 0
vector<int> v3(10, 42);               // 个数:10, 值: 42
vector<int> v4{10};                   // 个数:1,  值: 10
vector<int> v5{10, 42};               // 个数:2,  值: 10, 42
vector<string> v6{10};                // 个数:10, 值: ""
vector<string> v7{10, "hi"};          // 个数:10, 值: "hi"

练习3.14

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

#include <iostream>
#include <vector>

using std::cin;
using std::vector;

int main()
{
	vector<int> My_vector;
	int i;
	while (cin >> i)
	{
		My_vector.push_back(i);
	}

	return 0;
}

练习3.15

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

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

using std::cin;
using std::string;
using std::vector;

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

    return 0;
}

练习3.16

编写一段程序,把练习3.13中vector对象的容量和具体内容输出出来

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

using std::vector;
using std::string;
using std::cout;
using std::endl;

int main()
{
    vector<int> v1;
    cout << "{\n \"v1\":{\"size\":\"" << v1.size() << "\",\"value\":[";
    for (auto i : v1) cout << i << ",";
    if (!v1.empty()) cout << "\b";
    cout << "]}" << endl;

    vector<int> v2(10);
    cout << " \"v2\":{\"size\":\"" << v2.size() << "\",\"value\":[";
    for (auto i : v2) cout << i << ",";
    if (!v2.empty()) cout << "\b";
    cout << "]}" << endl;

    vector<int> v3(10, 42);
    cout << " \"v3\":{\"size\":\"" << v3.size() << "\",\"value\":[";
    for (auto i : v3) cout << i << ",";
    if (!v3.empty()) cout << "\b";
    cout << "]}" << endl;

    vector<int> v4{10};
    cout << " \"v4\":{\"size\":\"" << v4.size() << "\",\"value\":[";
    for (auto i : v4) cout << i << ",";
    if (!v4.empty()) cout << "\b";
    cout << "]}" << endl;

    vector<int> v5{10, 42};
    cout << " \"v5\":{\"size\":\"" << v5.size() << "\",\"value\":[";
    for (auto i : v5) cout << i << ",";
    if (!v5.empty()) cout << "\b";
    cout << "]}" << endl;

    vector<string> v6{10};
    cout << " \"v6\":{\"size\":\"" << v6.size() << "\",\"value\":[";
    for (auto i : v6)
        if (i.empty())
            cout << "(null)"
                 << ",";
        else
            cout << i << ",";
    if (!v6.empty()) cout << "\b";
    cout << "]}" << endl;

    vector<string> v7{10, "hi"};
    cout << " \"v7\":{\"size\":\"" << v7.size() << "\",\"value\":[";
    for (auto i : v7)
        if (i.empty())
            cout << "(null)"
                 << ",";
        else
            cout << i << ",";
    if (!v7.empty()) cout << "\b";
    cout << "]}\n}" << endl;

    return 0;
}

练习3.17

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

      int toupper(int c)函数可以转化小写为大写,toupper函数的参数是int类型,它的实现原型是这样的。


int toupper(int c)
{
	if ((c >= 'a') && (c <= 'z'))
		return c + ('A' - 'a');
	return c;
}
#include <iostream>
#include <vector>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;

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

    //这里在一个范围for循环中嵌套了一个范围for循环,是先用一个循环读vector中的一个单词,再用一个循环把这个单词中的字母从小写改成大写
    for (auto& str : vec)
        for (auto& c : str) c = toupper(c);

    // 使用decltype()获取vector的size()函数返回的类型
    for (decltype(vec.size()) i = 0; i != vec.size(); ++i) {
        if (i != 0 && i % 8 == 0) cout << endl;
        cout << vec[i] << " ";
    }
    cout << endl;

    return 0;
}

练习3.18

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

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

      不合法,空vector,不能给第一个元素赋值。

#include <vector>

using std::vector;

int main()
{
    vector<int> ivec{0};
    ivec[0] = 42;

    return 0;
}

练习3.19

如果想定义一个含有10个元素的vector对象,所有元素的值都是42,请例举三种不同的实现方法,哪种方式更好呢?

// 第一种
vector<int> ivec1(10, 42);
// 第二种
vector<int> ivec2{42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
// 第三种
vector<int> ivec3;
for (int i = 0; i != 10; ++i)
    ivec3.push_back(42);

练习3.20

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

      输出每对相邻整数的和。

#include <iostream>
#include <vector>

using std::vector;
using std::cout;
using std::endl;
using std::cin;

int main()
{
    vector<int> ivec;
    int i;
    while (cin >> i)
    {
        ivec.push_back(i);
    }

    // 首先判断输入的数是否够条件
    if (ivec.empty()) {
        cout << "至少输入一个整数。" << endl;
        return -1;
    }
    else if (ivec.size() == 1) {
        cout << ivec[0] << "只有一个元素,没有相邻的元素。";
    }
    else {
        for (decltype(ivec.size()) i = 0; i != ivec.size() - 1; ++i)
            cout << ivec[i] + ivec[i + 1] << " ";
    }

    return 0;
}

      输出第一个和最后一个元素的和 ,再输出第二个和倒数第二个的和,以此类推。

#include <iostream>
#include <vector>

using std::vector;
using std::cout;
using std::endl;
using std::cin;

int main()
{
    vector<int> ivec;
    int i;
    while (cin >> i)
    {
        ivec.push_back(i);
    }

    // 首先判断输入的数是否够条件
    if (ivec.empty()) {
        cout << "至少输入一个整数。" << endl;
        return -1;
    }
    else if (ivec.size() == 1) {
        cout << ivec[0] << "只有一个元素,没有相邻的元素。";
    }
    else {
        decltype(ivec.size()) size = ivec.size();
        if (size % 2 != 0)
            size = size / 2 + 1;
        else
            size /= 2;

        for (decltype(ivec.size()) i = 0; i != size; ++i)
            cout << ivec[i] + ivec[ivec.size() - i - 1] << " ";
        cout << endl;
    }

    return 0;
}

练习3.21

请使用迭代器重做3.3.3节的第一个练习。

      我们认定某个类型是迭代器当且仅当它支持一套操作,这套操作能使得我们能访问容器的元素或者从某个元素移动到另一个元素,vector中的begin()和end()函数,指向容器的第一个元素和最后一个元素的下一个位置。

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

using std::vector;
using std::string;
using std::cout;
using std::endl;

// 写一个函数把const vector<int>的引用作为函数参数,可以调用这个函数输出vector的大小和元素
void check(const vector<int>& vec)
{
    if (vec.empty())
        cout << "size: 0; no values." << endl;
    else {
        cout << "size: " << vec.size() << "; values:";
        for (auto it = vec.begin(); it != vec.end(); ++it) cout << *it << ",";
        cout << "\b." << endl;
    }
}

// 重载check函数把const vector<string>的引用作为参数
void check(const vector<string>& vec)
{
    if (vec.empty())
        cout << "size: 0; no values." << endl;
    else {
        cout << "size: " << vec.size() << "; values:";
        for (auto it = vec.begin(); it != vec.end(); ++it) {
            if (it->empty())
                cout << "(null)" << ",";
            else
                cout << *it << ",";
            }
        cout << "\b." << endl;
    }
}

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"};

    check(v1);
    check(v2);
    check(v3);
    check(v4);
    check(v5);
    check(v6);
    check(v7);

    return 0;
}

练习3.22

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

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

using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;

int main()
{
    vector<string> text;
    // 先用getline()读取text的第一段,然后存入vector中
    for (string line; getline(cin, line);) text.push_back(line);

    for (auto it = text.begin(); it != text.end() && !it->empty(); ++it) {
        for (auto& c : *it) c = toupper(c);
        cout << *it << endl;
    }

    return 0;
}

练习3.23

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

#include <vector>
#include <iostream>
#include <iterator>

using std::vector;
using std::iterator;
using std::cout;
using std::endl;

int main()
{
    vector<int> ivec(10, 1);
    for (auto it = ivec.begin(); it != ivec.end(); ++it) {
        *it *= 2;
    }
    for (auto value : ivec) cout << value << " ";
    cout << endl;

    return 0;
}

练习3.24

请使用迭代器重做3.3.3节的最后一个练习。

#include <iostream>
#include <vector>
#include <iterator>

using std::vector;
using std::cout;
using std::endl;
using std::cin;

int main()
{
    int i;
    vector<int> ivec;
    while (cin >> i) ivec.push_back(i);

    if (ivec.empty()) {
        cout << "至少输入一个整数。" << endl;
        return -1;
    }
    else if (ivec.size() == 1) {
        cout << *ivec.begin() << "只有一个元素,没有相邻的元素。";
    }

    for (auto it = ivec.begin(); it + 1 != ivec.end(); ++it)
        cout << *it + *(it + 1) << " ";
    cout << endl;

    for (auto beg = ivec.begin(), end = ivec.end() - 1; beg <= end; ++beg, --end)
        cout << *beg + *end << " ";
    cout << endl;

    return 0;
}

练习3.25

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

#include <vector>
#include <iterator>
#include <iostream>

using std::vector;
using std::cout;
using std::cin;
using std::endl;

int main()
{
    vector<unsigned> scores(11, 0);
    unsigned grade;
    while (cin >> grade)
        if (grade <= 100) ++(*(scores.begin() + grade / 10));

    for (auto score : scores) cout << score << " ";
    cout << endl;

    return 0;
}

练习3.26

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

      因为vector的迭代器没有定义两个迭代器之间的+运算符,迭代器之间只支持减法运算,两个迭代器相减的结果是他们之间的距离。迭代器加上一个整数值得到的新迭代器位置比原来相比向前移动了若干个元素。

练习3.27

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

unsigned buf_size = 1024;

int ia[buf_size];                   // 不合法, 维度必须是一个常量表达式,这里buf_size是一个变量
int ia[4 * 7 - 14];                 // 合法
int ia[txt_size()];                 // 不合法, 维度必须是一个常量表达式,txt_size()函数返回的也是一个变量
char st[11] = "fundamental";        // 不合法, 这个字符串的大小是12

练习3.28

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

string sa[10];
int ia[10];
int main() {
    string sa2[10];
    int ia2[10];
}

      如果定义变量时没有指定初值,则变量被默认初始化为默认值,默认值是什么由变量类型决定,同时定义变量的位置也会对此有影响。如果是内置类型的变量未被显示初始化,分为两种情况,一:定义于任何函数体之外的变量被初始化为0。二:定义在函数体内部的内置类型将不被初始化,变量的值是未定义的。对于非内置类型的类,每个类各自决定其初始化对象的方式,如string类规定:如果没有指定初值则生成一个空串。

      string不是内置类型,所以初始化sa,sa2置为空。

      int是内置类型,ia在函数体外,所以里面的元素都初始化为0,ia2在函数体内,所以ia中的值是未定义的。

练习3.29

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

  • 不能向数组增加元素。
  • vector可以更好地支持标准库std。

练习3.30

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

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

      ia的大小是10,所以值的索引应该是0~9。ix不能等于array_size。

练习3.31

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

#include <cstddef>
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    int ia[10];
    for (size_t i = 0; i < 10; ++i) {
        ia[i] = i;
    }

    for (auto i : ia) {
        cout << i << " ";
    }
    cout << endl;

    return 0;
}

练习3.32

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

#include <cstddef>
#include <iostream>
#include <vector>
#include <iterator>

using std::cout;
using std::endl;
using std::vector;
using std::iterator;

int main()
{
    // 使用数组
    int ia[10];
    for (size_t i = 0; i < 10; ++i) ia[i] = i;

    int ia2[10];
    for (size_t i = 0; i < 10; ++i) ia2[i] = ia[i];

    // 使用vector
    vector<int> iv(10);
    for (auto iter = iv.begin(); iter != iv.end(); ++iter)
        *iter = iter - iv.begin();

    vector<int> iv2(iv);

    for (auto i : iv2) cout << i << " ";
    cout << endl;

    return 0;
}

练习3.33

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

      如果没有初始化scores数组,数组未定义,值是未知的。

练习3.34

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

      p1和p2相减为其地址相减,因为p1和p2指向的是同一元素,地址相同,因此p1地址不变。所以只要p1和p2合法,这个语句就是合法的。

练习3.35

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

#include <iostream>
#include <iterator>

using std::begin;
using std::end;
using std::cout;
using std::endl;

int main()
{
    int arr[10];
    int* b = begin(arr);
    int* e = end(arr);

    for (int* i = b; i != e; ++i) *i = 0;

    for (auto i : arr) cout << i << " ";
    cout << endl;

    return 0;
}

练习3.36

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

#include <iostream>
#include <vector>
#include <iterator>

using std::begin;
using std::end;
using std::cout;
using std::endl;
using std::vector;

// pb指针指向数组的开头, pe指针指向数组的结尾
bool compare(int* const pb1, int* const pe1, int* const pb2, int* const pe2)
{
    if ((pe1 - pb1) != (pe2 - pb2))
        return false;
    else {
        for (int *i = pb1, *j = pb2; (i != pe1) && (j != pe2); ++i, ++j)
            if (*i != *j) return false;
    }

    return true;
}

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

    if (compare(begin(arr1), end(arr1), begin(arr2), end(arr2)))
        cout << "两个数组相等。" << endl;
    else
        cout << "两个数组是不相等的。" << endl;

    cout << "==========" << endl;

    vector<int> vec1 = {0, 1, 2};
    vector<int> vec2 = {0, 1, 2};

    if (vec1 == vec2)
        cout << "两个vectors是相等的。" << endl;
    else
        cout << "两个vectors是不相等的。" << endl;

    return 0;
}

练习3.37

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

      打印数组的所有元素。

练习3.38

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

      指针是对象的地址,两个指针相加是地址相加,得到的结果毫无意义。

练习3.39

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

      C++风格的字符串比较是字符串本身的比较

      C风格的字符串比较是字符串首地址的比较

#include <iostream>
#include <string>
#include <cstring>

using std::cout;
using std::endl;
using std::string;

int main()
{
    // 使用string.
    string s1("Mooophy");
    string s2("Pezy");

    if (s1 == s2)
        cout << "same string." << endl;
    else if (s1 > s2)
        cout << "Mooophy > Pezy" << endl;
    else
        cout << "Mooophy < Pezy" << endl;

    cout << "=========" << endl;
    // 使用C风格的字符串
    const char* cs1 = "Wangyue";
    const char* cs2 = "Pezy";

    auto result = strcmp(cs1, cs2);
    if (result == 0)
        cout << "same string." << endl;
    else if (result < 0)
        cout << "Wangyue < Pezy" << endl;
    else
        cout << "Wangyue > Pezy" << endl;

    return 0;
}

练习3.40

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

#include <cstring>
#include <iostream>

using std::cout;
using std::endl;

int main()
{
    const char cstr1[] = "Hello";
    const char cstr2[] = "world!";

    size_t new_size = strlen(cstr1) + strlen(" ") + strlen(cstr2) + 1;
    char* cstr3 = new char[new_size];

    strcpy(cstr3, cstr1);
    strcat(cstr3, " ");
    strcat(cstr3, cstr2);

    std::cout << cstr3 << std::endl;
    delete [] cstr3;
}

练习3.41

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

#include <iostream>
#include <vector>

using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;

int main()
{
    int int_arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    vector<int> ivec(begin(int_arr), end(int_arr));

    for (auto i : ivec) cout << i << " ";
    cout << endl;

    return 0;
}

练习3.42

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

#include <iostream>
#include <vector>

using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;

int main()
{
    vector<int> ivec{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int int_arr[10];

    for (int* i = begin(int_arr); i != end(int_arr); ++i)
        *i = ivec[i - begin(int_arr)];

    for (auto i : int_arr) cout << i << " ";
    cout << endl;

    return 0;
}

练习3.43

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

#include <iostream>

using std::cout;
using std::endl;

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

    // 用于管理迭代的范围
    for (const int(&p)[4] : ia)
        for (int q : p) cout << q << " ";
    cout << endl;

    // 使用下标的普通for循环
    for (size_t i = 0; i != 3; ++i)
        for (size_t j = 0; j != 4; ++j) cout << ia[i][j] << " ";
    cout << endl;

    // 使用指针
    for (int(*p)[4] = ia; p != ia + 3; ++p)
        for (int* q = *p; q != *p + 4; ++q) cout << *q << " ";
    cout << endl;

    return 0;
}

练习4.44

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

#include <iostream>

using std::cout;
using std::endl;

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

    // 使用类型别名
    using int_array = int[4];
    for (int_array& p : ia)
        for (int q : p) cout << q << " ";
    cout << endl;

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

    // 使用类型别名
    for (int_array* p = ia; p != ia + 3; ++p)
        for (int* q = *p; q != *p + 4; ++q) cout << *q << " ";
    cout << endl;

    return 0;
}

练习3.35

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

#include <iostream>

using std::cout;
using std::endl;

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

    for (auto& p : ia)
        for (int q : p) cout << q << " ";
    cout << endl;

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

    for (auto p = ia; p != ia + 3; ++p)
        for (int* q = *p; q != *p + 4; ++q) cout << *q << " ";
    cout << endl;

    return 0;
}

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值