C++篇---开篇(4)

一 .异常

运行时异常是指程序在运行过程中,由于意外事件的产生导致程序异常终止。

eg:内存空间不足

    打开的文件不存在

    零除数

    下标越界

方法一:判断返回值,比如当出现异常时候,我们让返回值为-1,那么我们在主函数里面就可以判断是否出现异常

方法二:使用全局标志变量

当函数中某处出现异常时,就将这个标志变量设置为特定的值,以便函数退出后根据该标志变量对异常进行处理。

方法三:使用exit和abort来终止程序执行

abort函数没有任何参数,而exit可指定一个状态参数

exit又称作完全终止,而函数abort什么都不做,仅仅中断程序

exit和abort是异常最直接的处理方式。

《C++篇---开篇(4)》

思想:让一个函数在发现自己无法处理的错误时抛出一个异常,然后它的调用着能够处理这个问题。

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包含很多类实体,最重要的是容器,算法,和迭代器

《C++篇---开篇(4)》

第一部分:容器

容器分为顺序容器和关联容器

《C++篇---开篇(4)》

关联容器:

《C++篇---开篇(4)》

顺序容器之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是双向链表,容器存储了第一个元素和最后一个元素的地址,因而可以迅速达到链表的两端

《C++篇---开篇(4)》

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;


第二部分  迭代器

迭代器类似于指针的实体,用来访问容器中的单个数据项

不同迭代器必须用于不容类型的容器

《C++篇---开篇(4)》

我们知道对一对一维数组,遍历所有数据可采用下标法;对于一个顺序容器list,遍历所有数据只能用front和pop_front();对于deque容器,遍历所有数据可以采用下标形式

因为不同的容器我们有不同的遍历方式,而iterator迭代器就厉害乐,对于不同容器都能够遍历其数据~~~~~~~~~~~~~~~

容器接受的迭代器类型:

《C++篇---开篇(4)》

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中去



点赞