C++_Primer_Plus学习笔记-第三章

/*第三章 字符串、向量和数组*/
**内置类型由C++语言直接定义,体现计算机硬件本身具备的能力
**标准库定义更高级性质类型,未直接实现再计算机硬件中
3.1 命名空间的using声明
	1. 命名空间作用域操作符(::):编译器从操作符左侧名字所示作用域寻找右侧对象
	2. using声明完成之后可以直接访问命名空间的名字
		**using namespace :: name;
		**每个名字(成员)都需要独立声明
	3. 头文件不应包含using声明:头文件内容拷贝到所有引用的文件夹中,可能产生冲突
3.2 标准库类型string
	**标准库类型string表示可变长的字符序列,使用必须首先包含string头文件
	3.2.1 定义和初始化string对象
		**如何初始化类的对象是类本身决定的
		1. 初始化常用方式:
			**string s1;			//默认初始化
			**string s2=s1;			//s2同样效果
			**string s2(s1);
			**string s3= "hiya";	//s3同样效果
			**string s3("hiya");
			**string s4(10, 'c');	//n个字符组成的字符串
		2. 使用等号(=)初始化执行的是拷贝初始化(右侧初始值拷贝到创建对象中)
		   不使用等号执行直接初始化
		   **拷贝初始化创建临时对象用于拷贝
		   **拷贝初始化只能初始化一个值,多个值必须用列表初始化(直接初始化)
		3. 拷贝初始化阅读性较差
	3.2.2 string对象上的操作
		**类除了规定初始化对象方式外,还要规定对象能执行的操作
		1. string的操作
			**os<<s				将s写到输出流os中,返回os
			**is>>s				从输入流is中读取字符串写入s,字符串以空格分隔,返回is
			**getline(is,s)	从is中读取一行字符串赋值到s,返回is
			**s.empty() 		判断s是否为空
			**s.size()			返回s中字符个数,忽略结尾'\0'字符
			**s[]				返回s中第n个字符的引用
			**s1+s2				返回s1和s2连接后的结果
			**s1=s2				用s2副本代替s1中字符串
			**s1==s2			比较字符串是否完全一样,对大小写敏感
			**s1!=s2
			**<,<=,>,>=			利用字符字典中顺序进行比较,对小大写敏感(ASCII码表)
		2. 读写string对象
			**使用IO操作符读写string对象
			**执行读取输入流操作时自动忽略开头空白部分,遇到下一处空白截止
			**此类操作返回左侧运算对象为结果,因此多个输入输出可以连写
		3. 读取位置数量的string对象
		4. 使用getline()读取一整行
			**函数说明:getline(instream,&string);
			**函数从输入流获取内容直到遇到换行符为止(换行符也读取,但是存时舍去)
			**内容存入string对象,开始就是换行符则结果为空字符串
			**返回流参数
		5. empty()size()操作
			**empty()函数根据对象是否为空返回一个对应的布尔值
			**size()函数返回string对象长度
		6. string::size_type类型:string.size()返回值类型
			**标准库类型定义了配套类型,配套类型体现标准库类型与机器无关的特性
			**string::size_type是一个无符号类型的值,且足够存放任何string对象的大小
			**所有用于存放string类size函数返回值的变量,都应该是string::size_type类型
		7. string类定义了用于比较字符串的运算符,逐一比较字符并对大小写敏感
			**字符完全一致,较短对象小于较长
			**字符不一致,比较结果为对象中第一对相异字符比较的结果
		8. 两个string类型对象相加得到一个新对象,内容为把左侧运算对象与右侧对象串接
			**+)和(+=)运算符
		9. 标准库允许把字符字面值和字符串字面值转换成string对象,在需要时可用字面值代替
			**必须确保每个加法运算符两侧运算对象至少有一个string对象
			**string s5 = "hello" + ","	;		//错误,两个都是字符串字面值而不是string对象
			**string s7 = "hello" + "," + s2;	//错误,加法运算符两侧至少要有一个string对象
			**string s6 = s1 + "hello" + "world";
			//string temp = s1 + "hello";
			//string s6 = temp + "world";
	3.2.3 处理string对象中的字符
		**处理对象中字符关键在于:1.如何获取字符本身 2. 改变字符的特性
		**cctype头文件定义库函数处理字符串字符类问题
		**常用空函数:
		——————————————————————————————————————————————————————————————————————————————————
		**isalnum(int c);
		**isalpha(int c);
		**iscntrl(int c);	//为控制字符时为真
		**isdigit(int c);
		**isgraph(int c);	//非字符但可打印时为真
		**islower(int c);
		**isupper(int c);
		**isprint(int c);	//可打印字符为真(空格或可视)
		**ispunct(int c);	//为标点符号时为真
		**isspace(int c);
		**isxdigit(int c);	//为十六进制数字时为真
		**tolower(int c);
		**toupper(int c);
		———————————————————————————————————————————————————————————————————————————————————
		**建议使用C++版本的C标准库头文件
		**C语言标准库头文件形式:name.h
		**C++将此类头文件命名:cname(c表明为c语言头文件)
		**cname中定义的名字从属于命名空间std,.h头文件中则不然
		1. 使用基于范围的for循环,方便对对象每个字符完成操作
			**string str("some string");
			**for(auto c : str)	//基于范围,c变量仅拷贝序列元素
			**{
			**}
		2. 要改变字符对象的值,必须使用引用类型作为循环变量
			**for(auto &c : str);//c为引用,依次绑定到序列元素
			**指针??也可以进行处理
		3. 访问string对象单个字符的两种方式:
			**使用下标
			**使用迭代器
		4. 下标运算符([])接受参数为string::size_type类型值,表示序列对应位置
			**返回值为该位置上的引用
			**使用下标可以进行迭代
			**使用下标可以进行随机访问,通过计算直接获取地址
			**使用下标必须考虑地址范围,检查合法性
	3.3 标准库类型vector
		**容器,表示同类新对象的集合,每个对象有对应索引用于访问
		**使用必须包含头文件(vector)和命名空间声明
		**vector是一个类模板,编译器根据模板创建类或函数
		**需要指定模板实例化的类:模板名字+<信息>
		**引用不是对象,不存在包含引用的vector
		3.3.1 定义和初始化vector对象
			1. 最常用方式是先定义一个空vector,运行时获取到元素的值再逐一添加
			2. 列表初始化,初始元素值时只能使用花括号(初始化的第三种情况)
			3. 创建指定数量的元素,使用圆括号
			4. 值初始化:
				**只提供vector对象容纳的元素数量而略去初始值时会创建一个值初始化的元素初值
				**初值由元素类型决定
				**有些类必须明确显式初始化(默认初始化相关内容)
				**如果提供元素的初始量而没有设定初始值,只能使用直接初始化
			5. 圆括号表示提供的值用以构造vector对象,花括号表述列表初始化vector对象
		3.3.2 向vector对象中添加元素
			1. 直接初始化用于三种情况:
				**初始值已知且数量较少
				**初始值为另一vector副本
				**所有元素初始值一样
				**常见情况为vector元素对象数量、值未知
			2. 成员函数push_back()向vector对象尾部位置添加元素
			3. 范围for循环语句体内不应改变其所遍历序列的大小
		3.3.3 其他vector操作
			1. 不能用下标形式添加元素
			2. 只能对确知已存在的元素执行下标
	3.4 迭代器介绍
		**迭代器提供对对象的间接访问
		**对象是容器中的元素或者string对象中的字符
		3.4.1 使用迭代器
			1. 拥有迭代器的类型同时拥有返回迭代器的成员
				**begin成员函数负责返回指向第一个元素的迭代器
				**end成员函数返回指向容器尾元素下一位置(虚拟 off the end)
				**end常用于标记,没有实际意义
			2. 不在意迭代器准确的类型
			3. 迭代器运算符
				________________________________________________________________________
				** *iter			返回迭代器iter所指元素的引用
				** iter->mem		解引用iter并获取该元素mem成员,等价于(*iter).mem
				** ++iter			指向容器中的下一个元素,不能对尾迭代器进行操作
				** --iter
				** iter1 == iter2
				** iter1 != iter2
				________________________________________________________________________
				**通过解引用迭代器来获取它所指向元素
			4. 所有标准库函数迭代器都定义了(==)、(!=),但是大多数没有定义(<)运算符
				**使用!=进行判断保证在所有标准库提供的容器都有效(泛型编程)
			5. 拥有迭代器的标准库类型使用iterator和const iterator来表示迭代器的类型
				**vector<int>::iterator it;
				**string::const_iterator it2;
				**对象是常量,那么只能用const_iterator
			6. cbegin和cend成员函数:返回容器迭代器,返回值类型为const_iterator
			7. 箭头运算符(->):将解引用和成员访问结合
				**(*it).empty();
				**it->empty;
			8. 任何一种可能改变vector对象容量的操作,都会使该对象的迭代器失效
		3.4.2 迭代器运算
			1. 关系比较运算、额外运算符、算术运算
			2. 二分搜索
	3.5 数组
		**类似于vector的数据结构,性能与灵活性的权衡上又与vector有所不同
		**与vector的共同点:存放类型相同对象的容器,对象本身没有名字,需要通过所在位置访问
		**与vector的不同点:数组大小确定不变,不能随意向数组中增加元素
		**相较vector,性能较好,损失灵活性
		3.5.1 定义和初始化内置数组
			1. 数组是复合类型,定义形式:a[d]
				**a为名字,d为维度,维度必须是一个常量表达式
				**constexpr unsigned int sz = 42;	//常量表达式
				**unsigned cnt = 42;				//非常量表达式
			2. 默认初始化
			3. 必须指定类型,元素应为对象,不存在引用的数组
			4. 使用字符串字面值对字符数组初始化,自动添加代表字符串结束的空字符
			5. 数组不允许为其他数组拷贝和赋值
		3.5.2 访问数组元素
			**范围for语句和下标运算符进行访问
			1. 数组下标类型为size_t,与机器相关的无符号类型,包含头文件为cstddef(c标准:stddef.h)
		3.5.3 指针和数组
			1. 用到数组名字时,编译器自动将其替换为一个指向数组首元素的指针
				**一些情况下数组的操作实际为指针的操作
				**int ia[10]={0,1,2,3,4,5,6,7,8,9};
				**auto ia2 = ia;	//ia2是一个整形指针,指向ia第一个元素
				**decltype(ia) ia3 = {0,1,2,3,4,5,6,7,8,9};	//ia3是一个含有10个整型的数组,与auto不一样
			2. 指针也是迭代器
				**int arr[10];
				**获取首元素的指针:数组名字或者数组首元素地址
				**获取尾后指针:int *e = &arr[10];	//不存在的地址,不能用于计算操作
			3. 标准库函数begin和end
				**计算尾后指针极易出错,引入标准库函数
				**begin(array_name):返回指向array_neme首元素指针
				**end(array_name):返回指向array_neme尾后指针
			4. 指针运算
				**两个指针相减,返回两者之间距离,返回值类型为有符号类型ptrdiff_t,定义在头文件cstddef中
				**可以减去空指针
			5. 只要指针指向数组的元素,都可以执行下标运算
				**int *p = &ia[2];
				**int j = p[1];		//*(p-1)
				**int k = p(-2)		//*(p-2),ia[0]
			6. 内置下标运算符索引值为有符号值,vector、string等标准库为无符号值
		3.5.4 C风格字符串
			**C++支持C风格字符串,最好不要使用。使用不方便且极易引发程序漏洞
			1. 字符串字面值是一种通用结构的实例。这种结构即是C++由C继承而来的C风格字符串。
			   C风格字符串不是一种类型,而是为了表达和使用字符串而形成的一种约定俗成的写法。
			   **按此习惯书写的字符串存放在字符数组中并以空字符结束
		3.5.5 与旧代码的接口
			1. 混用string对象和c风格字符串
				**任何出现字符串字面值的地方都可以用“空字符串结束的字符数组”来代替
				**允许使用以空字符结束的字符数组初始化string对象或赋值
				**在string对象的加法运算中允许用以空字符结束的字符数组作为运算对象
				**反之不能成立,若需要一个C风格字符串,无法直接用string对象代替,可以使用成员函数.c_str()调用
			2. 使用数组初始化vector对象
				**vector对象不允许初始化数组,反之允许
				**只需要指明数组拷贝区域的首元素地址和尾后地址
				**int int_arr[]={0,1,2,3,4,5};
				**vector<int> ivec(begin(int_arr),end(int_arr));
			3. 建议尽可能使用标准库类型而非数组:指针常用于底层操作,易引发错误
				
	3.6 多维数组
		**严格来说,C++没有多维数组,多维数组其实是数组的数组
		**二维数组:(行)一个维族表示数组本身大小,(列)另一个表示元素(数组)的大小
		1. 多维数组初始化
		2. 使用范围for语句处理多维数组,除了最内层的循环外,其他所有循环控制变量都应该是引用类型
		3. 类型别名简化多维数组的指针
		4. 定义指向多维数组的指针时,不要忘了多维数组实际上是数组的数组
			**所以由多维数组名转换来的指针实际是指向第一个内层数组的指针!!!
/***************************************************/
#include <iostream>
#include <string>
#include <vector>
#include <cstddef>
using namespace std;

//vector<vector<int>> ivec;
/*	练习3.2:编写一段程序从标准输入中一次读取一整行,然后修改该程序使其一次读入一个词*/
int main3_2()
{
	string temp;
	string temp_single_word;

	cout<< "please send a whole line of strings:" <<endl;
	while(getline(cin,temp))
	{
		cout << temp << endl;
	}
	cin.clear();			//清除输入流状态,使可以继续调用输入流
							//notepad++使用文件结尾符调用cin.setstate(eofbit),无法清除
							//cout<<cin.setstate(eofbit)<<endl;
	cout<<cin.eof()<<endl;	//无法清除eofbit位,eof()返回值为0
							//在vs或者cmd控制台中可以正确编译运行
	cout << "please send a whole line of strings,and i will catch the first word:" <<endl;
	while(cin>>temp_single_word)
	{
		cout << temp_single_word <<endl;
	}
	return 0;
}

/*	练习3.3:请说明string类的输入运算符和getline函数分别是如何处理空白字符的*
string::cin自动忽略开头的空白字符,读取到字符串字面值后空白停止读取
getline():读取包括空白字符在内的所有内容直到遇到换行符
*/
/*	练习3.4:
	1.编写一段程序读入两个字符串,比较是否相等并输出结果,不相等输出较大字符串
	2.修改程序,比较字符串是否等长,不等长输出较长字符串
	*/
int main3_4()
{
	string first_s, second_s;

	cout << "please send the first string:" <<endl;
	cin >> first_s;
	fflush(stdin);	//清除输入流缓存(移植性较差)
	cout << "please send the second string:" <<endl;
	cin >>second_s;
	if(first_s > second_s)
		cout << first_s <<endl;
	else cout << second_s << endl;
	if(first_s.size() > second_s.size())
		cout << first_s <<endl;
	else cout << second_s << endl;

	return 0;
}

/*	练习3.5:
	1.编写一段程序,从标准输入中读入多个字符并将他们连接在一起,输出连接成的大字符
	2.修改程序,用空格把输入的多个字符串分隔开来
	*/
int main3_5()
{
	string first_s, second_s;

	cout << "please send the first string:" <<endl;
	cin >> first_s;
	fflush(stdin);	//清除输入流缓存(移植性较差)
	cout << "please send the second string:" <<endl;
	cin >>second_s;
	cout << first_s + second_s << endl;	//没有新建对象存值
	cout << first_s + " " +second_s <<endl;
}

/*	练习3.6:编写一段程序,使用for范围语句将字符串内所有字符用X代替*/
int main3_6()
{
	string str;

	cout << "please send the string:" <<endl;
	cin >> str;
	for(char &c:str)	//编译器必须支持 -std=c11++
	{
		c='X';
	}
	cout << str <<endl;
	return 0;
}
/*	练习3.7:题3.6,如果将训话控制变量类型设为char将发生什么?
	c类型设置为char类型,如果str中字符字面值为非char类型时会报错
	验证:效果与上一个程序一样
*/
/*	练习3.8:分别用while循环和传统for循环重写第一题程序*/
int main3_8()
{
	string str;

	cout << "please send the string:" <<endl;
	cin >> str;
	
	for(decltype(str.size()) index = 0; index != str.size() && !isspace(str[index]); ++index)	//编译器必须支持 -std=c11++
	{
		str[index] = 'X';
	}
	cout << "1:"<< str <<endl;
	
	decltype(str.size()) index = 0;
	while(!isspace(str[index]))
	{
		if(index==str.size())
		{
			index = 0;
			cout <<"2:"<< str <<endl;
			break;
		}
		else 
		{
			str[index] = 'a';
			index++;
		}
	}
	return 0;
}

/*	练习3.9:
	**string s;
	**cout << s[0] <<endl;
	**不合法,默认初始化s,没有经过合法性检测,直接调用s[0]将访问非法地址
*/
/* 	练习3.10:编写一段程序,读入一个包含标点符号的字符串,将标点符号去除后输出字符串剩余部分*/
int main3_10()
{
	string str;
	cout << "please send a string:" <<endl;
	cin >> str;
	for(auto &c : str)
	{
		if(ispunct(c))
			continue;
		else cout << c;
	}
	return 0;
}

/*	练习3.11:
	**const string s = "keep out!";	//顶层const
	**for(auto &c : s)					//c应该为const char类型的引用
	**{
	**									//访问合法,修改值不合法
	**}
	*/
/*	练习3.14:编写一段程序,用cin读入一组整数并把它们存入一个vector对象*/
int main3_14()
{
	vector<int> int_vector;
	int temp=0;
	
	while(cin >> temp)
	{
		int_vector.push_back(temp);
	}
	cout << int_vector[2] <<endl;
	return 0;
}

/*	练习3.15:修改3.14程序,读入字符串*/
int main3_15()
{
	vector<string> str_vector;
	string temp="null";
	
	while(cin >> temp)
	{
		str_vector.push_back(temp);
	}
	cout << str_vector[2] <<endl;
	return 0;
}

/*	练习3.16:把练习3.13中vector对象的容量和具体内容输出出来
				1.vector<int> v1;			2.vector<int> v2(10)
				3.vector<int> v3(10,42)		4.vector<int> v4{10}
				5.vector<int> v5{10,42}		6.vector<string> v6{10}
				7.vector<string> v7{10,"hi"}
				*/
int main3_16()
{
	vector<int> v1,v2(10),v3(10,42),v4{10},v5{10,42};
	vector<string> v6{10},v7{10,"hi"};
	//输出对象元素数量:
	cout << "v1_size: " << v1.size() << "	" << "v2_size: " << v2.size() << endl;
	cout << "v3_size: " << v3.size() << "	" << "v4_size: " << v4.size() << endl;
	cout << "v5_size: " << v5.size() << "	" << "v6_size: " << v6.size() << endl;
	cout << "v7_size: " << v7.size();
	cout << endl;
	//输出具体内容:
	if(v1.empty())
		cout << "v1 is empty" <<endl;
	else cout << "v1 has something" << endl;
	for(auto c:v2)
	{
		cout << "v2: " << c << "  ";
	}
	cout << endl;
	for(auto c:v3)
	{
		cout << "v3: " << c << "  ";
	}
	cout << endl;
	for(auto c:v4)
	{
		cout << "v4: " << c << "  ";
	}
	cout << endl;
	for(auto c:v5)	
	{
		cout << "v5: " << c << "  ";
	}
	cout << endl;
	for(auto c:v6)	
	{
		cout << "v6: " << c << "  ";
	}
	cout << endl;
	for(auto c:v7)	
	{
		cout << "v7: " << c << "  ";	
	}
	cout << endl;
	
	return 0;
}
/* 	练习3.17: 从cin中读入一组词,并把它们存入一个vector对象,然后设法把所有词都改为大写形式
	输出改变后的结果,每个词占一行
	*/
int main3_17()
{
	int i = 0;
	string temp;
	vector<string> str;
	cout << "please send some words: " <<endl;
	while( cin >> temp)
	{
		str.push_back(temp);
		for(auto &c:str[i])
		{
			c=toupper(c);
		}
		cout << str[i] <<endl;
		i++;
	}
	
}

/*	练习3.20:
	1.读入一组整数并把它们存入一个vector对象,将每对相邻整数的和输出出来
	2.改写,先输出第1个和最后一个元素的和,接着输出第二个和倒数第2个元素的和
	*/
int main3_20()
{
	int temp=0, sum = 0;
	vector<int> ivec;
	cout << "please send some ints: " <<endl;
	while(cin>>temp)
	{
		ivec.push_back(temp);
	}
	if(!ivec.size())
	{
		cout << "no data!" << endl;
		return 0;
	}
	//第一问
	for(decltype(ivec.size()) index = 0; index <= ivec.size()-2; index++)
	{
		sum = ivec[index] + ivec[++index];
		cout << sum << endl;
	}
	if(ivec.size()%2)
	{
		cout << ivec[ivec.size()-1]<<endl;
	}
	//第二问
	for(decltype(ivec.size()) index = 0; index < ivec.size()/2; index++)
	{
		cout << ivec[index] << "+" <<ivec[ivec.size()-(index+1)]
			<< "=" << ivec[index]+ivec[ivec.size()-(index+1)] << endl;
	}
	if(ivec.size()%2 == 1)
		cout << ivec[ivec.size()/2] << endl;	
}
/*	练习3.21:使用迭代器重做3.16
	没有做完,遇到合法性检测问题,vector(int)对象元素使用isspace()等函数测试
	没有按理想状态运行
	当然,可以不去检测是否是数字,这样可以完成任务
*/
int main3_21()
{
	vector<int> v1,v2(10),v3(10,42),v4{10},v5{10,42};
	vector<string> v6{10},v7{10,"hi"};
	vector<int> a{11,12};
	cout << "a=";
	for(auto it=a.begin();it!=a.end() && isalnum(*it);++it)
		cout << *it << "	";
	cout << endl;
	
	cout << "v1: ";
	for(auto it = v1.cbegin(); it != v1.cend() && !isspace(*it); ++it)
	{
		cout << *it << "  ";
	}
	cout << endl;
	
	cout << "v2: ";
	for(auto it = v2.cbegin(); it != v2.cend() && isalnum(*it); ++it)
	{
		cout << *it << "  ";
	}
	cout << endl;
	
	cout << "v3: ";
	for(auto it = v3.cbegin(); it != v3.cend() && !isspace(*it); ++it)
	{
		cout << *it << "  ";
	}
	cout << endl;
	
	cout << "v4: ";
	for(auto it = v4.cbegin(); it != v4.cend()&&!isspace(*it); ++it)
	{
		cout << *it << "  ";
	}
	cout << endl;
	
	cout << "v5: ";
	for(auto it = v5.cbegin(); it != v5.cend()&&!isspace(*it); ++it)
	{
		cout << *it << "  ";
	}
	cout << endl;
	cout << "v5: ";
	for(auto c:v5)	
	{
		cout<< c << "  ";
	}
}
/**/
/*	练习题3.22:修改之前那个输出text第一段的程序,首先将text的第一段全部改成大写形式再输出它*/
int main3_22()
{
	string temp;
	vector<string> svec;
	cout << "please send the text(end with ^z):"<<endl;
	while(getline(cin,temp))
	{
		svec.push_back(temp);
	}
	if(svec.cbegin() == svec.cend())
	{
		cout << "no data!" <<endl;
		return -1;
	}
	for(auto it = svec.begin(); it!=svec.end()&&!it->empty();++it)
	{
		cout<<*it<<endl;
	}
	for(auto it = svec.begin(); it!=svec.end()&&!it->empty();++it)
	{
		for(auto it2 = (*it).begin(); it2 != (*it).end();++it2)
		{
			*it2=toupper(*it2);
		}
		cout << *it << endl;
	}
	//cout << svec[1] <<endl;
	return 0;
}
/*	练习题3.23:编写一段程序,创建含有10个整数的vector对象,使用迭代器将所有元素的值都翻倍输出*/
int main3_23()
{
	vector<int>a{1,2,3,4,5,6,7,8,9,10};
	cout << "vector对象内元素:";
	for(auto it = a.cbegin(); it != a.cend(); ++it)
		cout << *it  << "    ";
	cout << endl;
	cout << "数据进行处理:";
	for(auto it = a.begin(); it != a.end(); ++it)
	{
		*it = *it * 2;
		cout << *it << "    ";
	}
	cout << endl;
	return 0;
}
/*	练习题3.31:定义一个含有10个int类型的数组,另每一个元素的值为当前下标值*/
int main3_31()
{
	constexpr size_t array_size=10;
	int a[array_size];
	for(size_t index=0;index != array_size;index++)
	{
		a[index]=index;
		cout << a[index] << endl;
	}
}
/*	练习题3.32:
	1. 将上一题创建的数组拷贝给另外一个数组
	2. 使用vector实现类似的功能
	*/
int main3_32()
{
	constexpr size_t array_size=10;
	int a[array_size];
	int b[array_size];
	for(size_t index=0;index != array_size;index++)
	{
		a[index]=index;
		cout << a[index] << endl;
	}
	for(size_t index=0;index != array_size;index++)
	{
		b[index]=a[index];
		cout << b[index] << endl;
	}
	
	vector<int> ivec1,ivec2;
	int temp;
	cout << "please send me some ints:"<<endl;
	while(cin>>temp)
	{
		ivec1.push_back(temp);
	}
	ivec2 = ivec1;
	for(auto index = ivec1.begin(); index != ivec1.end(); ++index)
	{
		cout << *index << "	" << endl;
	}
	for(auto index = ivec2.begin(); index != ivec2.end(); ++index)
	{
		cout << *index << "	" << endl;
	}
}
/* 	练习题3_33:不初始化scores会发生什么*/
/*	在这个g++编译器上未定义,没有执行默认初始化,但是在vs上测试时完成默认初始化都为0
	----是否在函数基础上,scores并非全局作用域引发的*/
int main3_33()
{
	unsigned scores[11];
	unsigned grades;
	for(size_t i = 0; i != 11; ++i)
	{
		cout << scores[i] << endl;
	}
	while(cin >> grades)
	{
		if(grades <= 100)
		{
			++scores[grades/10];
		}
	}
	for(size_t i = 0; i != 11; ++i)
	{
		cout << scores[i] << endl;
	}
}
/*	练习题3.35:利用指针将数组内元素置为0*/
int main3_35()
{
	int ia[10];
	// int *p1 = begin(ia);
	// int *p2 = end(ia);
	for(int *p1 = begin(ia),*p2 = end(ia);p1!=p2;++p1)
	{
		*p1 = 0;
		cout << *p1 << endl;
	}
	return 0;
}
/*	练习题3.36:编写一段程序,判断两个数组是否相等。再编写一段程序,判断vector对象是否相等*/
//vector比较直接用v1 == v2
int main3_36()
{
	const int array_size=6;
	int ia1[array_size];
	int ia2[array_size];
	size_t ix;
	
	cout<<"enter "<<array_size<<" numbers for array1"<<endl;
	for(ix=0;ix != array_size;++ix)
		cin>>ia1[ix];
	cout<<"enter"<<array_size<<" numbers for array2"<<endl;
	for(ix=0;ix != array_size;++ix)
		cin>>ia2[ix];
	for(ix=0;ix != array_size;++ix)
	{
		if(ia1[ix] != ia2[ix])
		{
			cout<<"array1 is not equal to array 2"<<endl;
			cout << ia2[0];
			return 0;
		}
	}
	cout<<"array1 is equal to array2"<<endl;
	return 0;
}
/*	练习题3.37:程序输出结果是什么*/
int main3_37()
{
	const char ca[] = {'h', 'e', 'l', 'l', 'o'};
	const char *cp = ca;
	while(*cp)
	{
		cout << *cp << endl;
		++cp;
	}
	return 0;
}
/*	练习题3.38:
	指针相加,得到的是一个无意义的内存地址,甚至有可能缓冲区溢出,而指针相减得到的则是两者之间的距离,是有意义的*/ 
/*	练习题3.42:编写一段程序,将含有整数元素的vector对象拷贝给一个整型数组*/
int main3_42()
{
	vector<int> ivec{0,1,2,3,4,5};
	vector<int> ivec2{6,7,8,9,10,11};
	int a[6];
	int index = 0;
	for(auto it = ivec.begin(); it != ivec.end(); ++it, ++index)
	{
		a[index] = *it;
	}
	index = 0;
	for(auto c : a)
	{
		cout << c << "	";
	}
	cout << endl;
	
	for(size_t i= 0; i != 6; ++i)
	{
		a[i] = ivec2[i];
	}
	for(auto c : a)
	{
		cout << c << "	";
	}
	cout << endl;
}
/*	练习题3.43:编写不同版本程序3个,均能输出ia元素
	1. 使用范围for语句管理迭代过程
	2. for语句,用下标运算符
	3. 要求用指针
	都要直接写出数据类型
	*/
int main3_43()
{
	int ia[3][4];
	size_t i = 0;
	using pp = int[4];
	//为ia赋值
	for(auto &row : ia)
	{
		for(auto &col : row)
		{
			col = i;
			i++;
		}
	}
	//	1. 使用范围for语句管理迭代过程
	for(int (&row)[4] : ia)
	{
		for(int &col : row)
		{
			cout << col << "	";
		}
		cout << endl;
	}
	//	2. for语句,用下标运算符
	for(size_t i = 0; i != 3; ++i)
	{
		for(size_t j = 0; j != 4; ++j)
		{
			cout << ia[i][j] << "	";
		}
		cout << endl;
	}
	//	3. for语句,使用指针
	for(int (*p)[4] = ia; p != ia + 3; ++p)
	{
		for(int *p2 = *p; p2 != *p + 4; ++p2)
		{
			cout << *p2 << "	";
		}
		cout << endl;
	}
	
	return 0;
}
	
int main()
{
	main3_43();
}
/****************************************************************************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值