C++ Primer(第5版) 课后答案 第三章

3.1:使用恰当的using声明重做1.4.1节和2.6.2节的练习。

通过加入如下声明

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

如下为练习1.9用using声明的改写代码

#include<iostream>

using std::cout;
using std::endl;
int main()
{
	int sum = 0;
	int val = 50;
	while (val <= 100)
	{
		sum += val;
		val++;
	}
	cout << "50-100的整数和为" << sum << endl;
	return 0;
}

其它练习的声明重做依此类推。

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

一次读入一整行:

#include<iostream>
#include<string>

using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	string line;
	//每次读入一整行,直至到达文件末尾
	//getline函数的参数是一个输入流和一个string对象,遇到换行符就结束读取操作并返回结果
	//换行符并不被存入到string对象中(被丢弃)
	while (getline(cin, line))
		cout << line << endl;
	return 0;
}
//输入 a b c
//输出 a b c

一次读入一个词:

#include<iostream>
#include<string>

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

int main()
{
	string word;
	while (cin >> word)
		cout << word << endl;
	return 0;
}
//输入 SY
//输出 SY
//输入 S Y
//输出 S
//     Y

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

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

getline函数从输入流中读入内容,直到遇到换行符为止(这里换行符其实也被读进来了),然后将所读内容存入到string对象中(不存换行符)。

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

#include<iostream>
#include<string>

using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	string str1, str2;
    //读入两个字符串
	getline(cin, str1);
	getline(cin, str2);

    //如果相等,输出:两个字符串相等。
	if (str1 == str2)
		cout << "两个字符串相等" << endl;

    //如果不相等,输出其中较大的字符串。
	else
		cout << ((str1 > str2) ? str1 : str2) << endl;
	return 0;
}
//输入 Hi 
//     Hi World
//输出 Hi World

#include<iostream>
#include<string>

using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	string str1, str2;
	getline(cin, str1);
	getline(cin, str2);
    
    //如果等长,输出:两个字符串等长
	if (str1.size() == str2.size())
		cout << "两个字符串等长" << endl;

    //如果不等长,输出长度较大的那个字符串
	else
		cout << ((str1.size() > str2.size()) ? str1 : str2) << endl;
	return 0;
}
//输入 abc
//     abcde
//输出 abcde

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

#include<iostream>
#include<string>

using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	string strc, str;

	//读入字符串str
	while (getline(cin, str))
	{
		//每次读入字符串str都与strc字符串相加,接着与空格相加
		strc = strc + str+" ";
	}
	cout << strc << endl;

	return 0;
}
//输入 a
//     bc
//     d e
//输出 a bc d e 

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

#include<iostream>

using std::string;
using std::cout;
using std::endl;
int main()
{
	//原字符串
	string str = "abcde";

	//用引用改变它绑定的字符
	for (auto& c : str)
		c = 'X';
	cout << str << endl;

	return 0;
}

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

设为char同样正确,因为每一个元素都是char类型,而且auto让编译器同样决定类型位char。

#include<iostream>

using std::string;
using std::cout;
using std::endl;
int main()
{
	//原字符串
	string str = "abcde";

	//用引用改变它绑定的字符
	for (char & c : str)
		c = 'X';
	cout << str << endl;

	return 0;
}

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

while循环:

#include<iostream>

using std::string;
using std::cout;
using std::endl;
int main()
{
	string str = "abcde";
	//i为下标,类型是str.size()的返回类型
	decltype(str.size()) i= 0;

	while (i < str.size())
	{
		str[i] = 'X';
		i++;
	}
	cout << str << endl;
	return 0;
}

for循环

#include<iostream>

using std::string;
using std::cout;
using std::endl;
int main()
{
	string str = "abcde";
	//i为下标,类型是str.size()的返回类型
	 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未初始化,因此第一个元素未知,使用下标访问会引发不可预知的结果。

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

#include<iostream>
#include<string>

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

int main()
{
	string str;
	getline(cin, str);
	for (string::size_type i = 0; i < str.size(); i++)
	{
		//str[i]不是标点符号为真
		if (!ispunct(str[i]))
			cout << str[i];
	}
	cout << endl;
	return 0;
}
//输入ab .e
//输出ab e

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

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

合法,c的类型是 const char&。

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

#include<string>
#include<vector>
using std::vector;
using std::string;

int main()
{
	vector<vector<int>>ivec;
	//创建了元素为vector的vector对象

	vector<string> svec = ivec;
	//错误,两个vector对象的类型不相同

	vector<string> svec(10, "null");
	//svec有10个值为“null”的元素
}

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

(a)vector<int> v1;                                        //是一个空vector

(b)vector<int> v2(10);                                 //包含10个值为0的元素

(c)vector<int> v3(10,42);                             //包含10个值为42的元素

(d)vector<int> v4{10};                                  //包含1个元素,值为10

(e)vector<int> v5{10,42};                             //包含2个元素,值为10和42

(f)vector<string> v6{10};                              //包含10个元素,空string对象

(g)vector<string> v7{10,"hi"};                       //包含10个值为“hi”的元素

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

#include<vector>
#include<iostream>
using std::vector;
using std::cin;

int main()
{
	int n;
	//空vector对象
	vector<int> v;
	//从标准输入读取数字,把它作为vector对象的元素存储
	while (cin >> n)
	{
		//把n放到v后面
		v.push_back(n);
	}
	return 0;
}

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

#include<string>
#include<vector>
#include<iostream>
using std::vector;
using std::string;
using std::cin;

int main()
{
	string w;
	//空vector对象
	vector<string> str;
	//从标准输入读取字符串,把它作为vector对象的元素存储
	while (cin >> w)
	{
		//把n放到v后面
		str.push_back(w);
	}
	return 0;
}

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

#include<iostream>
#include<vector>
#include<string>
using std::vector;
using std::string;
using std::cout;
int main()
{
	vector<int> v1;					// 
	vector<int> v2(10);			    //0000000000
	vector<int> v3(10, 42);			//42424242424242424242
	vector<int> v4{ 10 };			//10
	vector<int> v5{ 10,42 };		//1042
	vector<string> v6{ 10 };		// 
	vector<string> v7{ 10,"hi" };	//hihihihihihihihihihi

	
	for (auto i : v1)
		cout << i;
	return 0;
}

将范围for循环中的对象v1改为v1-v7即可。

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

#include<iostream>
#include<vector>
#include<string>
using std::vector;
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	string word;
	//存储word的容器
	vector<string> sp;
	//输入一组单词
	while (cin >> word)
	{
		//每一个输入的单词都先转化为大写再存储
		for (auto &c : word)
		{
			c = toupper(c);
		}
		sp.push_back(word);
	}
	//每输出一个单词,换一行
	for (auto i : sp)
		cout << i << endl;
}
//输入ab cde ff
//输出 AB
//     CDE
//     FF

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

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

不合法,ivec是一个空vector,不包含任何元素,不能通过下标去访问任何元素。

修改方式如下:

#include<vector>
using std::vector;
int main()
{
	vector<int> ivec;
	ivec.push_back(42);
}

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

#include<vector>
using std::vector;
int main()
{
	vector<int> ivec1{ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
	vector<int> ivec2(10, 42);
	vector<int> ivec3 = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
}

第二种更好,因为所有元素的值都相同。

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

#include<iostream>
#include<vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	int num;
	vector<int> sp;
	while (cin >> num)
	{
		sp.push_back(num);
	}
	int sum = 0;
	for (vector<int>::size_type i = 0; i < sp.size() - 1;i++)
	{
		sum = sp[i] + sp[i + 1];
		cout << sum << " ";
	}
    cout << endl;
	return 0;
}

改写:

#include<iostream>
#include<vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	int num;
	vector<int> sp;
	while (cin >> num)
	{
		sp.push_back(num);
	}
	int sum = 0;

    //left坐标初始为0,right坐标初始为sp的size-1,如果left比right小,就相加
    //每经过一次循环,left加一,right-1

	for (vector<int>::size_type left = 0, right=sp.size()-1;
         left<=right;     //元素如果是奇数个,中间的元素将与自己相加 
         left++,right--)
	{
		sum = sp[left] + sp[right];
		cout << sum << " ";
	}
	return 0;
}

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

#include<iostream>
#include<vector>
#include<string>
using std::vector;
using std::string;
using std::cout;
using std::endl;
int main()
{
	vector<int> v1;					// 
	vector<int> v2(10);			    //0000000000
	vector<int> v3(10, 42);			//42424242424242424242
	vector<int> v4{ 10 };			//10
	vector<int> v5{ 10,42 };		//1042
	vector<string> v6{ 10 };		// 
	vector<string> v7{ 10,"hi" };	//hihihihihihihihihihi


	for (auto it=v1.begin();it!=v1.end(); it++)
		cout <<*it;
	return 0;
}

同样将v1改为v1-v7即可。

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

#include<iostream>
#include<vector>
#include<string>
using std::vector;
using std::string;
using std::cout;
using std::cin;
using std::endl;
int main()
{
	string word;
	vector<string> text;
	while (cin >> word)
	{
		text.push_back(word);
	}
	//依次输出text的每一行直至遇到第一个空白行为止
	for (auto it = text.begin(); it != text.end() && !it->empty(); it++)
	{
		//还有另一种形式 (*it).begin()
		for (auto i = it->begin(); i != it->end(); i++)
		{
			*i = toupper(*i);
		}
		cout << *it << endl;;
	}
    return 0;
}

注意:如果不用it ->begin(),用 (*it).begin()时要将*it用括号括起来,否则编译器会试图访问it的名为empty的成员,一定出错!!!

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

#include<iostream>
#include<vector>
using std::vector;
using std::cout;
using std::endl;
int main()
{
	//创建一个有10个元素,初始值为1,2,3,4,5,6,7,8,9,10的vector对象
	vector<int> sp{1,2,3,4,5,6,7,8,9,10};

	for (auto it = sp.begin(); it != sp.end(); it++)
	{
		*it *=  2;
		cout << *it<<" ";
	}
	cout << endl;
	return 0;
}

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

#include<iostream>
#include<vector>
using std::vector;
using std::cout;
using std::cin;
using std::endl;
int main()
{
	int num;
	vector<int> sp;
	while (cin >> num)
	{
		sp.push_back(num);
	}

	//sp.end()是尾后迭代器,为了防止越界判断条件不能等于最后一个元素
	for (auto it = sp.begin(); it != sp.end()-1; it++)
	{
		int sum = 0;
		sum = *it + *(it + 1);
		cout << sum << " ";
	}
	return 0;
}

#include<iostream>
#include<vector>
using std::vector;
using std::cin;
using std::cout;
using std::endl;
int main()
{
	int num;
	vector<int> sp;
	while (cin >> num)
	{
		sp.push_back(num);
	}
	int sum = 0;
	for (auto left=sp.begin(),right=sp.end()-1;left<=right;left++,right--)
	{
		sum = *left + *right;
		cout << sum << " ";
	}
	cout << endl;
	return 0;
}

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

#include<iostream>
#include<vector>
using std::vector;
using std::cin;
using std::cout;
int main()
{
	vector<unsigned> scores(11, 0);
		unsigned grade;
	while (cin >> grade)
	{
		auto it = scores.begin();
		if (grade <= 100)
		{
			//将迭代器it加n的结果赋给迭代器
			it += grade / 10;
			//迭代器指示的元素加1
			*it += 1;
		}	
	}
	for (auto it = scores.begin(); it != scores.end(); it++)
		cout << *it<<" ";
	return 0;
}

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

//test必须是有序的
//beg和end表示我们搜索的范围
auto beg = text.begin(), end = text.end();
auto mid = text.begin() + (end - beg) / 2;  //初始状态下的中间点
//当还有元素尚未检查并且我们还没有找到sought时执行循环
while (mid != end && *mid != sought)
{
	if (sought < *mid)				//我们要找的元素还在前半部分吗?
		end = mid;					//如果是,调整搜索范围使得忽略掉后半部分
	else							//我们要找的元素在后半部分
		beg = mid + 1;				//在mid之后寻找
	mid = beg + (end - beg) / 2;    //新的中间点
}

不支持两个迭代器相加,如果用了mid=(beg+end)/2,编译器会报错

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

int main()
{
	unsigned buf_size = 1024;

	int ia[buf_size];
	//非法,buf_size不是常量表达式

	int ia[4 * 7 - 14]
	//合法

	int ia[txt_size()];
	//非法,txt_size()是一个返回值为int的函数,而不是常量

	char st[11] = "fundamental";
	//非法,没有空间可以存放空字符
	//fundamental后还有一个'\0'
}

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

#include<string>
using std::string;

string sa[10];			//10个string元素,值为空
int ia[10];				//10个int元素,值为0
int main()
{
	string sa2[10];		//10个string元素,值为空
	int ia2[10];		//内置类型在函数体内默认初始化值不确定
}

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

数组的大小是确定不变的,不能随意向数组中增加元素,因此损失了一些灵活性。


 

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

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

for的循环条件是 ix<=array_size,但array_size=10,因此循环到最后ix会增加到10,而这个ia数组的类型是int [10],下标的范围在0-9,因此错误。

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

int main()
{
	int arr[10];
	size_t i = 0;
	for (i = 0; i != 10;i++)
		arr[i] = i;
	return 0;
}

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

int main()
{
	int arr1[10],arr2[10];
	size_t i = 0;
	for (i = 0; i != 10;i++)
	{
		arr1[i] = i;
	}
	for (i = 0; i != 10; i++)
	{
		arr2[i] = arr1[i];
	}
	return 0;
}

vector:

#include<iostream>
#include<vector>
using std::vector;
using std::cout;
int main()
{
	vector<int> sp1(10),sp2(10);
	for (int i = 0; i != 10; i++)
	{
		sp1[i] = i;
	}
	sp2 = sp1; //vector对象可以直接拷贝
	for (auto it : sp2)
		cout << it << " ";
}

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

#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
	unsigned scores[11]={};
	unsigned grade;
	while (cin >> grade)
	{
		if (grade <= 100)
			++scores[grade / 10];
	}
	for (auto i : scores)
		cout << i << " ";
	cout << endl;
}

上面代码是全部初始化为0的

运行结果为

 下面代码是未初始化的

#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
	unsigned scores[11];
	unsigned grade;
	while (cin >> grade)
	{
		if (grade <= 100)
			++scores[grade / 10];
	}
	for (auto i : scores)
		cout << i << " ";
	cout << endl;
}

运行结果为

 因为如果scores数组在函数体内不初始化,它的默认初始值不确定。

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

p1 += p2 - p1;

我们用如下一段代码来看

#include<iostream>
using std::cout;
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p1 = arr;
	int* p2 = &arr[5];
	p1 += p2 - p1;
	cout << *p1;
}

//输出的结果是6

程序的功能是将p1向后移动p2-p1个位置。在上述例子中,p1开始指向arr的第一个元素arr[0],移动后指向了arr[5]。

我认为如果编译器通过即为合法的话,此程序应该没有情况是非法的。

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

#include<iostream>
#include<iterator>
using namespace std;
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* beg= begin(arr);
	int* last = end(arr);
	while (beg != last)
	{
		*beg = 0;
		beg++;
	}
	return 0;
}

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

#include<iostream>
using namespace std;
int main()
{
	int arr1[] = { 1,2,3,4,5,6 };
	int arr2[] = { 1,2,3,4,5 };
	
	int i = 0;
	if (sizeof(arr1) == sizeof(arr2))
	{
		for (i = 0; i < 5; i++)
		{
			if (arr1[i] != arr2[i])
			{
				cout << "两个数组不相等。" << endl;
				break;
			}
		}
		if (i == 5)
			cout << "两个数组相等。" << endl;
	}
	else
		cout << "两个数组不相等。" << endl;
	return 0;
}
#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int>sp1{ 1,2,3,4,5 }, sp2{ 1,2,3,4,5 };
	auto a1 = sp1.begin(), a2 = sp2.begin(), e1 = sp1.end(), e2 = sp2.end();
	if (sp1.size() == sp2.size())
	{
		while (a1 != e1 && a2 != e2)
		{
			if (*a1 != *a2)
			{
				cout << "两个vector对象不相等。" << endl;
				break;
			}
			a1++, a2++;
		}
		if (a1 == e1 && a2 == e2)
			cout << "两个vector对象相等。" << endl;
	}
	else
		cout << "两个vector对象不相等。" << endl;
	return 0;
}

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

#include<iostream>
using namespace std;
int main()
{
	const char ca[] = { 'h','e','l','l','o' };
	const char* cp = ca;
	while (*cp)
	{
		cout << *cp << endl;
		++cp;
	}
}

指针cp初始化为字符数组ca的第一个元素,进入while循环每次输出一个元素,输出后指针加1。

输出的结果并不确定,因为当hello这五个字母输出以后,循环并没有停止,会继续向后访问输出,直到遇到 '\0'才停止。

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

指针存放地址,两个地址相加得到的结果毫无意义,而且也非法。但是如果指向同一数组的两个指针相减,得到的是它们的距离,也就是它们之间的元素个数。

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

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s1 = "Code w";
	string s2 = "Coder w";
	if (s1 > s2)
		cout << "s1>s2" << endl;
	else if (s1 < s2)
		cout << "s1<s2" << endl;
	else
		cout << "s1==s2" << endl;
}
#include<iostream>
using namespace std;
int main()
{
	char str1[] = "Code w";
	char str2[] = "Coder w";
	int ret = strcmp(str1, str2);
	if (ret == 0)
		cout << "str1=str2" << endl;
	else if (ret < 0)
		cout << "str1<str2" << endl;
	else
		cout << "str1>str2" << endl;
}

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

#include<iostream>
using namespace std;
int main()
{
	char str1[] = "my ";
	char str2[] = "code";
	char str3[20];
	strcpy(str3, str1);
	strcat(str3, str2);

	char* cp = str3;
	while (*cp != '\0')
	{
		cout << *cp;
		cp++;
	}
	return 0;
}
//输出my code

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

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int arr[] = { 1,2,3,4,5 };
	vector<int> ivec(begin(arr), end(arr));
	for (auto i : ivec)
		cout << i << " ";
}

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

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int>ivec { 1, 2, 3, 4, 5 };
	int arr[10];
	for (int i = 0; i < ivec.size(); i++)
		arr[i] = ivec[i];
}

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

版本1:

#include<iostream>
using namespace std;
int main()
{
	int ia[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
	for (const int(&row)[4] : ia)
		for (const int col : row)
			cout << col << " ";
}

版本2:

#include<iostream>
using namespace std;
int main()
{
	int ia[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
	for (int row = 0; row != 3; row++)
		for (int col = 0; col != 4; col++)
			cout << ia[row][col] << " ";
}

版本3:

#include<iostream>
using namespace std;
int main()
{
	int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
	for (int(*p)[4] = ia; p != ia + 3; p++)
		for (int* q = *p; q != *p + 4; q++)
			cout << *q << " ";
}

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

#include<iostream>
using namespace std;
int main()
{
	using int_array = const int[4];
	int ia[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
	for (int_array(&row) : ia)
		for (const int col : row)
			cout << col << " ";
}
#include<iostream>
using namespace std;
int main()
{
	using int_array = int[4];
	int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
	for (int_array *p = ia; p != ia + 3; p++)
		for (int* q = *p; q != *p + 4; q++)
			cout << *q << " ";
}

如上为版本1和版本3的改写结果,版本2的类型并不复杂所以没有改写。

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

#include<iostream>
using namespace std;
int main()
{
	int ia[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
	for (const auto &row: ia)
		for (const auto col : row)
			cout << col << " ";
}
#include<iostream>
using namespace std;
int main()
{
	int ia[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11 };
	for (auto p = ia; p != ia + 3; p++)
		for (auto q = *p; q != *p + 4; q++)
			cout << *q << " ";
}

如上为版本1和版本3的改写结果,版本2同样无需改写。


版权声明:本文为Hhhh_Jy原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。