第一章 C++编程基础
1.初始化两种方式:int a=10;int a(10);第一种使用等于是继承自C语言的风格。第二种出现的原因是因为的变量可能初始化值有多个,例如complex。
2.定义vector指针:vector<int>*pv=&vec1;定义vector指针数组:vector<int>*pv[2]={&vec1,&vec2};
3.产生随机数可以使用C语言中的srand()和rand()。其中,前者接收一个int参数作为种子,然后srand函数的结果对rand进行初始化,产生不同的随机数。srand常用的参数有时间函数time(0)等。
4.文件操作。头文件fstream。写文件:ostream ofile("filename.txt");读取文件:istreamifile("filename.txt");读写文件有很多不同的模式,例如同时读写等。
第二章 面向过程的编程风格
1.费波纳切数列非递归实现(第pos个元素):
int elem=1;
int n1=1,n2=1;
//第一第二位置返回1
for(int i=3;i<=pos;i++)
{
elem=n1+n2;
n2=n1;n1=elem;
}
2.引用作为函数参数时,对象本身不会复制,复制的是对象的地址。这样能够对对象直接操作并节省复制对象的开销。而且,引用由于必须初始化,因此不用做指针的是否为空检查。
3.内置数据类型全局自动初始化为0,非全局需要用户初始化。
4.默认参数值:void display(int a,int b=0){};默认规则:
a.解析操作从右自左。因此,定义默认值参数右边的参数必须全部定义参数值。
b.函数声明的头文件中需要写明默认值,实现文件中不需要写明默认值。
5.关于函数的返回值:如果返回的是函数中局部变量的指针、引用,该函数都无法正常返回自己想要的结果;如果返回的是函数中局部变量的值,返回时局部变量会进行对象复制,虽然浪费空间,但是函数调用结束后,返回的对象仍然存在。例如三个函数:vector<int>* get()、vector<int>& get()、和vec<int> get(),三个get函数中返回自定义的局部vector。
6.局部静态变量在函数的调用中,其值始终存在。
7.inline定义的函数,表示编译器在每个函数的调用点上将函数展开。inline能够将不同的子函数连接起来形成以个统一的函数。
8.函数的重载根据的是参数列表的不同(参数类型,参数个数、顺序等),函数返回值的不同不能构成函数的重载。
9.可以功能相似的函数定义为模板函数,由用户定义数据类型,函数实现特定数据类型的功能。模板函数格式如下:
template<typename/class elemType>
void function(vector<elemType> vec)
{
elemType elem =vec[0];
}
10.如果函数具备多种实现方式,使用重载,每份提供的是相同的服务;如果希望程序代码主体不变,仅仅改变的是数据类型,可以使用函模板函数。此外,模板函数也可以重载。
11.函数指针:
typedef void(*pf)();
void sayHello()
{
cout<<"Hello!"<<endl;
}
int main()
{
pfpf1;
pf1= sayHello;
(*pf1)();
return0;
}
第三章 泛型编程风格
1.STL(标准模板库)包括container(容器)和generic algorithm(泛型算法)。
2.容器包括顺序容器(如vector、list等)和关联容器(如map、set等)。
3.map是key/value组合,set只有key。map和set的key不能重复。
4.泛型算法通过模板函数实现。
5.C++中指针如果作为函数参数或者函数返回值,只有数组的第一个值会被传递。
6.vector的本质是内存连续的数组,list的本质是双向链表。因为vector和list的实现方式不同,因此泛型函数find不能通过指针进行参数传递(vector合适,但是list不合适)。因此需要加入抽象层,提供vector和list的起始元素指针。这就是iterator的由来。
7.所有容器的共通操作:
= =、! =返回true或者false;
=容器复制;
Empty()返回true或者false;
Size()返回容器元素个数;
Clear()删除所有元素;
Begin()返回iterator,指向第一个元素;
End()返回iterator,返回最后一个元素;
Insert()插入元素;
Erase()删除一定范围内的元素。
8.顺序容器:
Vector:数组实现,连续内存区域,读取效率高,删除、插入(非尾部)效率低。
List:双链表实现,非连续内存区域,插入删除效率高,读取效率低。
Deque:连续内存区域,对于最前段的插入、删除效率高,尾部效率也高(同vector)。
9.使用顺序容器(vector、list、deque)
添加、删除尾部元素:push_back()、pop_back()
添加、删除首部元素(除vector):push_front()、pop_front()
获取首尾元素:front()、back()
插入元素:insert()
删除元素:erase()
10.使用泛型算法:需要包含algorithm头文件
泛型搜索算法:
find():无序集合搜索,搜索范围[first,last])。存在返回该元素的iterator,不存在返回指向last的iterator。对象的比较,find可以通过重载等号运算符==进行;find_if用于用户自定义比较规则。
binary_search():有序集合搜索。存在返回true,不存在返回false。效率较find()高。
count():返回数值相符合元素的数目。
search():查找是否存在子序列,如查找[1,3,5]中是否含有[3,5]等。存在返回子序列的iterator,不存在返回指向容器尾部的iterator。
获取最大值:
max_element():传入一对iterator,返回该范围内的最大值。
复制:
copy():接受三个iterator,前两个标示处带赋值元素的范围,第三个标示处复制目的地的iterator,要确保目的iterator有足够的空间存储元素。
11.设计泛型算法:例如,找出vector中小于10的数字。为了扩展函数的通用性,设计函数如下:vector<int>filter(const vector<int> &vec, int value, bool (*pred)(int,int));其中,函数指针用于指定不同元素之间的关系比较,例如大于、小于等,采用函数指针实现。
12.函数对象(Fuction Object):某种class的实例对象,该class对函数调用运算符做了重载操作,使函数对象可以当成一般函数来使用。
算数运算符(6个):
plus<type>/minus<type>/negate<type>/multiplies<type>/divides<type>/modules<type>
关系运算符(6个):
less<type>/less_equal<type>/greater<type>/greater_equal<type>/equal_to<type>/not_equal_to<type>
逻辑运算符(3个):
logical_and<type>/logical_or<type>/logical_not<type>分别对应&&、||和!。
使用方法:需要包含functional头文件。例如sort中使用:sort(vec.begin(),bec.end(),greater<int>());greater<int>()会产生一个未命名的模板类对象,传递给sort算法。
13.函数对象适配器(Fuction object adapter)可以对函数对象进行修改操作。Binder adapter(绑定适配器)可以将函数对象的参数绑定到特定值,使二元函数对象变为一元函数对象。绑定适配器包括:bind1st:将指定值绑定到第一个操作数;bind2nd:将指定值绑定到第二个操作数。例如:bind2nd(less<int> <, int val)将val绑定在less<int>的第二个参数上,使less将每个元素同val对比。
14.使用map:map<string,int>words;words[“conan”] = 1;如果调用的words[“lan”]中lan不在words的key中,map会自动添加lan为key并且赋默认value值为0。Map的遍历:
map<string,int>::iterator it =words.begin();
for(;it!=words.end();++it)
{
Cout<<”key:”<<it->first<<”value”<<it->second<<endl;
}
Map中元素的查询可以利用map提供的find函数(注意不是泛型函数find):words.find(“conan”);
15.使用set:同map中的key类似,可以使用set提供的count函数超找set中是否含有某值。
16.使用iterator inserter(需要头文件iterator):为了防止容器实现时需要传入的是固定大小(这样需要考虑赋值时目标空间是否足够等因素),因此insertion adapter出现,用于避免容器的赋值运算符。Insertion adapter包括:
back_inserter():用容器的push_back()取代赋值运算符。
例如:unique_copy(ivec.begin(),ivec.end(),back_inserter(res_vec));
inserter():用insert()代替赋值运算符。
front_inserter():用push_front()代替赋值赋值运算。
17.使用iostream iterator:iostream iterator支持单一类型的元素的读取和写入。