3.1 命名空间的using声明
-
形式:using namespace::name;
3.2 标准库类型string
-
表示可变长的字符序列
- size()的返回值值类型是string::size_type,一个无符号的整数
- string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符两侧对象至少一个时string,如:
string s6 = s1 + ", " + “world”;//正确
string s7 = “hello” + “,” +s1; //错误 <cctype>
中定义了函数isalnum()、isdigit()…- 对string对象的每个元素做某个操作,如
for (auto &c : s) //基于范围的for语句 c = toupper(c); //改成大写
- 使用下标方式迭代:
for(decltype(s.size()) index=0;index!=s.size() &&!isspace(s[index]); ++index) s[index] = toupper(s[index]);
- string 对象上的操作
- 1.初始化对象的方式
- 2.所能执行的操作:函数名调用操作、<<、+等运算符操作
string s;cin>>s1>>s2;
: 会自动忽略开头的空白(\n \t)while(getline(cin,s));
:遇到换行符结束但不会存到s中,返回流参数
3.2 标准库类型vector
表示对象的集合,也叫容器,是一个类模板
#include <vector>
using std::vector
- 编译器根据模板创建类或函数的过程称为实例化
- 初始化如:
vector<T> v5{a,b,c,d,...} vector<T> v5={a,b,c,d,..} //注意这里不是圆括号
3.4 迭代器
- 有效的迭代器或者指向某个元素、或者指向容器中尾元素的下一位置。
- 有迭代器的类型同时拥有返回迭代器的成员,比如都有begin/cbegin()和end/cend()成员
- *iter:返回迭代器所指元素的引用
- iter->mem:解引用该元素,(*iter).mem
- …
- 迭代器类型:
vector<int>::iterator it; // it能读写vector<int>的元素 string::iterator it; // it能读写string对象中的元素 vector<int>::const_iterator it; // it能读不能写vector<int>的元素 string::const_iterator it; // it能读不能写string对象的元素
谨记:但凡是使用了迭代器的循环体,都不要向迭代器所属的容器中添加元素
- 迭代器的运算:iter±n表向前后移动n个元素,iter1-iter2表之间的距离(
difference_type
), - 例:
auto beg = text.begin(),end = text.end(); auto min = text.begin() + (end - beg)/2; while(mid != end && *mid != sought){ if(sought < *mid) end = mid; else beg = mid+1; mid = beg + (end-beg)/2; }
3.5 数组
- 复杂的数组声明
- int *ptrs[10]; //ptrs是含有10个整型指针的数组
- int &refs[10] = /* ? */ //错误,不存在引用的数组
- int (*pArray)[10] = &arr; //指向含有10个整数的数组,从内向外理解
- int (&arrRef)[10] = arr; //引用一个含10个整数的数组
- int *(&array)[10] = ptrs; //array是数组的引用,该数组含有10个指针
- 数组下标为定义在
<cstddef>
中的size_t
类型 - 数组与指针:
int ia[]={0,1,2}; auto ia2(ia); //ia2是一个整型指针,指向ia的第一个元素 decltype(ia) ia3 = {0,1,2};//ia3是数组 int *beg=begin(ia); //指向ia的首元素 int *last=end(ia); //指向ia尾元素的下一位置的指针
- 与旧代码的接口:
- 允许使用空字符结束的字符数组来初始化string对象或为string对象赋值
- const char *str=s.c_str();//不能保证返回的数组一直有效
- 数组初始化vector对象:
int int_arr[]={0,1,2,3,4,5}; vector<int> ivec(begin(int_arr),end(int_arr));
4.表达式
4.11 类型转换
- 隐式类型转换
- 表达式中,比int小的会提升为较大的整数类型
- 条件中,非布尔会转换成布尔类型
- 初始化过程中,初始值转换成变量类型
- 算术转换:
- 运算对象会转换成最宽的类型
- 整数值会被转换成浮点类型
- 整型提升
- char、uchar、short、ushort会转int,不能存则转unsigned int
- 较大的char(wchar_t、char16_t、char32_t)会转成int、uint、ulong、llong、ullong中最小的能容纳原类型值得一个
- 无符号类型得运算对象
- 先进行整型提升
- 无符号>=带符号(类型大小),对象转为无符号
- 无符号<带符号(类型大小),如 unsigned int a,long b,若a<=b,a转b,否则转a
- 显示转换:
- 形式:
cast-name<type>(expression)
- type是目标
- expression是要转换的值
- case-name是
①static_case、②dynamic_case、③const_cast、④reinterpret_cast
中的一种- ①.任何具有明确定义的类型转换
double s=static_case<double>(j)/i;
- ②.只能改变运算对象的底层const
const char *pc; char *p=const_cast<char*>(pc);//正确但通过p写行为未定义
- ③为运算对象的位模式提供较低层次上的重新解释
int *ip; char *pc=reinterpret_cast<char*>(ip);//很危险 string str(pc);//可能产生错误
- ①.任何具有明确定义的类型转换
- 形式:
4.12 运算符的优先级表
- p148页
5.语句
5.6 TRY语句块和异常处理
异常:存在运行时的反常行为,超出了函数的正常功能范围,如失去数据库连接、遇到意外输入。—设计系统最难的一部分
- throw表达式:用来表示遇到了无法处理的问题,我们说throw引发了异常
- try语句块:用它处理异常,以try语句块开始,多个catch子句结束。我们称为异常处理代码。
- 一套异常类:用于在throw和相关catch子句之间传递异常的具体信息
- 例:
#include <stdexcept> while(cin>>item1>>item2) { try{ if(item1.isbn() != item2.isbn()) throw runtime_error("Date must refer to same ISBN"); } catch (runtime_error err) { // 提醒用户两个ISBN必须一致,询问是否重新输入 cout<<err.what() <<"\nTry Again? Enter y or n"<<endl; char c; cin>>c; if(!cin || c == 'n') break; } }
- 标准异常:
- <exception>定义了最通用的异常类,只报告异常发生
- <stdexcept>定义了常用的异常类
- <new>定义了bad_alloc异常类型
- <type_info>定义了bad_cast异常类型
6.函数
- 组成:return value、function name、parameter、<body>
- 名字有作用域,对象有生命周期
6.2.6 含有可变形参的函数
-
initializer_list 形参
- 与vector不一样的是,initializer_list对象中的元素永远是常量值,无发改变
void error_msg(ErrCode e,initializer_list<string> il){ cout<<e.mesg()<<": "; for(auto beg=il.begin();beg!=il.end();++beg) cout<<*beg<<" "; cout<<endl; } //调用: error_msg(ErrCode(42),{"test1","test2"});
- 与vector不一样的是,initializer_list对象中的元素永远是常量值,无发改变
-
省略符形参
- 只能出现在形参列表的最后一个位置
- 你的C编译文档会教你怎么使用varargs
-
值是怎么返回的
- 返回的值用于初始化调用点的一个临时变量,该临时变量就是函数调用的结果
- 不要返回局部对象的引用或指针
-
列表初始化返回值
- C++ 11规定函数可以返回花括号包围的值的列表,如:
vector<string> process(){ return {"aa","bb"}; }
- C++ 11规定函数可以返回花括号包围的值的列表,如:
-
主函数main的返回值
- 没有语句隐式返回0
- <cstdlib>中定了两个预处理变量:
EXIT_FAILURE
、EXIT_SUCCESS
-
返回数组指针的函数:数组维度必须跟在函数名后,形参列表跟在函数名后且先于数组维度
Type (*function(parameter_list))[dimension] int (*func(int i))[10];
-
使用尾置返回类型
尾置返回类型跟在形参列表后,
->
开头,原来的位置替换位auto,如:auto func(int i) -> int(*)[10];
-
使用decltype,如:
int odd[]={1,3,5}; int even[]={0,2,4}; decltype(odd) *arrPtr(int i){ return (i%2)?&odd:&even; }
6.4 函数重载
同一作用域内几个函数名字相同但行参列表(类型或数量)不同,称为
重载函数
- 一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开
- 如果形参是指针或引用,可通过区分其指向的是常量还是非常量实现函数重载,如:
Record lookup(Account&); //用做Account的引用 Record lookup(const Account&); //新函数,作用于常量的引用