C++ STL容器vector篇(一) vector容器存放内置和自定义数据类型并遍历

550 阅读2分钟

写在前面

本文算是B站黑马C++课程STL-vector部分的一个总结, 包含自己的一些想法(都在代码里了).

存放内置数据类型

int类型为例, 直接使用vector<int> v; 即可创建存放int类型数据的vector容器, 通过push_back()函数进行赋值.

遍历容器有三种方式, 前两种需要使用vector中的迭代器进行实现.

  • begin()迭代器指向容器中的第一个元素;
  • end()迭代器指向容器中最后一个元素的后一个元素(为空), 这点类似Python中的列表索引方式,是一个左闭右开区间;

最后一种方法使用了STL的algorithm头文件中的for_each()函数, 通过给定容器的两个迭代器和自定义函数(回调函数)进行遍历.

代码

#include<iostream>
#include<vector>
#include <algorithm>

using namespace std;

// 自定义的打印函数, 在第三种遍历方式中会用到
void myprint(int val)
{
    cout<<val<<endl;
}

void test1()
{
	// 首先创建一个vector容器并赋值
    vector<int> v;
    v.push_back(1);
    v.push_back(3);
    v.push_back(5);
    v.push_back(7);
    v.push_back(9);
    // // 遍历方式1: while循环, 需要指定开始和结束两个迭代器
    // vector<int>::iterator itBegin = v.begin();
    // vector<int>::iterator itEnd = v.end();
    // while(itBegin != itEnd)
    // {
    //     cout<<*itBegin<<endl;
    //     itBegin++;
    // }

    // // 遍历方式2: for循环, 直接在循环体重指定迭代器即可
    // for (vector<int>::iterator it = v.begin();it< v.end();it++)
    // {
    //     cout<<*it<<endl;
    // }

    // 遍历方式3: 需要algorithm头文件, 以及自定义的打印函数
    for_each(v.begin(), v.end(), myprint);
}

int main() 
{
    test1();
    return 0;
}

运行结果:

1
3
5
7
9
[Finished in 1.4s]

存放自定义数据类型

代码

#include<iostream>
#include<vector>
#include <algorithm>
#include <string>

using namespace std;


// 先定义一个P类
class P
{
public:
    string name;
    int age;
    P(string name, int age)
    {
        this->name = name;
        this->age = age;
    }
};

void myprint(P &val)
{
    cout<<"name: "<<val.name<<"  age: "<<val.age<<endl;
}


// 方式一: 直接存放数据
void test1()
{
    vector<P> v;
    P p1("a", 1);
    P p2("b", 3);
    P p3("c", 5);
    v.push_back(p1);
    v.push_back(p2);
    v.push_back(p3);

    // // 遍历方式1
    // vector<P>::iterator itBegin = v.begin();
    // vector<P>::iterator itEnd = v.end();
    // while(itBegin != itEnd)
    // {
    //     // cout<<"name: "<<(*itBegin).name<<" age:  "<<(*itBegin).age<<endl;
    //     cout<<"name: "<<itBegin->name<<" age:  "<<itBegin->age<<endl;
    //     itBegin++;
    // }

    // // 遍历方式2
    // for (vector<P>::iterator it = v.begin();it != v.end();it++)
    // {
    //     // cout<<"name: "<<(*it).name<<" age:  "<<(*it).age<<endl;
    //     cout<<"name: "<<it->name<<"  age: "<<it->age<<endl;
    // }

    // 遍历方式3
    for_each(v.begin(), v.end(), myprint);
}


void myprint1(P* &val)
{
    cout<<"name: "<<(*val).age<<"  age: "<<(*val).name<<endl;
}

// 方式二: 存放自定义数据类型的地址(指针), 指针的指针
void test2()
{
    vector<P*> v;
    P p1("a", 1);
    P p2("b", 3);
    P p3("c", 5);
	
	// 
    v.push_back(&p1);
    v.push_back(&p2);
    v.push_back(&p3);

    // // 遍历方式1
    // vector<P>::iterator itBegin = v.begin();
    // vector<P>::iterator itEnd = v.end();
    // while(itBegin != itEnd)
    // {
    //     // cout<<"name: "<<(*itBegin).name<<" age:  "<<(*itBegin).age<<endl;
    //     cout<<"name: "<<itBegin->name<<" age:  "<<itBegin->age<<endl;
    //     itBegin++;
    // }

    // // 遍历方式2
    // for (vector<P*>::iterator it = v.begin();it != v.end();it++)
    // {
    //     // 指针的指针
    //     cout<<"name: "<<(**it).name<<"  age: "<<(**it).age<<endl;
    //     // 外层指针解引用之后得到类的指针再取值
    //     cout<<"name: "<<(*it)->name<<"  age: "<<(*it)->age<<endl;
    // }

    // 遍历方式3
    for_each(v.begin(), v.end(), myprint1);
}

int main() 
{
    // test1();
    test2();
    return 0;
}

运行结果:

name: 1  age: a
name: 3  age: b
name: 5  age: c
[Finished in 1.2s]

总结

在进行取值的时候, 需要注意迭代器的类型是值还是地址, 如果是地址的话需要进行解引用, 或者直接用->的方式进行取值.