C++ VECTOR

一、vector简介

在 C++ 中,std::vector 是标准库提供的一个容器类,用于存储动态大小的元素序列(即"动态数组")。它提供了一系列成员函数和操作符,使得元素的访问、插入、删除等操作变得方便和高效。

- vector与数组的区别

  • 扩展:数组的大小在创建时就确定了,无法动态改变,而 std::vector 空间可以动态扩展(不是在原空间后拼接新空间,而是找更大的内存空间,然后将原数据拷贝到新空间,并释放原空间)
  • 内存管理:数组在栈上或静态存储区中分配内存,大小是在编译时确定的。而 std::vector 使用动态内存分配,它在堆上分配内存,并自动处理内存的释放。
  • 访问和操作:数组使用下标操作符 [] 访问元素,而 std::vector 也支持下标操作符,还提供了一些额外的成员函数来方便地操作元素,例如 push_back()pop_back()insert()erase() 等。
  • 大小管理:数组的大小是固定的,无法改变,而 std::vector 可以动态增长或缩小,可以使用 resize() 函数调整大小。
  • 内存开销:由于 std::vector 使用动态内存分配,它可能会引入一些额外的开销,例如内存分配和释放的开销。而数组在编译时就分配了固定大小的内存,因此没有这些开销。
  • 标准库支持std::vector 是 C++ 标准库提供的容器,提供了许多方便的函数和算法来操作和管理元素。而数组是 C++ 的基本数据结构之一,没有提供类似的标准库支持。

总结

  1. 数组适用于大小固定且事先知道元素数量的情况下使用,尤其是数据集较小或需要静态分配内存的场景。
  2. vector 适用于大小可变的情况,特别是需要动态增长或缩小的场景,并且具有更多的功能和灵活性。

二、vector 构造函数

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void printVec(vector<int> &v)
{
    for (vector<int>::iterator At = v.begin(); At != v.end(); At++)
    {
        cout << *At << " ";
    }
    cout << endl;
}
void printVec(vector<double> &v)
{
    for (vector<double>::iterator At = v.begin(); At != v.end(); At++)
    {
        cout << *At << " ";
    }
    cout << endl;
}

void test01()
{
    vector<int> v1;
    v1.push_back(10);  //添加元素
    v1.push_back(20);
    printVec(v1);

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

    vector<double> v3(5, 6.32);
    printVec(v3);

    vector<double> v4(v3);
    printVec(v4);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

std::vector 作为函数的参数或者返回值时,不能缺少其中的“&”。

三、vector 赋值

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void printVec(vector<int> &v)
{
	for (vector<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	vector<int> v1;
	v1.push_back(10);  //添加元素
	v1.push_back(20);
	printVec(v1);

	vector<int> v2 = v1;
	printVec(v2);

	vector<int> v3;
	v3.assign(v1.begin(), v1.end());
	printVec(v3);

	vector<int> v4;
	v4.assign(6, 1);
	printVec(v4);
}

int main()
{
	test01();
	system("pause");
	return 0;
}

四、vector 容量与长度

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void printVec(vector<int> &v)
{
	for (vector<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	vector<int> v1;
    if(v1.empty())     //判断是否为空
    {
        cout << "当前v1为空!"<< endl;
    }
    
	v1.push_back(10);  //添加元素
	v1.push_back(20);
    v1.push_back(30);
    
    if(! v1.empty())
    {
        cout << "v1中元素个数:"<< v1.size() << endl;
        cout << "v1的容量:"<< v1.capacity() << endl;
        printVec(v1);
    }

    v1.resize(5);
    printVec(v1);

    v1.resize(10,1);
    printVec(v1);
}

int main()
{
	test01();
	system("pause");
	return 0;
}

五、vector 插入与删除 

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void printVec(vector<int> &v)
{
	for (vector<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	vector<int> v1;
	v1.push_back(1);  //尾部添加元素
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(3);
	printVec(v1);

	v1.pop_back();    //尾部删除元素
	printVec(v1);

	v1.insert(v1.begin(), 100);      //插入元素100
	printVec(v1);

	v1.insert(v1.begin(), 5, 100);   //插入5个元素100
	printVec(v1);

	v1.erase(v1.begin());    //删除元素
	printVec(v1);

	v1.clear();				 //清空容器
	printVec(v1);
}

int main()
{
	test01();
	system("pause");
	return 0;
}

注意:

使用 erase() 函数删除元素后,原来的迭代器会失效,因此在删除元素后继续使用失效的迭代器是不安全的。如果需要在遍历 std::vector 的同时删除元素,应使用更为安全的方式,例如使用迭代器的后置递增运算符来避免迭代器失效,如下:

std::vector<int> vec = { 1, 2, 3, 4, 5 };
for (auto it = vec.begin(); it != vec.end(); /* 迭代器更新放在循环体内 */) 
{
	if (*it == 1) 
	{
		it = vec.erase(it);  // 删除满足条件的元素,并将迭代器指向下一个元素
	}
	else 
	{
		++it;  // 迭代器递增
	}
}

六、vector 数据获取 

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void test01()
{
	vector<int> v1 = { 1, 2, 3, 4, 5, 6 };
	cout << "v1.at(0) = " << v1.at(0) << endl;
	cout << "v1[0] = " << v1[0] << endl;
	cout << "v1.front() = " << v1.front() << endl;
	cout << "v1.back() = " << v1.back() << endl;
}

int main()
{
	test01();
	system("pause");
	return 0;
}

七、vector 互换 

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void printVec(vector<int> &v)
{
	for (vector<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	vector<int> v1 = { 1, 2, 3, 4, 5, 6 };
	vector<int> v2 = { 6, 5, 4, 3, 2, 1 };
   
    v1.swap(v2);   //互换v1与v2中的元素
    printVec(v1);
    printVec(v2);
}

int main()
{
	test01();
	system("pause");
	return 0;
}

八、vector 预留空间 

描述:减少vector在动态扩展容量时的扩展次数

示例:

#include <iostream>
#include <vector>     //必须包含该头文件
using namespace std;

void printVec(vector<int> &v)
{
	for (vector<int>::iterator At = v.begin(); At != v.end(); At++)
	{
		cout << *At << " ";
	}
	cout << endl;
}

void test01()
{
	vector<int> v1 = { 1, 2, 3, 4, 5, 6 };
	v1.reserve(100);

	printVec(v1);
	cout << "v1.size() = "  << v1.size() << endl;
	cout << "v1.capacity() = " << v1.capacity() << endl;
}

int main()
{
	test01();
	system("pause");
	return 0;
}

注意:

在 C++ 中,std::vector 类提供了 reserve() 和 resize() 两个函数,用于调整 std::vector 的容量和大小。它们的区别如下:

reserve() 函数用于预留 std::vector 的容量,即为 std::vector 分配内存空间,但不会改变 std::vector 的大小。可以通过 reserve() 提前分配足够的内存空间,以减少插入元素时的内存重新分配次数,提高性能。调用 reserve() 后,std::vector 的容量将大于或等于指定的值,但实际大小仍然为 0。例如:
std::vector<int> vec;
vec.reserve(10);  // 预留容量为 10

std::vector<int> vec;
vec.reserve(10);  // 预留容量为 10


resize() 函数用于改变 std::vector 的大小,即调整 std::vector 中元素的个数。当指定的大小大于当前大小时,将在末尾插入新的元素;当指定的大小小于当前大小时,将删除末尾的元素。如果在扩大 std::vector 大小时,新添加的元素将使用默认构造函数进行初始化。例如:
std::vector<int> vec;
vec.resize(5);  // 将 vec 的大小调整为 5,新增的元素值为 0

std::vector<int> vec;
vec.resize(5);  // 将 vec 的大小调整为 5,新增的元素值为 0


需要注意的是,resize() 函数可能会导致元素的构造和析构操作,因此在调整大小时要谨慎考虑性能开销。

综上所述,reserve() 函数用于预留容量,而 resize() 函数用于调整大小。reserve() 不会改变 std::vector 的大小,而 resize() 会改变 std::vector 的大小,并可能触发元素的构造和析构操作。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小火球2.0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值