一 .异常
运行时异常是指程序在运行过程中,由于意外事件的产生导致程序异常终止。
eg:内存空间不足
打开的文件不存在
零除数
下标越界
方法一:判断返回值,比如当出现异常时候,我们让返回值为-1,那么我们在主函数里面就可以判断是否出现异常
方法二:使用全局标志变量
当函数中某处出现异常时,就将这个标志变量设置为特定的值,以便函数退出后根据该标志变量对异常进行处理。
方法三:使用exit和abort来终止程序执行
abort函数没有任何参数,而exit可指定一个状态参数
exit又称作完全终止,而函数abort什么都不做,仅仅中断程序
exit和abort是异常最直接的处理方式。
思想:让一个函数在发现自己无法处理的错误时抛出一个异常,然后它的调用着能够处理这个问题。
1.抛出异常用throw
throw(异常类型表达式)
2.捕获用try.....catch
try
{
//被侦测的语句........
}
catch(形参类型[形参名1])
{
异常处理语句.......
}
catch侦测到try里面的语句出现异常,那么catch会接受throw抛出的内容,然后进行下一步的处理
例子
#include<iostream>
using namespace std;
int div1(unsigned int a, unsigned int b)
{
if(b==0)
{
throw "被除数不能为0 ";
}
else
{
return (a/b);
}
}
int main()
{
int x,y;
cin>>x>>y;
try
{
div1(x,y);
}
catch(char* s)
{
cout<<s<<endl;
}
system("pause");
return 0;
}
/***********************STL介绍***********************************/
STL包含很多类实体,最重要的是容器,算法,和迭代器
第一部分:容器
容器分为顺序容器和关联容器
关联容器:
顺序容器之vector:
可以把vector作为灵活的数组,它自己掌握存储管理,在插入或者删除时vector能扩展和压缩其大小
vector<类型>对象名
vector的成员函数push_back()在vector的末尾插入参数的值,vector的前端是不能用来插入新元素
vector<int>v;
v.push_back(10);
v.push_back(12);
v.push_back(13);
for(int i=0;i<v.size();i++)
{
cout<<v[i]<<endl;
}
在容器的某个位置插入元素: insert()
v.insert(v.begin()+1,15) //在第二个元素前插入15
在容器的某个位置移去元素: erase()
顺序容器之list(链表):
list是双向链表,容器存储了第一个元素和最后一个元素的地址,因而可以迅速达到链表的两端
list的成员函数:
push_front()
pop_front()
sort() 排序 ,注意 list不支持STL的算法sort
remove() 删除和指定值相等的所有元素
unique() 删除所有和前一个元素相同的元素
merge() 合并两个链表,并清空被合并的链表
reverse() 颠倒链表
splice() 在指定位置前面插入另一个链表中的一个或多个元素,并在另一链表中删除被插入的元素
不可以用下标法访问list的成员
list<int>ilist;
ilist.push_back(30);
ilist.push_back(40);
ilist.push_front(20);
ilist.push_front(10);
int size=ilist.size();
for(int i=0;i<size;i++)
{
cout<<ilist.front()<<endl; //首先显示链表的头元素
ilist.pop_front(); //之后删除链表的头元素,这样下一次显示的头元素就是下一个元素值
}
list<int>list1,list2;
int arr1[]={40,30,50,60};
int arr2[]={15,20,30,25,40};
for(int j=0;j<4;j++)
{
list1.push_back(arr1[j]);
}
for(int j=0;j<5;j++)
{
list2.push_back(arr2[j]);
}
list1.reverse(); //现在list1里面的值分别是60,50,30,40
list1.merge(list2); //按照升序的方式合并起来
list1.unique(); //删除掉重复的值
int size=list1.size();
for(i=0;i<size;i++)
{
cout<<list1.front()<<endl;
list1.pop_front();
}
总结: 1.list是双向链表,双向链表中的每一个元素都有一个指向下一个元素的指针,也有一个指针指向上一个元素。
2.不能随机访问list中的元素,由于list的访问方法太慢,所以没有定义[ ]运算符;
3.当需要在链表中频繁的插入和删除数据,list最合适
顺序容器之deque():
deque有些方面向vector,而另外一些方面像list.它可以像vector一样使用[ ]运算符随机访问,也可以像list一样从首端和尾端开始访问
deque分配内存的方式为它可以存储一些不连续的区域上,vector通常占有一段连续的内存空间,如果太大,就移动到新的合适位置。
/*********************************************关联容器***************************************************************************/
关联容器
关联容器分为set和map;
set容器
set它用于存储数据并且能从一个数据集合中取出数据,它的每一个元素的值必须唯一,每一个元素的值不能直接被改变。
set一些重要的成员函数:begin(返回指向set头部的迭代器的地址),insert,find,erase,end(返回指向set尾部的迭代器的地址)等等
总结几点:
1 数据传入set容器中会自动排序;
2.set容器它的大小可以改变,根据关键字值来提高读取数据的能力;
3.set容器通常用来存储用户自定义的类,也可以用来存储简单元素,如字符串;
map容器
map存储一对对象,即键对象(key)和值对象(value),键对象用于查找过程的键,值对象包含附加数据
map<键类型,值类型>对象名
键-值关联:
map<string,string>mapAnimal;
mapAnimal["dog"]="a annimal";
map的成员函数,begin(),insert(),find(),erase(),end(),clear(),swap()
例子:
string name;
int pop;
string states[ ]={"BeiJing","SuZhou","ShangHai"};
int pops[]={1000,2000,3000};
map<string,int>mapStatus;
map<string,int>::iterator iter;
for(int j=0;j<3;j++)
{
name=states[j];
pop=pops[j];
mapStatus[name]=pop;
} //将states的数组,以及pops的数组映射到map容器中
for(iter=mapStatus.begin();iter!=mapStatus.end();iter++)
{
cout<<(*iter).first<<","<<(*iter).second<<endl;
}
cout<<"请输入城市名: ";
cin>>name;
pop=mapStatus[name];
cout<<"城市: "<<name<<"对应的人口数: "<<pop<<endl;
return 0;
第二部分 迭代器
迭代器类似于指针的实体,用来访问容器中的单个数据项
不同迭代器必须用于不容类型的容器
我们知道对一对一维数组,遍历所有数据可采用下标法;对于一个顺序容器list,遍历所有数据只能用front和pop_front();对于deque容器,遍历所有数据可以采用下标形式
因为不同的容器我们有不同的遍历方式,而iterator迭代器就厉害乐,对于不同容器都能够遍历其数据~~~~~~~~~~~~~~~
容器接受的迭代器类型:
list<int>iList;
int arr[]={2,4,6,8};
list<int>::iterator iter; //list型的迭代器,自动转换为双向迭代器。从上往下看默认,这点需要注意
for(iter=iList.begin();iter!=iList.end();iter++)
{
cout<<*iter<<endl;
}
第三部分 算法
我们这里以算法在数组中的使用举个例子,因为数组本身就属于一个容器,而且是顺序容器,且在我们开发中经常用到。
研究算法find(), count(),sort(),search(),merge在数组中的使用:
find()例子:
int arr[]={11,22,33,44,55,66};
int* ptr;
ptr=find(arr,arr+6,33)
cout<<"第一个33的位置为: "<<(ptr-arr)<<endl; //结果为2
count()例子:
int arr1[]={11,22,33,44,55,66,33,33};
int n= count(arr1,arr1+8,33);
cout<<"一共有33的个数: "<<n<<endl;
默认的话,sort()在数组中是按照升序排列:
sort(arr1,arr1+8);
for(int j=0; j<8; j++)
{
cout<<arr1[j]<<endl;
}
search(source,source+9, pattern, pattern+3) //其中pattern也是一个数组,就相当于在一个大数组中查询小数组成员
算法merge()在数组中的使用:
merge(src1,src1+5,src2,src2+3,dest)//将数组src1和数组src2合并到dest
STL算法主要由于以下头文件组成<algorithm>,<numeric>,<functional>
算法copy的使用:
int arr[10]={2,3,7,8,4,11,5,9,1,13};
vector<int>v(8);
copy(arr,arr+8, v.begin() ); //将数组中的成员复制到vector容器中去
输出流迭代器
ostream_iterator<int,char>out(cout," "); //将int型数据按照char通过cout输出(输出到屏幕上去),并且每个数据之间有空格
copy(arr,arr+10,out);将数组从头到位的数据赋值到 out中去