欢迎光临散文网 会员登陆 & 注册

黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难

2022-10-26 10:56 作者:Ctrl_CVa  | 我要投稿

C++重点笔记

tips

编译和调试的区别

编译(compile):依赖于编译器,将源码转化成目标文件 如.obj

调试:让程序在系统中运行之前查错和改错,找出并修正潜在的错误

-------------------------------------------------------------

B站篇幅有限,没有markdown模式,完整笔记请看https://blog.csdn.net/liushuping528/article/details/126087429?spm=1001.2014.3001.5501

--------------------------------------------------------------

linux c++的四个处理过程

1. 预处理

将所有#include头文件以及宏定义替换成其真正的内容

2. 编译

将经过预处理之后的程序转换成特定汇编代码的过程

3. 汇编

将上一步的汇编代码转换成机器代码,这一步产生的文件叫做目标文件

4. 链接

将多个目标文件以及所需的库文件(.so)链接成最终的可执行文件

数据类型

4种转换较为规范的运算符

`reinterpret_cast<type-name>(expression)`


1. reinterpret_cast 可以将指针类型转换为足以存储指针表示的整型

2. 不能将函数指针转换为数据指针

static_cast

`auto *ptr = static_cast<void(Teacher::*)(QString)>(&Teacher::hungry);`


尖括号里面的转为外面的


用于各种隐式转换,如非const转const,void*转指针,static_cast能用于多态向上转化,如果向下转能成功但是不安全

## 内存模型和名称空间


### 单独编译


将组件函数放在独立的文件中,然后将他们链接成可执行的程序。如若要修改文件,只需重新头文件,然后将它与其他文件编译版本链接,程序的管理更为便捷


**组织策略 可以把程序拆分为三个部分**


1. 头文件:编写函数原型 结构声明



eg:

```cpp

#ifndef STOCK_H_

#define STOCK_H_

struct polar

{

    double distance;

    double angle;

};

struct rect

{

    double x;

    double y;

};


polar rect_to_polar(rect xypos);

void show_polar(polar dapos);

#endif

```

2. 源代码文件:函数定义

 


eg:

```cpp

#include <iostream>

#include<cmath>

#include "stock.h"

polar rect_to_polar(rect xypos) {

    using namespace std;

    polar answer;

    answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);

    answer.angle = atan2(xypos.x, xypos.y);

    return answer;

}

void show_polar(polar dapos) {

    using namespace std;

    cout << "angle" << dapos.angle << endl;

    cout << "distance" << dapos.distance << endl;

}


```

3. 源代码文件:main()和其他使用这些函数的函数放在第三个文件

 


```cpp

#include <iostream>

#include "stock.h"

using namespace std;

int main() {

    rect rplace;

    polar pplace;

    cout << "enter the x and y values: ";

    while (cin >> rplace.x >> rplace.y) {

        pplace = rect_to_polar(rplace);

        show_polar(pplace);

        cout << "next two number(q to quit):";


    }

    cout << "bye!\n";

    return 0;

}

```

> 1.高效的组织策略,编写另一程序,需要使用这些函数时,只需包含头文件,并将函数文件添加到项目列表或make列表中即可。

> 2.这种组织方式也是面向对象(OOP)的体现


**头文件包含的内容:**

* 函数原型

* 结构声明

* 类声明

* 内联函数(~)

* 模板声明(~)


头文件编写

```cpp

#ifndef HEAD_H_  //根据include名选择名称,并加上下划线 以防止被其他地方定义

#define HEAD_H_

…… //file content

#endif

```



名称空间 -ing

名称可以是函数、变量、结构、类以及类的成员,随着项目的增大,名称相互冲突的可能性也将增加


```cpp

namespace jack{

    double pail;

    void fetch();

    int pal;

    struct well{}

}

```

名称空间是开放的(open),

1.   .

```cpp

namespace jack{

    char name[10];

}

```

2. jack名称空间为fetch()函数提供原型。可以在文件后面再次使用Jack名称空间定义这个函数

```cpp

namespace jack{

    void fetch(){

        ……

    }

}

```

using声明和using编译


* **using声明**由using和被限定的名称组成

*

`using jack::pail;  // 一个using声明`


  using声明将特定的名称添加到它所属的声明区域中。  

 

  ```cpp

  int main(){

      using jack::pail;

      cin >> pail;

      cin >> ::pail; //读入进去一个pail全局变量

  }

  ```


using声明使一个名称可用,而using编译指令使所有名称都可用。


* **using编译指令**由using namespace和名称空间组成

*

`using namespace jack; //一个using编译声明`


using namespace


**总结:** 导入名称时,首选使用作用域解析运算符或using声明的方法。


### const成员函数


const关键字放在函数的括号后面 stock类中的函数声明


`void show() const  //函数声明`


函数定义的开头


`void stock :: show() const //函数定义 不被改变`


只要类不修改调用对象,就应将其声明为const




## effective C++

### 永远在使用对象之前先将它初始化

构造函数做好使用成员初始列,而不要在构造本体函数内使用赋值操作



### 8-2法则

一个程序的80%的资源用于20%的代码身上,80%执行时间花在20%的代码身上,80%执行时间花在20%的代码


8-2 法则告诉我们,如果东一块西一块的改善程序,病急乱投医,头痛医头脚痛医脚,不会有太大帮助。

枚举类型 enum

定义:

enum 类型名{枚举值表}

枚举值表也叫枚举元素列表,列出定义的枚举类型的所有可用值,各个值之间用“,”分开。

`enum Suit{Diamonds,Hearts,Clubs};`



数组


c++的运算符优先要求使用括号


数组类比于指针

数组名是第一个元素的地址

int* a的类型是int* int a的类型是int

前者a是指向整型数据的指针,它的本质是一个地址,后者就是一个数据了


`Dog* dog = new Dog;` 分配一片内存 并把内存的地址赋给 dog

### 无符号类型

不能存储负数值的无符号变体,其优点是可以增大变量能够存储的最大值

(short范围-32768-32767,unsign short范围0-65535)

### 指针表示动态数组

使用new[]运算符创建数组时,将采用动态联遍,即将在运行时为数组分配空间,其长度也将在运行时设置

使用完成后,应用delete[]释放占用的内存

```cpp

int size;

cin >>size;

int *arr = new int [size];

……

delete[] arr;

```

### 数组区间的函数

指定元素区间 可以通过传递两个指针完成:一个指针标识数组的开头,另一个指针标识数组的尾部

```c++

int sum_arr(const int *begin,const int *end); //函数声明

int main(){

    int arr[10];

    int sum = sum_arr(arr,arr+3); //定义区间  

}

```

### const保护数组

为防止函数无意中修改数组的内容,可在声明形参时使用关键字**const**

`void show_array(const double ar[],int n)`

### 结构体

```c++

struct typename {

    char name[10];

    int ages;

}

```

1. new 创建动态结构


`inflat *ps = new inlat;`

使用完成后要用**delete**释放内存 `delete ps;`

> ps -> price 也是指向结构的price成员

> ps 是指向结构的指针,则*ps就是指向的值--结构本身

> (*ps)是一种结构 (*ps).name 是该结构的name成员


## 函数

### 函数原型

原型可以帮助编译器完成许多工作,降低程序出错的机率,具体有一下几点:

1. 编译器正确处理函数返回值

2. 编译器检查使用的参数数目是否正确

3. 编译器检查使用参数类型是否正确


###  #define的定义

(文本替换)

define 是宏定义,程序在预处理阶段将用define定义的内容进行替换。程序在运行时,常量表中并没有用define定义的常量,系统不会为它分配内存

 1. #define定义一个标识符来表示一个常量。

 特点:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了


    * 宏展开是在预处理阶段完成的,这个阶段把替换文本只看做一个字符串,并不会有任何的计算发生。

    * 宏其实就是简单的文本替换。


定义标识符的一般形式:

```c++

#define 标识符 常量 //注意,最后没有分量

```

2. 在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的的功能就是条件编译

```cpp

#ifdef WINDOWS

……

#endif

#ifdef LINUX

……

#endif

```

可以在编译的时候通过#define设置编译环境。

### 函数指针

使用函数指针的三个步骤:

1. 声明函数指针

2. 让函数指针指向函数地址

3. 通过函数指针调用函数


**声明函数指针**

```cpp

double pam(int)  //函数原型


double (*f)(int)   //函数指针

```

pam 替换为了(*f).由于pam是函数名 即(*f)也是函数名, f 是函数指针


**函数指针调用函数**

```cpp

//函数指针调用函数

f = pam;

double y = pam(2);

double x = (*f)(5);


```

```cpp

#include<iostream>

using namespace std;

double jack(int);

double rose(int);

void accrate(int lines, double(*pf)(int)); //声明指针函数

int main() {

    int code;

    cin >> code;

    cout<<"jack和rose输入"<<code<<"行代码算花费的时间"<<endl;

    accrate(code, jack);

    accrate(code, rose);

}

double jack(int n) {

    double sum = n * 0.5;

    return sum;

}

double rose(int n) {

    double sum = n * 0.7;

    return sum;

}


void accrate(int lines, double(*pf)(int)) {

    //double um = (*pf)(lines);

    cout << lines << " lines may have " << (*pf)(lines) << "mins" << endl;


}

```


### 回调函数


> 回调函数就是一个通过函数指针调用的函数,如果你把函数的指针作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说回调函数


把一段可执行的代码像参数传递那样传给其他代码,而这个代码在某个时刻被调用执行,叫做回调。


如果代码立即被执行就称为**同步回调**,如果在之后晚点的某个时间在执行,则称为**异步回调**


回调函数的作用 ,**解耦**


```cpp

#include "../apue.h"


int Call_back_1(int x)

{

    printf("Hello,this is Call_back_1,the value is %d\n",x);

    return 0;

}


int Call_back_2(int x){

    printf("Hello,this is Call_back_2,the value is %d\n",x);

    return 0;

}


int Call_back_3(int x){

    printf("Hello,this is Call_back_3,the value is %d\n",x);

    return 0;

}


int Handle(int x,int (*Callback)(int x))

{

    printf("Entering Handle Function.\n");

    Callback(x);

    printf("Leaving Handle Function.\n");

    return 0;


}


int main(){


    int x = 1;

    int y = 2;

    int z = 3;

    printf("Entering Main Function.\n");

    Handle(x,Call_back_1);

    Handle(y,Call_back_2);

    Handle(z,Call_back_3);

    printf("Leaving Main Function.\n");

    return 0;

}


```





### 引用&

1. 形参需要修改实参时

2. 当实参较大时,如(数据 结构体)传递引用 系统不会生成临时变量 较小的内存消耗


### 形参实参的三种传值方式

 1. 按值传递

2. 按地址传递 形参改变实参

3. 按引用传递


```cpp

#include<iostream>

void swap1(int a, int b) {

    int temp;

    temp = a;

    a = b;

    b = temp;

}


void swap2(int* p, int* q) {

    int temp;

    temp = *p;

    *p = *q;

    *q = temp;

}


void swap3(int& a, int& b) {

    int temp;

    temp = a;

    a = b;

    b = temp;

}


int main() {

    int i = 10;

    int j = 20;

    //按值传递  

    swap1(i, j); //形参不会对实参进行修改

    std::cout << "i的值是" << i << std::endl;

    std::cout << "j的值是" << j << std::endl;


    //按地址传递  

    swap2(&i, &j); //形参会对实参进行修改

    std::cout << "i的值是" << i << std::endl;

    std::cout << "j的值是" << j << std::endl;


    //按引用传递  

    swap3(i, j); //形参不会对实参进行修改

    std::cout << "i的值是" << i << std::endl;

    std::cout << "j的值是" << j << std::endl;

    return 0;


}

```

## STL模板


### vector容器


与数据相似,也成为单端数组(类比于栈)


**vector与普通的数组的区别**


数组时静态空间,而vector可以动态扩展


**动态扩展**


并不是在原有的基础上进行拓展,而是找一个更大的空间,将原数据拷贝到新空间,释放原空间


vector迭代器 支持随机访问的迭代器


vector四种构造方法

1. 默认构造

2. 区间构造

3. 拷贝构造

4. n个元素构造



```cpp

#include<iostream>

#include<vector>

using namespace std;

void printvector(vector<int> &v) {

    for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {

        cout << *it << " ";

    }

    cout << endl;

}

void test() {

    //默认构造

    vector<int>v1;


    for (int i = 0; i < 50; i++) {

        v1.push_back(i);


    }

    printvector(v1);


    //通过区间的方式进行构造

    vector<int>v2(v1.begin(), v1.end());

    printvector(v2);


    //N个elem方式构造

    vector<int>v3(10, 123);//(个数,元素)

    printvector(v3);

    //拷贝构造

    vector<int>v4(v3);

    printvector(v4);

```

**vector的增删查**

```cpp

struct review

{

    string title;

    int rating;

};

bool Fillreview(review& re);

void printbook(vector<review>& b1);

int main() {

    vector<review>book;

    review temp;

    while (Fillreview( temp)) {

        book.push_back(temp);

    }

    printbook(book);

    vector<review>oldbook(book);

    printbook(oldbook);

    book.erase(book.begin() + 1, book.begin() + 3); //vector的删除

    printbook(book);

    book.insert(book.begin(), oldbook.begin() + 1, oldbook.begin() + 2);//vector的插入

    printbook(book);

   

   

    book.swap(oldbook);

    printbook(book);

    return 0;

    system("pause");

}


bool Fillreview(review& re)

{

    cout << "please enter a book name" << endl;

    getline(cin,re.title);

    if (re.title == "quit")

    {

        return false;

    }

    else

        cin >> re.rating;

    if (!cin)

        return false;

    while (cin.get()!='\n')

    {

        continue;

    }

    return true;

}


void printbook(vector<review>& b1)

{

    for (vector<review>::iterator it =b1.begin();it!=b1.end();it++)

    {

        cout << (*it).rating <<" "<<(*it).title<< endl;

    }

    cout << "--------------------" << endl;

}


```

**支持随机访问的容器 都可以用标准算法sort进行排序**


### list双向循环链表


由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器


list 不支持随机存取


List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的


STL中**list和vector是两个最常使用的容器**,各有缺点


`list.reverse();` 双向链表的反转


`list.sort()` 双向链表的排序


`font` 首元素


`back` 尾部元素


**list自定义类型排序**


> 自定义类型 类类型or结构类型 要先指定类型规则


**语法**


```cpp

//指定排序规则   如果年龄相等 按照体重排序

bool compareage(Person& p1, Person& p2) {

    if (p1.m_age == p2.m_age) {

        return p1.m_weight < p2.m_weight;

    }

    else

    {

        return p1.m_age < p2.m_age;

    }

   

}

```


```cpp

#include<iostream>

#include<list>

#include<string>

using namespace std;

class Person {

public:

    Person(string name, int age,float weight) {

        this->m_name = name;

        this->m_age = age;

        this->m_weight = weight;

    }

    string m_name;

    int m_age;

    float m_weight;

};

void printlist(list<Person>& p) {

    for (list<Person>::const_iterator it=p.begin();it!=p.end();it++)

    {

        cout << (*it).m_name << it->m_age <<" " << it->m_weight << " ";

    }

    cout << endl;

}


//指定排序规则   如果年龄相等 按照体重排序

bool compareage(Person& p1, Person& p2) {

    if (p1.m_age == p2.m_age) {

        return p1.m_weight < p2.m_weight;

    }

    else

    {

        return p1.m_age < p2.m_age;

    }

   

}

void test() {

    Person p1("zhangsan", 56,50.2);

    Person p2("lisi", 16,53.2);

    Person p3("wangwu", 16,59.9);

    Person p4("zhaoliu", 17,45.9);

    Person p5("gouba", 19,49.3);

    list<Person>ll;

    ll.push_back(p1);

    ll.push_back(p2);

    ll.push_back(p3);

    ll.push_back(p4);

    ll.push_back(p5);

    printlist(ll);

    ll.sort(compareage);

    printlist(ll);

}

int main() {

    test();

    return 0;

}

```

### 关联容器set,mutiset


所以的元素都会在插入时自动排序


set与multiset属于关联容器,底层结构是二叉树实现


**区别**

1. set不允许容器有重复的元素

2. multiset允许容器有重复的元素


set的插入使用的是insert,没有push_back这个方法


empty();


size();


swap();


**插入删除**


insert()


erase(迭代器) erase(容器元素)


clear(); 清空


**查找和统计**


find(); //查找key是否存在,返回该元素的迭代器不存在 返回set.end()


cout(); 要么是0 要么是1


### set容器排序规则


set的默认排序规则是从小到大,改变排序规则从大到小


利用仿函数,改变排序规则



### map/multimap容器


map所有元素都是一对


第一个key值(索引的作用)第二个valu值(实值)


所有元素都会根据元素的键值自动排序


关联容器,二叉树实现


可以通过key值快速的找到value值


map与multimap 的区别 是能不能插入重复的key值


```cpp

void printmap(map<int, int>& ma) {

    for (map<int,int>::const_iterator it =ma.begin();it!=ma.end();it++)

    {

        cout << "key= " << (*it).first << " value=" << (*it).second << endl;

    }

    cout << endl;

}

void test() {

    //map容器

    map<int, int>m;    //k v  创建map容器

    m.insert(pair<int, int>(1, 10));

    m.insert(pair<int, int>(2, 28));

    m.insert(pair<int, int>(4, 20));

    m.insert(pair<int, int>(6, 21));

    m.insert(pair<int, int>(9, 320));

    m.insert(make_pair(10, 22));       //make_pair 插入

    printmap(m);

    map<int, int>m2(m);   //拷贝构造函数

    printmap(m2);

    map<int, int>m3;

    m3 = m2;          //赋值

    printmap(m3);

    cout << m[6] << endl;     //可以使用[]查找;

    cout<<m.size()<<endl;

    //删除

    m.erase(m.begin()); //按照迭代器删除

    m.erase(6);   //按照key值删除

    printmap(m);

    }


```


查找 统计


`find()` 查找key值是否存在,不存在返回set.end;


```cpp

map<int, int>::iterator it = m.find(9);

    cout << (*it).first <<it->second<<endl;

```

cout()  0or1


使用仿函数改变map的默认排序  由大到小


> 仿函数 传入的时候传入一个数据类型,在类中重载了()函数

  重载()

 

```cpp

class Mycompare {

public:

    bool operator()(int v1, int v2) const  自定义排序规则

    {

        return v1 > v2;

    }

};

```


```cpp

void printmap(map<int, int,Mycompare>& ma) {

    for (map<int, int>::const_iterator it = ma.begin(); it != ma.end(); it++)

    {

        cout << "key= " << (*it).first << " value=" << (*it).second << endl;

    }

    cout << endl;

}

void test() {

    //map容器

    map<int, int,Mycompare>m;    //k v  创建map容器

    m.insert(pair<int, int>(1, 10));

    m.insert(pair<int, int>(2, 28));

    m.insert(pair<int, int>(4, 20));

    m.insert(pair<int, int>(6, 21));

    m.insert(pair<int, int>(9, 320));

    m.insert(make_pair(10, 22));

    printmap(m);

}

```


### 函数对象


重载函数调用操作符的类,其对象成为函数对象


对()重载的函数 也叫仿函数


```cpp

#include<iostream>

using namespace std;

//1. 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值

class Mycompare {

public:

    int operator()(int v1, int v2) {

        return v1 + v1;

    }

};


void test() {

    Mycompare myadd;

    cout << myadd(10, 10) << endl;

}

//2. 函数对象可以有自己的状态

class Myprint {

public:

    Myprint() {

        count = 0;

        }

    void operator()(string test) {

        cout << test << endl;

        this->count++;

    }

    int count;  //内部自己的状态

};


void test1() {

    Myprint myprint;

    myprint("helloworld");

    myprint("helloworld");

    myprint("helloworld");

    cout << "myprint调用次数" << myprint.count << endl;

}


void doprint(Myprint& mp, string test) {

    mp(test);

}

//3. 函数对象可以作为参数传递

void test2() {

    Myprint my1;

    doprint(my1, "hello C++");

}

```

#### 内建仿函数


**算术仿函数**


```cpp

#include<iostream>

#include<functional>    //使用内建函数对象时,需要引入头文件 #include<functional>

using namespace std;

void test() {

    //negate 一元仿函数 取反函数

    negate<int>n;

    cout << n(50) << endl;

}

void test1() {

    //plus 二元仿函数 加法

    plus<int>p;

    cout << p(10, 20) << endl;

}


```

**关系仿函数**


自定义降序仿函数定价与`greater<int>()` -> 需要使用`#include<functional>`


自定义


```cpp

class Mycompare {

public:

    bool operator()(int v1, int v2) const  自定义排序规则

    {

        return v1 > v2;

    }

};

```


### STL-常用算法


算法主要是由头文件<algorithm> 最大的一个,涉及比较、交换、查找、遍历<functional>仿函数  <numeric>


**常用遍历算法**


`for_each(iterator_beg;iterator_end;函数 仿函数);`

```cpp

#include<iostream>

#include<vector>

#include<algorithm>

using namespace std;



//仿函数

class Myprint {

public:

     void operator()(int val) {

        cout << val;

    }

};


void printv(int val) {

    cout << val<<endl;

}

void test() {

    vector<int>v1;

    for (int i=0;i<10;i++)

    {

        v1.push_back(i);

    }

    //for_each算法

    for_each(v1.begin(),v1.end(), printv);

    for_each(v1.begin(), v1.end(), Myprint());


}


```

`transform(v.begin(),v.end(),target.begin(),fun_函数)`


> 搬运的目标容器必须提前开辟空间,否则无法正常搬运


```cpp

class Transform {

public:

    int operator()(int v) {

        return v;

    }


};

class Print {

public:

    void operator()(int val) {

        cout << val << endl;

    }

};

void test() {

    vector<int>v1;

    for (int i=1;i<10;i++)

    {

        v1.push_back(i);

    }

    vector<int>target;

    target.resize(v1.size());  //目标容器需要提前开辟空间

    transform(v1.begin(), v1.end(), target.begin(), Transform());

    for_each(target.begin(), target.end(), Print());

}


```


**常用的查找算法**

1. `find`



`find(iterator.beg(),iter.end(),value)`

find 可以在容器中找指定的元素,返回值是迭代器

自定义类型 需要写仿函数 对"=="就行重载


```cpp

class Person {

public:

    Person(string name, int age) {

        this->m_name = name;

        this->m_age = age;

    }

    string m_name;

    int m_age;

    bool operator ==(Person p2 ) {

        if (this->m_age==p2.m_age&&this->m_name==p2.m_name)

        {

            return true;

        }

    }

};

```

2. `find_if`



按条件查找


`   vector<Person>::iterator it =find_if(p.begin(), p.end(), fun_仿函数);`


3. `binary_search`



二分查找 对于有序的数列

`bool binary_search(it.beg(),it.end(),查找值)`

```cpp

    bool ret = binary_search(v1.begin(), v1.end(), 8);

    cout << ret << endl;


```

4. `count`



统计自定义类型时 需要配合重载`operator==`


自定义数据类型 就在自定义的类型里面就行仿函数的定义


内建型 就添加写一个类对运算符进行重载


5. `count_if`



```cpp

class mix14  //谓词

{

public:

    bool operator()(int v1) {

        return v1 > 12;

    }

};

    int num =count_if(v1.begin(), v1.end(), mix14());


```


**常用排序算法**


1. `sort(it.beg(),it.end(),谓词)`



```cpp

class ree {

public:

    bool operator()(int v1, int v2) {

        return v1 > v2;

    }

};

    sort(v1.begin(), v1.end(), ree());


```

2. 洗牌算法



random_shuffle(it.beg(),it.end())


```cpp

    srand((unsigned int)time(NULL));   //实时时间

    vector<int>v1;

    for (int i=1;i<10;i++)

    {

        v1.push_back(i);

    }

    random_shuffle(v1.begin(), v1.end());

    for_each(v1.begin(), v1.end(), print);


```


3. **merge算法**

```cpp

void test() {

    vector<int>v1;

    vector<int>v2;

    for (int i=1;i<10;i++)

    {

        v1.push_back(i);

        v2.push_back(i + 2);

    }

    vector<int>target;

    target.reserve()

    target.resize(v1.size() + v2.size());     //目标容器定义大小

   

    merge(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin());

    for_each(target.begin(), target.end(), myprint);

}


```

4. **reverse算法**


`   reverse(target.begin(), target.end());`   容器元素反转


常用的拷贝和替换算法


`copy` 容器内指定范围的元素拷贝到另一容器总·


```cpp

    vector<int>tar2;

    tar2.resize(6);

    copy(target.begin(), target.begin() + 6, tar2.begin());


```


`replace`


`replace(tar3.begin(), tar3.end(), 5, 500); ` //将区间的5 替换成500


`replace_if`


```cpp

//谓词

class mix5 {  

public:

    bool operator()(int val) {

        return val > 5;

    }

};


    replace_if(tar3.begin(), tar3.end(), mix5(), 3000);


```

两个容器元素合并,并储存在另一个容器


黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难的评论 (共 条)

分享到微博请遵守国家法律