C++中的几种数组:array,vector,valarray
2021/7/8 11:09:16
本文主要是介绍C++中的几种数组:array,vector,valarray,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1. 内置数组(C语言风格数组)
数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。c++内置的原生数组可以存储一个固定大小的相同类型元素的顺序集合,并且其中的特定元素可以通过索引访问。它由连续的内存位置组成,最低的地址对应第一个元素,最高的地址对应最后一个元素。声明格式如下:
type arrayName [ arraySize ];
定义和初始化 :
// 默认初始化 int arr[5]; // 创建包含5个int型整数的数组,未被初始化 int arr[5] = {}; //创建并初始化5个值为0的int型元素 // 列表初始化 int arr[5] = {1, 2, 3}; // 显式的初始化数组的前三个元素,剩下的元素默认初始化为0 int arr[5] = {1, 2, 3, 4, 5 }; int arr[] = {1, 2, 3, 4, 5 }; // 等同于上
特点:
- 数组大小固定,速度较快;
- 数组初始化不能直接使用拷贝和赋值,数组的传递只能以遍历的形式来拷贝。
2. array
array是c++11中引入的一个数组模板 ,是一种固定大小的容器类型,在定义的时候需要指定元素的类型和个数。array是一种更容易使用,更加安全的数组类型,可以用来替代内置数组。与内置的数组相比, array类模版支持几乎所有内置数组包含的特性,并且融入了很多容器操作,使得array在使用和性能上都要强于内置数组。声明格式如下:
array<typeName, arraySize> arrayName;
定义和初始化 :
// 默认初始化 array<int, 5> arr //创建具有5个int型元素的array<>,但未被初始化 array<int, 5> arr = {}; //创建并初始化5个值为0的int型元素 // 列表初始化 array<int, 5> arr = {1, 2, 3 }; //显式的初始化数组的前三个元素,剩下的元素默认初始化为0 array<int, 5> arr = {1, 2, 3, 4, 5 };
特点:
- 数组大小固定,速度较快,但是和内置数组一样,不能增加和删除数组中元素;
- 可以使用拷贝和赋值;
- 可以使用迭代器;
- 用内置数组时,数组被衰减为指针的风险更大,而array类不会衰减为指针;
- Array类通常比内置数组更有效,更轻量且更可靠;
操作:
at()
:用来访问array数组中的元素;get()
:也是用来访问array数组中的元素,不过该函数并不属于array类,而是重载tuple类;operator[]
:类似于内置数组中的访问方式,也是用来访问array数组中的元素;
array<int,6> ar = {1, 2, 3, 4, 5, 6}; // 使用at()打印数组 for ( int i=0; i<6; i++) cout << ar.at(i) << " "; // 使用get()打印数组 cout << get<0>(ar) << " " << get<1>(ar) << " "; cout << get<2>(ar) << " " << get<3>(ar) << " "; cout << get<4>(ar) << " " << get<5>(ar) << " "; // 使用operator[]打印数组 for ( int i=0; i<6; i++) cout << ar[i] << " ";
front()
:返回array数组的第一个元素;back()
:返回array数组的最后一个元素;
array<int,6> ar = {1, 2, 3, 4, 5, 6}; // 打印数组的第一个元素 cout << ar.front() << endl; // 打印数组的最后一个元素 cout << ar.back() << endl;
size()
:返回array数组的长度;max_size()
:返回array数组可以容纳的最大元素数。size()和max_size()是一样大的;
array<int,6> ar = {1, 2, 3, 4, 5, 6}; // 打印数组中元素的数量 cout << ar.size() << endl; // 打印数组所能存放的元素的最大数目 cout << ar.max_size() << endl;
swap()
:和目标数组交换本数组中的所有元素
array<int,6> ar = {1, 2, 3, 4, 5, 6}; array<int,6> ar1 = {7, 8, 9, 10, 11, 12}; // 将ar1的值与ar交换 ar.swap(ar1);
empty()
:当数组大小为零时,此函数返回true,否则返回false;fill()
:用指定的值填充整个array数组。
array<int,6> ar; array<int,0> ar1; // 检查ar1的长度是否为空 ar1.empty()? cout << "Array empty": cout << "Array not empty"; // 用0填充 ar ar.fill(0);
3. vector
vector 是一种序列容器,可以看作是可变长的动态数组,支持随机访问迭代器,所有 STL算法都能对 vector 进行操作。创建vector变量时会自动在内存中分配一块连续的内存空间来保存数据,初始内存空间大小可以预先指定,也可以由vector默认指定大小。当存储的数据超过分配的空间时,vector会重新分配一块内存,但是这样的分配很耗时,步骤如下:
- vector 会申请一块更大的内存块;
- 将原来的数据拷贝到新的内存块中;
- 销毁掉原内存块中的对象(调用对象的析构函数);
- 将原来的内存空间释放掉。
在vector中,数据插入到最后。 在末尾插入需要花费不同的时间,因为有时可能需要扩展空间。删除最后一个元素需要的时间固定,因为不会发生大小调整。在开始或中间插入和删除元素的时间是线性的。
vector的声明格式如下:
vector<typename> arrayName; vector<typename> arrayname[arraySize];
定义和初始化:
// 默认初始化 vector<int> arr; //创建一个包含int类型的空vector数组 vector<int> arr[5]; //创建一个包含5个int型元素的vector数组,未被初始化 vector<int> arr(5); //创建一个vector数组并缺省初始化5个元素为0 vector<int> arr(5, 0); //创建一个vector数组并初始化5个元素为0 // 列表初始化 vector<int> arr{1, 2, 3, 4, 5 }; vector<int> arr = {1, 2, 3, 4, 5 };
特点:
- vector 像内置数组一样连续存储,但空间可以动态扩展。即它可以像内置数组一样被操作,通过[]符号;
- 随机访问方便,它像内置数组一样被访问,支持[ ] 操作符和vector.at();
- 节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的;
- 在内部进行插入、删除操作效率非常低,这样的操作基本上是被禁止的。Vector 被设计成只能在后端进行追加和删除操作,其原因是vector 内部的实现是按照顺序表的原理,即只能在vector 的最后进行push 和pop ,不能在vector 的头进行push 和pop ;
- 当动态添加的数据超过vector 默认分配的大小时要进行内存的重新分配、拷贝与释放,这个操作非常消耗性能。 所以要vector 达到最优的性能,最好在创建vector 时就指定其空间大小。
操作:
size()
:返回容器中的元素个数;max_size()
:返回vector可以容纳的最大的元素数量,一般来说这个数非常大;capacity()
:返回当前分配给vector的存储空间的大小,以元素数表示;resize(n)
:调整size()的大小,使其包含n个元素(size);empty()
:返回容器是否为空;shrink_to_fit()
:降低容器的容量以适应其大小,并销毁超出容量的所有元素(capacity);reserve()
:请求容器容量至少足以包含n个元素(capacity)。
#include <iostream> #include <vector> using namespace std; int main() { vector<int> g1; for (int i = 1; i <= 5; i++) g1.push_back(i); cout << "Size : " << g1.size(); cout << "\nCapacity : " << g1.capacity(); cout << "\nMax_Size : " << g1.max_size(); // resizes the vector size to 4 g1.resize(4); // prints the vector size after resize() cout << "\nSize : " << g1.size(); // checks if the vector is empty or not if (g1.empty() == false) cout << "\nVector is not empty"; else cout << "\nVector is empty"; // Shrinks the vector g1.shrink_to_fit(); cout << "\nVector elements are: "; for (auto it = g1.begin(); it != g1.end(); it++) cout << *it << " "; return 0; }
operator []
:用来访问vector中的元素;at()
:用来访问vector中的元素;front()
:返回vector中的第一个元素;back()
:返回vector中的最后一个元素;data()
:返回指向向量内部使用的存储数组的直接指针,以存储其拥有的元素;
#include <bits/stdc++.h> using namespace std; int main() { vector<int> g1; for (int i = 1; i <= 10; i++) g1.push_back(i * 10); cout << "\nReference operator [g] : g1[2] = " << g1[2]; cout << "\nat : g1.at(4) = " << g1.at(4); cout << "\nfront() : g1.front() = " << g1.front(); cout << "\nback() : g1.back() = " << g1.back(); // pointer to the first element int* pos = g1.data(); cout << "\nThe first element is " << *pos; return 0; }
assign()
:通过替换旧元素为vector分配新值;push_back()
:从vector末端插入一个新的元素;pop_back()
:从vector末端弹出一个元素;insert()
:在指定位置的元素之前插入新元素,需调用类的构造函数和拷贝构造函数(先构造,再移动);erase()
:它用于从指定位置或范围中删除容器中的元素;swap()
:它用于将一个向量的内容与另一个相同类型的向量交换。大小可能有所不同;clear()
:用于删除容器中的所有元素;emplace()
:在指定位置的元素之前插入新元素。和insert()不同的是,emplace 最大的作用是避免产生不必要的临时变量,直接在指定位置处构造元素,并且emplace() 每次只能插入一个元素,而不是多个;emplace_back()
:用于将新元素插入vector的末尾。
#include <bits/stdc++.h> #include <vector> using namespace std; int main() { // Assign vector vector<int> v; // fill the array with 10 five times v.assign(5, 10); cout << "The vector elements are: "; for (int i = 0; i < v.size(); i++) cout << v[i] << " "; // inserts 15 to the last position v.push_back(15); int n = v.size(); cout << "\nThe last element is: " << v[n - 1]; // removes last element v.pop_back(); // prints the vector cout << "\nThe vector elements are: "; for (int i = 0; i < v.size(); i++) cout << v[i] << " "; // inserts 5 at the beginning v.insert(v.begin(), 5); cout << "\nThe first element is: " << v[0]; // removes the first element v.erase(v.begin()); cout << "\nThe first element is: " << v[0]; // inserts at the beginning v.emplace(v.begin(), 5); cout << "\nThe first element is: " << v[0]; // Inserts 20 at the end v.emplace_back(20); n = v.size(); cout << "\nThe last element is: " << v[n - 1]; // erases the vector v.clear(); cout << "\nVector size after erase(): " << v.size(); // two vector to perform swap vector<int> v1, v2; v1.push_back(1); v1.push_back(2); v2.push_back(3); v2.push_back(4); cout << "\n\nVector 1: "; for (int i = 0; i < v1.size(); i++) cout << v1[i] << " "; cout << "\nVector 2: "; for (int i = 0; i < v2.size(); i++) cout << v2[i] << " "; // Swaps v1 and v2 v1.swap(v2); cout << "\nAfter Swap \nVector 1: "; for (int i = 0; i < v1.size(); i++) cout << v1[i] << " "; cout << "\nVector 2: "; for (int i = 0; i < v2.size(); i++) cout << v2[i] << " "; }
参考:https://blog.csdn.net/ye1223/article/details/79772771
https://www.geeksforgeeks.org/vector-in-cpp-stl/
4. valarray
valarray是一个类模板,面向数值计算,优势是重载了各种数学函数,方便数学计算。
定义与初始化:
valarray<int> arr(5); //创建包含5个int型元素的valarray valarray<int> arr(1, 5); //创建包含5个值为1的元素的int型valarray int a[] = {1, 2, 3, 4, 5 }; valarray<int> arr(a, 5); //创建包含5个int型元素的valarray,初始值为a[]
特点:
- 数组大小固定,速度较快;
- 方便进行数学计算。
操作:
apply()
:将其参数中给出的操作应用于所有valarray元素,并返回具有操作值的新valarray;sum()
:返回valarrays所有元素的总和;
#include<iostream> #include<valarray> // for valarray functions using namespace std; int main() { // Initializing valarray valarray<int> varr = { 10, 2, 20, 1, 30 }; // Declaring new valarray valarray<int> varr1 ; // Using apply() to increment all elements by 5 varr1 = varr.apply([](int x){return x=x+5;}); // Displaying new elements value cout << "The new valarray with manipulated values is : "; for (int &x: varr1) cout << x << " "; cout << endl; // Displaying sum of both old and new valarray cout << "The sum of old valarray is : "; cout << varr.sum() << endl; cout << "The sum of new valarray is : "; cout << varr1.sum() << endl; return 0; }
min()
:返回valarray中最小的元素;max()
:返回valarray中最大的元素;
valarray<int> varr = { 10, 2, 20, 1, 30 }; cout << varr.max() << endl; cout << varr.min() << endl;
shift()
:将元素移动到其参数中的数字后,并返回新的valarray。如果数字为正,则元素左移;如果数字为负,则元素右移;cshift()
:该函数将元素循环移位(旋转)其参数中的数字后,将返回新的valarray。如果数字为正,则元素左循环移位;如果数字为负,则元素右圆周移位;
#include<iostream> #include<valarray> // for valarray functions using namespace std; int main() { // Initializing valarray valarray<int> varr = { 10, 2, 20, 1, 30 }; // Declaring new valarray valarray<int> varr1; // using shift() to shift elements to left // shifts valarray by 2 position varr1 = varr.shift(2); // Displaying elements of valarray after shifting cout << "The new valarray after shifting is : "; for ( int&x : varr1) cout << x << " "; cout << endl; // using cshift() to circulary shift elements to right // rotates valarray by 3 position varr1 = varr.cshift(-3); // Displaying elements of valarray after circular shifting cout << "The new valarray after circular shifting is : "; for ( int&x : varr1) cout << x << " "; cout << endl; return 0; }
swap()
:将valarray与另一个valarray交换。
valarray<int> varr1 = {1, 2, 3, 4}; valarray<int> varr2 = {2, 4, 6, 8}; varr1.swap(varr2);
代码来源:https://www.geeksforgeeks.org/the-c-standard-template-library-stl/
这篇关于C++中的几种数组:array,vector,valarray的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-23DevExpress 怎么实现右键菜单(Context Menu)显示中文?-icode9专业技术文章分享
- 2024-12-22怎么通过控制台去看我的页面渲染的内容在哪个文件中呢-icode9专业技术文章分享
- 2024-12-22el-tabs 组件只被引用了一次,但有时会渲染两次是什么原因?-icode9专业技术文章分享
- 2024-12-22wordpress有哪些好的安全插件?-icode9专业技术文章分享
- 2024-12-22wordpress如何查看系统有哪些cron任务?-icode9专业技术文章分享
- 2024-12-21Svg Sprite Icon教程:轻松入门与应用指南
- 2024-12-20Excel数据导出实战:新手必学的简单教程
- 2024-12-20RBAC的权限实战:新手入门教程
- 2024-12-20Svg Sprite Icon实战:从入门到上手的全面指南
- 2024-12-20LCD1602显示模块详解