资讯动态

顺序容器:Array 数组 详解

发布时间:2026/8/7 17:03:13 来源:尧图企业网站定制
目录前言一、Array 数组特点二、定义及初始化1.定义 array 对象2.初始化方式三、向 array 对象中添加或删除元素1.修改元素四、array 常用迭代器五、array 常用运算符六、array 常用成员函数1.at 成员函数2.empty 成员函数3.size 成员函数4.front 成员函数5.back 成员函数6.fill 成员函数7.swap 成员函数七、array 与原生数组的比较1.优势2.劣势3.示例array 与原生数组的对比八、综合练习1.练习 1array 基本操作2.练习 2使用 array 存储自定义类型前言C11标准库中的array容器是一种固定大小的顺序容器具有连续存储、高效性能和类型安全等特点。它定义在array头文件中大小在编译时确定不能动态调整。array支持多种初始化方式默认、列表、聚合、拷贝提供丰富的迭代器类型正向、反向、常量和成员函数at、empty、size、front、back、fill、swap。相比原生数组array具有类型安全、边界检查等优势但大小固定。文章详细介绍了array的定义、初始化、元素修改、迭代器使用、运算符重载以及与原生数组的比较并提供了两个综合练习示例。一、Array 数组特点array是 C11 引入的标准库容器定义在array头文件中位于std命名空间内。它是一种固定大小的顺序容器具有以下特点固定大小在编译时确定大小不能动态扩容或缩容连续存储元素在内存中连续存储支持快速随机访问高效性能性能与原生数组相当同时提供了更多的成员函数和安全检查与 STL 兼容可以使用 STL 算法和迭代器类型安全提供了类型安全的接口避免了原生数组的一些问题它是有着固定大小用于保存一系列同类型元素的顺序容器。因此不能对它进行增加或者删除,只能使用或者替换它的元素值。二、定义及初始化1.定义 array 对象使用array,必须包含头文件array#include array //使用array,在std命名空间该类型被定义为一个类模板,在std命名空间中。templateclass T, std::size_t N class array;#include array // 定义一个包含 5 个 int 元素的 array std::arrayint, 5 arr; // 定义一个包含 3 个 std::string 元素的 array std::arraystd::string, 3 strArr;2.初始化方式默认初始化值初始化对于内置类型初始化为 0 或空std::arrayint, 5 arr; // 所有元素初始化为 0 std::arraystd::string, 3 strArr; // 所有元素初始化为空字符串列表初始化std::arrayint, 5 arr {1, 2, 3, 4, 5}; std::arrayint, 5 arr2{1, 2, 3, 4, 5}; // 与上面等价聚合初始化std::arrayint, 5 arr {1, 2, 3}; // 前三个元素初始化为 1, 2, 3其余元素初始化为 0拷贝初始化std::arrayint, 5 arr1 {1, 2, 3, 4, 5}; std::arrayint, 5 arr2 arr1; // 拷贝初始化 std::arrayint, 5 arr3(arr1); // 拷贝构造三、向 array 对象中添加或删除元素由于array是固定大小的容器因此不能像vector那样动态添加或删除元素。所有元素的存储空间在编译时就已经分配好了。1.修改元素虽然不能添加或删除元素但可以修改现有元素的值#include array std::arrayint, 5 arr {1, 2, 3, 4, 5}; // 通过下标修改元素 arr[0] 10; arr[1] 20; // 通过 at() 成员函数修改元素 arr.at(2) 30; // 通过迭代器修改元素 auto it arr.begin(); *it 100; it; *it 200;四、array 常用迭代器array容器提供了多种迭代器类型用于遍历容器中的元素迭代器含义a.begin()第一个元素的迭代器a.end()最后一个元素的下一个位置迭代器(尾后迭代器或尾迭代器)a.cbegin()第一个元素的常量迭代器(不修改元素内容)a.cend()尾后常量迭代器(不修改元素内容)a.rbegin()从后往前的第一个迭代器a.rend()从后往前的最后一个迭代器使用示例std::arrayint, 5 arr {1, 2, 3, 4, 5}; // 使用正向迭代器遍历 for (auto it arr.begin(); it ! arr.end(); it) { std::cout *it ; // 输出: 1 2 3 4 5 } std::cout std::endl; // 使用反向迭代器遍历 for (auto it arr.rbegin(); it ! arr.rend(); it) { std::cout *it ; // 输出: 5 4 3 2 1 } std::cout std::endl; // 使用常量迭代器遍历不能修改元素 for (auto it arr.cbegin(); it ! arr.cend(); it) { std::cout *it ; // 输出: 1 2 3 4 5 // *it 10; // 错误常量迭代器不能修改元素 } std::cout std::endl;五、array 常用运算符array类重载了多种运算符方便容器操作赋值运算符将一个 array 赋值给另一个 array要求大小相同std::arrayint, 5 arr1 {1, 2, 3, 4, 5}; std::arrayint, 5 arr2; arr2 arr1; // arr2 现在包含 {1, 2, 3, 4, 5}比较运算符判断两个 array 是否相等!判断两个 array 是否不相等判断一个 array 是否小于另一个 array字典序判断一个 array 是否小于或等于另一个 array判断一个 array 是否大于另一个 array判断一个 array 是否大于或等于另一个 arraystd::arrayint, 3 arr1 {1, 2, 3}; std::arrayint, 3 arr2 {1, 2, 4}; bool b1 (arr1 arr2); // false bool b2 (arr1 arr2); // true第三个元素 3 4下标运算符[]访问指定位置的元素不进行边界检查std::arrayint, 5 arr {10, 20, 30, 40, 50}; int x arr[0]; // x 10 arr[1] 25; // arr 现在包含 {10, 25, 30, 40, 50}六、array 常用成员函数array的成员函数含义a.at()访问指定位置的元素a.empty()判断a是否为空,只能测试长度为0(不重要)a.size()返回数组长度a.front()返回第一个元素的引用a.back()返回最后一个元素的引用a.fill(val)将val赋值给每个元素a.swap()交换两个array的值1.at 成员函数功能访问指定位置的元素进行边界检查参数元素的索引位置返回值指定位置的元素的引用异常如果索引超出范围抛出out_of_range异常std::arrayint, 5 arr {10, 20, 30, 40, 50}; int x arr.at(0); // x 10 arr.at(1) 25; // arr 现在包含 {10, 25, 30, 40, 50} try { x arr.at(10); // 抛出 out_of_range 异常 } catch (const std::out_of_range e) { std::cout Exception: e.what() std::endl; }2.empty 成员函数功能判断 array 是否为空参数无返回值如果 array 为空返回true否则返回false说明对于非空大小的 array始终返回falsestd::arrayint, 0 emptyArr; // 空 array std::arrayint, 5 nonEmptyArr {1, 2, 3, 4, 5}; std::cout emptyArr.empty(); // 输出: 1 (true) std::cout nonEmptyArr.empty(); // 输出: 0 (false)3.size 成员函数功能返回 array 中元素的个数参数无返回值元素个数类型为size_t说明返回的是编译时确定的大小与初始化时的大小相同std::arrayint, 5 arr {1, 2, 3, 4, 5}; std::cout arr.size(); // 输出: 5 std::arraydouble, 10 dblArr; std::cout dblArr.size(); // 输出: 104.front 成员函数功能返回 array 中第一个元素的引用参数无返回值第一个元素的引用说明如果 array 为空行为未定义std::arrayint, 5 arr {1, 2, 3, 4, 5}; std::cout arr.front(); // 输出: 1 arr.front() 10; // arr 现在包含 {10, 2, 3, 4, 5}5.back 成员函数功能返回 array 中最后一个元素的引用参数无返回值最后一个元素的引用说明如果 array 为空行为未定义std::arrayint, 5 arr {1, 2, 3, 4, 5}; std::cout arr.back(); // 输出: 5 arr.back() 50; // arr 现在包含 {1, 2, 3, 4, 50}6.fill 成员函数功能用指定值填充 array 中的所有元素参数要填充的值返回值无std::arrayint, 5 arr {1, 2, 3, 4, 5}; arr.fill(0); // arr 现在包含 {0, 0, 0, 0, 0} std::arraystd::string, 3 strArr; strArr.fill(hello); // strArr 现在包含 {hello, hello, hello}7.swap 成员函数功能交换两个 array 的内容参数另一个 array 对象必须与当前 array 大小相同返回值无std::arrayint, 3 arr1 {1, 2, 3}; std::arrayint, 3 arr2 {4, 5, 6}; arr1.swap(arr2); // arr1 现在包含 {4, 5, 6}arr2 现在包含 {1, 2, 3}七、array 与原生数组的比较1.优势类型安全array是一个模板类提供了类型安全的接口边界检查at()成员函数提供了边界检查STL 兼容可以使用 STL 算法和迭代器大小信息通过size()成员函数可以获取大小赋值操作支持直接赋值而原生数组不支持2.劣势大小固定编译时确定大小不能动态调整稍微的性能开销相比原生数组有轻微的性能开销通常可以忽略3.示例array 与原生数组的对比#include iostream #include array #include algorithm int main() { // 原生数组 int nativeArr[5] {5, 2, 8, 1, 9}; // array 容器 std::arrayint, 5 arr {5, 2, 8, 1, 9}; // 原生数组的大小需要使用 sizeof 计算 std::cout Native array size: sizeof(nativeArr) / sizeof(nativeArr[0]) std::endl; // array 容器直接通过 size() 获取大小 std::cout Array container size: arr.size() std::endl; // 原生数组不能直接赋值 // int anotherNativeArr[5]; // anotherNativeArr nativeArr; // 错误 // array 容器可以直接赋值 std::arrayint, 5 anotherArr; anotherArr arr; // 都可以使用范围 for 循环 std::cout Native array elements: ; for (int x : nativeArr) { std::cout x ; } std::cout std::endl; std::cout Array container elements: ; for (int x : arr) { std::cout x ; } std::cout std::endl; // 都可以使用 STL 算法 std::sort(nativeArr, nativeArr 5); std::sort(arr.begin(), arr.end()); std::cout Sorted native array: ; for (int x : nativeArr) { std::cout x ; } std::cout std::endl; std::cout Sorted array container: ; for (int x : arr) { std::cout x ; } std::cout std::endl; return 0; }八、综合练习1.练习 1array 基本操作#include iostream #include array int main() { // 创建并初始化 array std::arrayint, 5 arr {1, 2, 3, 4, 5}; // 输出原始 array std::cout Original array: ; for (int x : arr) { std::cout x ; } std::cout std::endl; // 修改元素 arr[0] 10; arr.at(1) 20; arr.back() 50; // 输出修改后的 array std::cout Modified array: ; for (int x : arr) { std::cout x ; } std::cout std::endl; // 使用 fill 填充 arr.fill(99); // 输出填充后的 array std::cout After fill: ; for (int x : arr) { std::cout x ; } std::cout std::endl; // 创建另一个 array 并交换 std::arrayint, 5 arr2 {100, 200, 300, 400, 500}; arr.swap(arr2); // 输出交换后的 array std::cout After swap - arr: ; for (int x : arr) { std::cout x ; } std::cout std::endl; std::cout After swap - arr2: ; for (int x : arr2) { std::cout x ; } std::cout std::endl; // 输出 array 信息 std::cout Size: arr.size() std::endl; std::cout Empty: (arr.empty() ? Yes : No) std::endl; std::cout Front: arr.front() std::endl; std::cout Back: arr.back() std::endl; return 0; }2.练习 2使用 array 存储自定义类型#include iostream #include array #include string class Person { public: std::string name; int age; Person(std::string n , int a 0) : name(n), age(a) {} void display() const { std::cout Name: name , Age: age std::endl; } }; int main() { // 创建存储 Person 对象的 array std::arrayPerson, 3 people { Person(Alice, 25), Person(Bob, 30), Person(Charlie, 35) }; // 遍历并显示所有元素 std::cout All people: std::endl; for (const auto person : people) { person.display(); } // 修改元素 people[0].name Alicia; people.at(1).age 31; // 显示修改后的元素 std::cout \nAfter modification: std::endl; for (const auto person : people) { person.display(); } // 使用 fill 填充 people.fill(Person(Unknown, 0)); // 显示填充后的元素 std::cout \nAfter fill: std::endl; for (const auto person : people) { person.display(); } return 0; }

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价