C/C++总结


C语言参考学习网址:http://c.biancheng.net/cpp/u/jiaocheng/
C++参考学习网址:http://c.biancheng.net/cpp/biancheng/cpp/rumen/

一,数据

1.变量

2.数组

3.指针

4.结构体

5.C++容器

5.1. victor容器(类似于数组)

用法:

#include<vector>
//1.初始化
vector<int> vec;        //声明一个int型向量
vector<int> vec(5);     //声明一个初始大小为5的int向量
vector<int> vec(10, 1); //声明一个初始大小为10且值都是1的向量
vector<int> vec(tmp);   //声明并用tmp向量初始化vec向量
vector<int> tmp(vec.begin(), vec.begin() + 3);  //用向量vec的第0个到第2个值初始化tmp
int arr[5] = {1, 2, 3, 4, 5};   
vector<int> vec(arr, arr + 5);      //将arr数组的元素用于初始化vec向量
//说明:当然不包括arr[4]元素,末尾指针都是指结束元素的下一个元素,
//这个主要是为了和vec.end()指针统一。
vector<int> vec(&arr[1], &arr[4]); //将arr[1]~arr[4]范围内的元素作为vec的初始值

//2. 元素排序
#include <algorithm>
sort(vec.begin(), vec.end()); //采用的是从小到大的排序
//如果想从大到小排序,可以采用上面反转函数,也可以采用下面方法:
bool Comp(const int& a, const int& b) {
    return a > b;
}
sort(vec.begin(), vec.end(), Comp);

//3.元素翻转
#include <algorithm>
reverse(vec.begin(), vec.end());

//4.遍历元素
vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); it++)
    cout << *it << endl;
//或者
for (size_t i = 0; i < vec.size(); i++) {
    cout << vec.at(i) << endl;
}

vector基本操作
(1). 容量

向量大小: vec.size();
向量最大容量: vec.max_size();
更改向量大小: vec.resize();
向量真实大小: vec.capacity();
向量判空: vec.empty();
减少向量大小到满足元素所占存储空间的大小: vec.shrink_to_fit(); //shrink_to_fit

(2). 修改

多个元素赋值: vec.assign(); //类似于初始化时用数组进行赋值
末尾添加元素: vec.push_back();
末尾删除元素: vec.pop_back();
任意位置插入元素: vec.insert();
任意位置删除元素: vec.erase();
交换两个向量的元素: vec.swap();
清空向量元素: vec.clear();

(3)迭代器

开始指针:vec.begin();
末尾指针:vec.end(); //指向最后一个元素的下一个位置
指向常量的开始指针: vec.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
指向常量的末尾指针: vec.cend();

(4)元素的访问

下标访问: vec[1]; //并不会检查是否越界
at方法访问: vec.at(1); //以上两者的区别就是at会检查是否越界,是则抛出out of range异常
访问第一个元素: vec.front();
访问最后一个元素: vec.back();
返回一个指针: int* p = vec.data(); //可行的原因在于vector在内存中就是一个连续存储的数组,所以可以返回一个指针指向这个数组。这是是C++11的特性。

5.2.deque容器(类似于队列)

deque的使用:




//1.插入数值到deque 
//c.insert(pos,num)在pos位置插入元素num
//c.insert(pos,n,num)在pos位置插入n个元素num
//c.insert(pos,beg,end)在pos位置插入区间为[beg,end)的元素

 deque<int> d {1,2,3,4,5};
     deque<int>::iterator it;
     cout << "insert before:" ;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
     d.insert(d.end(),22);
     d.insert(d.end(), 3,88);
     int a[5] = {1,2,3,4,5};
     d.insert(d.begin(),a,a+3);
     cout << "insert after:" ;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
    cout << endl;
//2.删除deque中的元素
//c.erase(pos)删除pos位置的元素
//c.erase(beg,end)删除区间为[beg,end)之间的元素
deque<int> d {1,2,3,4,5};
     d.erase(d.begin());
     deque<int>::iterator it;
     cout << "erase(pos) after:" ;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
     d.erase(d.begin(), d.begin()+3);
     cout << "erase(beg,end) after:" ;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
//c.push_back(num)在末尾位置插入元素
//c.pop_back()删除末尾位置的元素
//c.push_front(num)在开头位置插入元素
//c.pop_front()删除开头位置的元素
 deque<int> d {1,2,3,4,5};
     d.push_back(10);
     deque<int>::iterator it;
     cout << "push_back(num):" ;
     for(it=d.begin();it!=d.end();it++){
             cout << *it << " ";
     }
     cout << endl;
     
     d.pop_back();
     cout << "pop_back(num):" ;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
     
     d.push_front(10);
     cout << "push_front(num):" ;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
     
     d.pop_front();
   cout << "pop_front(num):" ;
    for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
    return 0;

//3.迭代器遍历
 deque<int> d {1,2,3,4,5};
     deque<int>::iterator it;
     for(it=d.begin();it!=d.end();it++){
         cout << *it << " ";
     }
     cout << endl;
//反向迭代器(从尾部向头部向尾部迭代)
//c.rbegin()返回指向反向队列的第一个元素的迭代器(即原队列的最后一个元素)
//c.rend()返回指向反向队列的最后一个元素的下一个位置(即原队列的第一个元素的前一个位置)
     deque<int> d {1,2,3,4,5};
     deque<int>::reverse_iterator it;
     for(it=d.rbegin();it!=d.rend();it++){
         cout << *it << " ";
     }
    cout << endl;






构造函数
  deque c 创建一个空的deque
  deque c1(c2) 复制一个deque。
  deque c(n) 创建一个deque,含有n个数据,数据均已缺省构造产生。
  deque c(n, elem) 创建一个含有n个elem拷贝的deque。
  deque c(beg,end) 创建一个以[beg;end)区间的deque。
  ~deque() 销毁所有数据,释放内存。
成员函数
迭代器:
c.begin()返回指向第一个元素的迭代器
c.end()返回指向最后一个元素下一个位置的迭代器
c.rbegin()返回指向反向队列的第一个元素的迭代器(即原队列的最后一个元素)
c.rend()返回指向反向队列的最后一个元素的下一个位置(即原队列的第一个元素的前一个位置)
operator=赋值运算符重载
c.assign(n,num)将n个num拷贝复制到容器c
c.assign(beg,end)将[beg,end)区间的数据拷贝复制到容器c
c.operator[]下标运算符重载
c.empty()判断c容器是否为空
c.front()返回c容器的第一个元素
c.back()返回c容器的最后一个元素
c.size()返回c容器中实际拥有的元素个数
c.max_size()返回c容器可能存放元素的最大数量
c.clear()清除c容器中拥有的所有元素
c.resize(num)从新定义容器的大小
c1.swap(c2)交换容器c1,c2;

5.3.map容器(key———valu)

map的使用:

//1.用insert函数插入pair数据
//数据的插入--第一种:用insert函数插入pair数据  
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
    map<int, string> mapStudent;  
    mapStudent.insert(pair<int, string>(1, "student_one"));  
    mapStudent.insert(pair<int, string>(2, "student_two"));  
    mapStudent.insert(pair<int, string>(3, "student_three"));  
}  

//2.用数组方式插入数据
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
     map<int, string> mapStudent;  
    mapStudent[1] = "student_one";  
    mapStudent[2] = "student_two";  
    mapStudent[3] = "student_three"; 
    //区别:
    //map<int, string> iter 是 声明一个map容器  
    //map<int, string>::iterator iter 是声明一个 迭代器
    map<int, string>::iterator iter;  
    
  
}  

//数据的删除
#include <map>  
  
#include <string>  
  
#include <iostream>  
  
using namespace std;  
  
int main()  
  
{  
  
       map<int, string> mapStudent;  
       mapStudent.insert(pair<int, string>(1, "student_one"));  
       mapStudent.insert(pair<int, string>(2, "student_two"));  
       mapStudent.insert(pair<int, string>(3, "student_three"));  
        //如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好  
       //如果要删除1,用迭代器删除  
       map<int, string>::iterator iter;  
       iter = mapStudent.find(1);  
       mapStudent.erase(iter);  
       //如果要删除1,用关键字删除  
       int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0  
       //用迭代器,成片的删除  
       //一下代码把整个map清空  
       mapStudent.erase( mapStudent.begin(), mapStudent.end() );  
       //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合  
       //自个加上遍历代码,打印输出吧  
  
}  
// 数据的遍历
//3.用数组方式,程序说明如下  
  
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
    map<int, string> mapStudent;  
    mapStudent.insert(pair<int, string>(1, "student_one"));  
    mapStudent.insert(pair<int, string>(2, "student_two"));  
    mapStudent.insert(pair<int, string>(3, "student_three"));  
    int nSize = mapStudent.size();  
//此处应注意,应该是 for(int nindex = 1; nindex <= nSize; nindex++)  
//而不是 for(int nindex = 0; nindex < nSize; nindex++)  
    for(int nindex = 1; nindex <= nSize; nindex++)  
     cout<<mapStudent[nindex]<<endl;  
  
}  


使用map:

map对象是模板类,需要关键字和存储对象两个模板参数:std:map<int,string> personnel;
map的构造函数: map<int, string> mapStudent;
数据的插入:1.用insert函数插入pair数据 2.用数组方式插入数据
map的大小:在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数
Int nSize = mapStudent.size();

从map中删除元素
移除某个map中某个条目用erase()
该成员方法的定义如下:
iterator erase(iterator it);//通过一个条目对象删除
iterator erase(iterator first,iterator last)//删除一个范围
size_type erase(const Key&key);//通过关键字删除
clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());
这里要用到erase函数,它有三个重载了的函数

//_______________________________________________________________________________
查找并获取map中的元素(包括判定这个关键字是否在map中出现)

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。

查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,在这里需要提到的是begin()和end()两个成员,

分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.

//查找并获取map中的元素
#include <map>  
#include <string>  
#include <iostream>  
using namespace std;  
int main()  
{  
    map<int, string> mapStudent;  
    mapStudent.insert(pair<int, string>(1, "student_one"));  
    mapStudent.insert(pair<int, string>(2, "student_two"));  
    mapStudent.insert(pair<int, string>(3, "student_three"));  
    map<int, string>::iterator iter;  
    iter = mapStudent.find(1);  
    if(iter != mapStudent.end())  
       cout<<"Find, the value is "<<iter->second<<endl;  
    else  
        cout<<"Do not Find"<<endl;  
    return 0;  
}  

二,选择/循环语句

三,函数

函数逻辑组成:

函数逻辑块 功能
if语句 判断对应条件下的对应情况
switch语句 判断对应条件下的对应情况
————— ————————————————
for循环语句 进行大量初始化
while循环语句 进行大量初始化

函数分类:

函数类型 作用
内联函数 编译时,函数调用处被函数体替换(提高效率)
函数模板 参数个数相同,类型不同(提高函数参数的通用性,同一参数可以定义为多种类型)
函数重载 参数类型,顺序,个数不相同(提高函数名的通用性,同一函数名可以有多种用途)
虚函数 纯虚函数没有函数体,只有函数声明(派生类按需求实现纯虚函数)

—————————————————————————————————————

四,C++类

在这里插入图片描述

虚函数:父类中提供虚函数并实现。(目的是“运行时多态”,为子类提供默认的函数实现。)
纯虚函数:纯虚函数在类中只提供声明,不提供实现,实现由子类去完成。(目的是为了实现“运行时的多态”。)

函数模板:用于函数的变量类型
类模板:用于类的函数变量类型+类成员的类型

c++异常及异常处理

程序的错误大致可以分为三种,分别是:
①语法错误(语法错误在编译和链接阶段就能发现)
②逻辑错误( 逻辑错误是编写的代码思路有问题,可以通过调试来解决)
③运行时错误(运行时错误是指程序在运行期间发生的错误,可以通过C++ 异常机制解决)
(运行时错误eg:除数为 0、内存分配失败、数组越界、文件不存在等。)

try catch异常处理

捕获异常的语法为:

try{
    // 可能抛出异常的语句
}catch(exceptionType variable){
    // 处理异常的语句
}

exceptionType是异常类型,异常类型可以是 int、char、float、bool 等基本类型,也可以是指针、数组、字符串、结构体、类等聚合类型。
variable是一个变量,用来接收异常信息。当程序抛出异常时,会创建一份数据,这份数据包含了错误信息。
C++ 语言本身以及标准库中的函数抛出的异常,都是 exception 类或其子类的异常。也就是说,抛出异常时,会创建一个 exception 类或其子类的对象。

抛出异常

抛出(Throw)–> 检测(Try) --> 捕获(Catch)

// throw 关键字来显式地抛出异常的用法为:
throw exceptionData;
//exceptionData 是“异常数据”的意思,它可以包含任意的信息,完全有程序员决定。
//exceptionData 可以是 int、float、bool 等基本类型,也可以是指针、数组、字符串、结构体、类等聚合类型。

多级 catch

try{
    //可能抛出异常的语句
}catch (exception_type_1 e){
    //处理异常的语句
}catch (exception_type_2 e){
    //处理异常的语句
}
//其他的catch
catch (exception_type_n e){
    //处理异常的语句
}

eg:

#include <iostream>
#include <string>
using namespace std;

class Base{ };
class Derived: public Base{ };

int main(){
    try{
        throw Derived();  //抛出自己的异常类型,实际上是创建一个Derived类型的匿名对象
        cout<<"This statement will not be executed."<<endl;
    }catch(int){
        cout<<"Exception type: int"<<endl;
    }catch(char *){
        cout<<"Exception type: cahr *"<<endl;
    }catch(Base){  //匹配成功(向上转型)
        cout<<"Exception type: Base"<<endl;
    }catch(Derived){
        cout<<"Exception type: Derived"<<endl;
    }

    return 0;
}
发布了48 篇原创文章 · 获赞 29 · 访问量 4432

猜你喜欢

转载自blog.csdn.net/qq_43573718/article/details/91432174