C++——三种数组(array、vector、valarry)

1、内置数组

        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 }; // 等同于上

int a[]={1,2,3};    
int a2[]=a;            //错误
a2=a;                //错误

特点:

  • 数组大小固定,速度快;
  • 数组初始化不能直接使用拷贝和赋值,数组的传递只能以遍历的形式来拷贝;

2、array

       C++11引入的一个数组模板,固定大小的容器类型,定义时需指定元素类型和个数,arry更易使用,更安全,用来替代内置数组,与内置的数组相比, 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数组中的元素;
  • front() :返回array数组的第一个元素;
  • back():返回array数组的最后一个元素;
  • size():返回array数组的长度;
  • max_size():返回array数组可以容纳的最大元素数。size()和max_size()是一样大的;
  • swap():和目标数组交换本数组中的所有元素;
  • empty():当数组大小为零时,此函数返回true,否则返回false;
  • fill():用指定的值填充整个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] << " "; 
    
     
    // 打印数组的第一个元素  
    cout << ar.front() << endl; 
     
    // 打印数组的最后一个元素
    cout << ar.back() << endl; 
    
     
    // 打印数组中元素的数量
    cout << ar.size() << endl; 
     
    // 打印数组所能存放的元素的最大数目
    cout << ar.max_size() << endl; 
     
     
    // 将ar1的值与ar交换
    array<int,6> ar1 = {7, 8, 9, 10, 11, 12}; 
    ar.swap(ar1); 
     
    // 检查ar1的长度是否为空 
    array<int,6> ar; 
    array<int,0> 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<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);
  • operator [] :用来访问vector中的元素;
  • at():用来访问vector中的元素;
  • front():返回vector中的第一个元素;
  • back():返回vector中的最后一个元素;
  • data():返回指向向量内部使用的存储数组的直接指针,以存储其拥有的元素;
  • assign():通过替换旧元素为vector分配新值;
  • push_back():从vector末端插入一个新的元素;
  • pop_back():从vector末端弹出一个元素;
  • insert():在指定位置的元素之前插入新元素,需调用类的构造函数和拷贝构造函数(先构造,再移动);
  • erase():它用于从指定位置或范围中删除容器中的元素;
  • swap():它用于将一个向量的内容与另一个相同类型的向量交换。大小可能有所不同;
  • clear():用于删除容器中的所有元素;
  • emplace():在指定位置的元素之前插入新元素。和imsert()不同的是,emplace 最大的作用是避免产生不必要的临时变量,直接在指定位置处构造元素,并且emplace() 每次只能插入一个元素,而不是多个;
  • emplace_back():用于将新元素插入vector的末尾。
    #include <iostream> 
    #include <vector> 
      
    using namespace std; 
      
    int main() 
    { 
        vector<int> g1;   //定义一个int型动态数组
      
        for (int i = 1; i <= 5; i++) 
            g1.push_back(i);    //末端插入
      
        cout << "Size : " << g1.size();   //元素个数   5
        cout << "Capacity : " << g1.capacity();  //存储空间大小  6(通常比元素个数大一点)
        cout << "Max_Size : " << g1.max_size();  // 容纳最大的元素数量 4611686018427387903
     
        g1.resize(4);      //调整sixe()大小
        cout << "\nSize : " << g1.size();    //4
     
        if (g1.empty() == false)                 //判断是否为空
            cout << "\nVector is not empty"; 
        else
            cout << "\nVector is empty"; 
    
        g1.shrink_to_fit();    //降低容器的容量以适应其大小,并销毁超出容量的所有元素(capacity);
        cout << "\nVector elements are: "; 
        for (auto it = g1.begin(); it != g1.end(); it++) 
            cout << *it << " "; 
      
        cout << "\nat : g1.at(4) = " << g1.at(4);   //访问第5个元素
       
        cout << "\nfront() : g1.front() = " << g1.front();   //首元素
      
        cout << "\nback() : g1.back() = " << g1.back();    //尾元素
    
        int* pos = g1.data(); 
        cout << "\nThe first element is " << *pos; 
        
        // 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] << " "; 
        
       return 0; 
    } 
    

    5、valarry

        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所有元素的总和;
  • min():返回valarray中最小的元素;
  • max():返回valarray中最大的元素;
  • shift():将元素移动到其参数中的数字后,并返回新的valarray。如果数字为正,则元素左移;如果数字为负,则元素右移;
  • cshift():该函数将元素循环移位(旋转)其参数中的数字后,将返回新的valarray。如果数字为正,则元素左循环移位;如果数字为负,则元素右圆周移位;
  • swap():将valarray与另一个valarray交换;
  • #include<iostream> 
    #include<valarray> // for valarray functions 
    using namespace std; 
    int main() 
    { 
        // Initializing valarray 
        valarray<int> varr = { 10, 2, 20, 1, 30 }; 
        cout << varr.max() << endl; 
        cout << varr.min() << endl; 
          
        // Declaring new valarray 
        valarray<int> varr1 ; 
       
         // using shift() to shift elements to left 
        // shifts valarray by 2 position 
        varr1 = varr.shift(2); 
        
        // using cshift() to circulary shift elements to right 
        // rotates valarray by 3 position 
        varr1 = varr.cshift(-3); 
    
        // 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 << " "; 
        
        //swap
        valarray<int> varr2 = {2, 4, 6, 8}; 
        varr1.swap(varr2); 
        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; 
    } 
    

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值