C++ array函数

C++ array

1、前要:

数组是固定大小的序列容器:它们包含按严格的线性顺序排列的特定数量的元素。一个array—也就是容器类array<>的一份实体—模塑出一个static array。它包覆一个寻常的statci C-style array 并提供一个STL容器的接口。

通用格式:arrat<类型名,元素个数>数组名;

注意,因为长度固定,这里的元素个数不能是变量。

array成员函数
函数功能
begin(),end(),cbegin(),cend()提供正向迭代器支持
rbegin(),rend(),crbegin(),crend()提供反向迭代器支持
size()返回数组大小
max_size()返回数组最大大小
empty()判断数组是否为空
at(),operator[]获取数组的元素
front()返回数组第一个元素的引用
back()返回数组最后一个元素的引用
data()返回指向数组对象包含的数据的指针
fill()用值填充数组
swap()交换两个数组元素
get(array)返回某一个数组元素的引用

2、成员函数与用法示例

array用法及初始化
template<class T,size_t N> class array;
//T为所包含元素的类型,别名为成员类型value_type.N的数组大小,以元素数表示。

在使用array前,首先需要添加array这个头文件,即 #include****

注意:array<>是唯一一个无任何东西被指定为初值时,会被预初始化的容器。这就意味着对于基础类型,初值可能不明确,而不是0,下面定义一个有110个int元素的数组arr:

std::array<int,110> arr;
//上面定义的arr并未进行初始化。未初始化将会分配随机值,如下图:

请添加图片描述

所以尽量不要定义未初始化的数组,否则访问数组元素,而该元素恰好未初始化时,可能出现意想不到的错误。

//array数组对象初始化与标准初始化一摸一样,如:
std::array<int,110>arr{};//将数组所有元素初始化为0
std::array<int, 110>arr{1,2,3,4};//将数组前四个元素分别初始化为1,2,3,4 其余全部为0
fill()

​ fill()函数可以用指定值给数组中所有元素赋值

fill()函数原型如下:

void fill(const value_type &u);//value_type为数组元素类型

【例子】:

#include <iostream>
#include <array>
using namespace std;

int main(){
    std::array<int, 110> arr{1,2,3,4,5,6,7,8,9};
    arr.fill(3);//用3对数组所有元素赋值
    for (auto i:arr) {
        cout<<i<<" ";
    }
    cout<<endl;
    return 0;
}
array元素的获取
  • array元素的获取可以使用下标 [] (与标准数组用法相同),以及STL容器所持有的at()。

  • []与at()的区别在于,[]不会进行检查数字是否越界,at()会进行检查(时间开销很少),如果越界则抛出std::out_of_rang异常。

  • 因此,除非确定访问没有越界,否则应该尽量使用更安全的at()。

  • #include <iostream>
    #include <array>
    using namespace std;
    
    int main(){
        std::array<int, 110> arr{1,2,3,4,5,6,7,8,9};
        arr.at(9) = arr.at(3) + arr.at(5);
        arr[10] = arr[1] + arr[8];
        cout<<arr.at(9)<<endl;
        cout<<arr[10]<<endl;
    //    arr[11]=6;//越界访问,程序异常,但Qt creator并未报错
        arr.at(11) = 6;//异常
        cout<<arr.at(11)<<endl;
        return 0;
    }
    
front()和back()

​ front() 返回数组第一个元素的引用

​ back()返回数组最后一个元素的引用

#include <iostream>
#include <array>
using namespace std;

int main(){
    std::array<int, 11> arr{1,2,3,4,5,6,7,8,9};
    arr.front() = 666;
    arr.back() = 666;
    for(auto i:arr){
        cout<<i<<" ";
    }
    cout<<endl;
    return 0;
}

程序运行结果:

666 2 3 4 5 6 7 8 9 0 666

data()

​ 返回指向数组对象中第一个元素的指针,该元素无参数

#include <iostream>
#include<cstring>
#include <array>
using namespace std;

int main(){
    std::array<int, 10> arr{1,2,3,4,5,6,7,8,9};
    
    cout << *arr.data()<<endl;
    cout << *(arr.data()+6)<<endl;
    
    const char *str = "Test string";
    std::array<char, 12> charray;
    std::memcpy(charray.data(), str, charray.size());
    
    cout << charray.data() << endl;
    return 0;
}

程序运行结果为:

1

7

Test string

size() 和 max_size()

​ 由于array在创建的时候必须明确指定大小,而且array为固定容器,因此size()与max_size()的返回值是相同的,通常使用size()函数。

返回值类型size_t即无符号整数。

使用size()可以有效避免使用for遍历数组时,发生越界的情况。同时它也使得你在写程序的时候,不必去花心思记忆数组大小。

std::array<int , 1o> arr{1,2,3,4,5,6,7,8,9,10};

for(unsigned int i(0);i < arr.size();i++){
		cout<<arr[i]<<" ";
cout << endl;
}
empty()

该函数在array中为鸡肋函数,因为array在定义的时候已经指明了大小,不可能为空。

Tuple接口

array提供tuple接口。因此可以使用表达式tuple_size<>::value取得元素个数,用tuple_element<>::type取得特定元素的类型,用get<>()取得某特定元素。

get()

get()函数为非成员函数重载。

该函数返回array中指定元素的引用。

函数原型如下:

template <size_t I,class T , size_t N>T & get(array<T, N>& arr)noexcept;
template <size_t I,class T , size_t N>T && get(array<T, N>&& arr)noexcept;
template <size_t I,class T , size_t N>const T & get(const array<T, N>& arr)noexcept;
//参数I为:元素在数组中的位置,第一个元素的位置为0.
//参数T为:数组中包含的元素模型(通常从arr隐式获取)。
//参数N为:数组的大小,以元素数为单位(通常从arr隐式中获得)。
//由于参数T、N可以从arr中隐式中获取,所以使用的时候不显示指定二者。
/*
		注意参数I必须明确为数字,不能使用变量,下面为错误用例
*/
int n = 3;
std::get<n>(arr);

例如

#include<cstring>
#include <array>
using namespace std;

int main(){
    std::array<int, 10 > arr{1,2,3,4,5,6,7,8,9,10};
    int a = std::get<6>(arr);
    cout<<a<<endl;
    
    std::get<5>(arr) = 666;
    for (auto i : arr) {
        cout<<i<<" ";
    }
    cout<<endl;
    return 0;
}

程序运行结果如下:

7

1 2 3 4 5 666 7 8 9 10

tuple_size ::value 、、tuple<i,tupleType>::type

在array中用途不大,示例如下:

#include <iostream>
#include<cstring>
#include <array>
using namespace std;

int main(){
    std::array<string, 5> arr = {"one","two","three","four","five"};
    //返回元素的个数,或者说是元组的长度
    cout<<std::tuple_size<decltype(arr)>::value<<endl;
    
    
    //type为array第二个成员变量类型,string型
    std::tuple_element<1,decltype(arr)>::type type;
    type = get<1>(arr);
    cout<<type<<endl;
    
    return 0;
    
}

/*
	补充decltype相关的知识:
	(1)decltype含义和举例:用于推导类型
*	1 decltype对于给定的变量名或者表达式,decltype能够告诉你该名字或者表达式的类型
*		从表达式的类型推断出要定义的变量类型,并且不想初始化变量--使用decltype
*		decltype说明符:主要作用:返回操作数的数据类型
*
*		decltype的特点:
*			1.decltype的自动类型推断会发生在编译期间
*			2.decltype不会真正计算表达式的值
*	1.1decltype后的圆括号是个变量
*	1.2decltype后的圆括号是个不是个变量,表达式。返回表达式结果对应类型
*	1.3decltype后的圆括号是个函数--返回值是函数返回值类型
*
/
array元素的修改

array元素的修改与标准数组用法几乎相同,如:

std::array<int , 10> arr{1,2,3,4,5,6,7,8,9,10};
arr[3] = 6;
arr[2] = arr[0] + arr[1];

同样可以使用指针,引用对其进行修改。

不同于标准数组的是,只要array类型的数组的数据类型和数组长度都相同的话,可以直接用数组B的值覆盖数组A的值,“=”。

#include <iostream>
#include<cstring>
#include <array>
using namespace std;

int main(){
    std::array<int , 3> arr_1{1,2,3};
    std::array<int, 3> arr_2{4,5,6};
    
    arr_2 = arr_1;//用arr_1的元素覆盖arr_2的元素
    
    for (auto i : arr_1) {
        cout<<i<<" ";
    }
    cout<<endl;
    
    for (auto i : arr_1) {
        cout<<i<<" ";
    }
    cout<<endl;
    
    return 0;
    
}

程序运行结果为:

1 2 3

1 2 3

swap()

交换两个array的值,注意:这两个数组的大小和数据类型必须相同。

无返回值,无参数。线性操作(效率较低)

#include <iostream>
#include<cstring>
#include <array>
using namespace std;

int main(){
    std::array<int , 10> arr_1{1,2,3,4,5,6,7,8,9,10};
    std::array<int, 10> arr_2{0,0,0,0,0,0,0,0,0,1};
    
    arr_1.swap(arr_2);
    for (auto i : arr_1) {
            cout<<i<<" ";
        }
        cout<<endl;
        
        for (auto i : arr_2) {
            cout<<i<<" ";
        }
        cout<<endl;
        
        return 0;
}

程序运行结果如下:

0 0 0 0 0 0 0 0 0 1

1 2 3 4 5 6 7 8 9 10

array迭代器
名称功能
begin()返回指向数组第一个元素的迭代器
end()返回指向数组最后一个元素后紧跟的理论元素迭代器
cbegin()返回指向数组第一个元素的const类型迭代器
cend()返回指向数组最后一个元素后紧跟的理论元素的const类型迭代器
rbegin()返回一个反向的迭代器,该迭代器指向数组的最后一个元素
rend()返回一个反向迭代器,该迭代器指向数组第一个元素之前的理论元素
crbegin()返回一个const类型反向迭代器,该迭代器指向数组最后一个一个元素
crend()返回一个const类型反向迭代器,该迭代器指向数组第一个元素之前的理论元素
下面为数组迭代器的简单用法:
#include <iostream>
#include <array>
using namespace std;

int main(){
    std::array<int, 10> arr{1,2,3,4,5,6,7,8,9,10};
    
    array<int, 10>::iterator it_beg = arr.begin();
    array<int, 10>::reverse_iterator rit_beg = arr.rbegin();
    
    for (; it_beg!=arr.end(); it_beg++) {
        cout<<*it_beg*2<<" "; //二倍输出
    }
    cout<<endl;
    
    for (; rit_beg!=arr.rend(); rit_beg++) {
        cout<<*rit_beg<<" ";//倒序输出数组元素
    }
    cout<<endl;
    
    return 0;
}

在使用时最好使用全局的begin()和end()函数从容器中获取迭代器,因为它们是通用的。

如上述array<int, 10>::iterator it_beg = arr.begin();可以改为一下语句

array<int, 10>::iterator it_beg = std::arr.begin();

array元素的比较

可以用任何比较运算符比较两个数组容器,只要它们有相同的大小,保存的是相同的元素,而且这种类型的元素还要支持比较运算符。示例如下:

#include <iostream>
#include <array>
using namespace std;

int main(){
    std::array<int, 3 >arr_1{1,2,3};
    std::array<int, 3>arr_2{1,2,3};
    std::array<int, 3> arr_3{1,3,2};
    
    if (arr_1 == arr_2) {
        cout<<"arr_1 = arr_2"<<endl;
    }
    
    if (arr_1!=arr_3) {
        cout<<"arr_1!=arr_3"<<endl;
    }
    
    if (arr_1 < arr_3) {
        cout << "arr_1 < arr_3" << endl;
    }
    
    return 0;
}

代码运行结果如下:

arr_1 = arr_2

arr_1!=arr_3

arr_1 < arr_3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值