C++数组用法详解(附带实例)
数组是编程中最基础且最常用的数据结构之一,它可以存储多个同类型的元素。
数组是一种线性数据结构,可以存储固定数量的同类型元素。数组中的元素在内存中是连续存储的,每个元素都有一个索引,用于唯一标识该元素,索引(下标)从 0 开始。
例如,我们可以声明一个包含 5 个整数的数组(见下图):

图 1 包含5个整数的数组
在这个数组中,arr[0] 是第一个元素,arr[4] 是最后一个元素。
在不同位置开辟的数组,其初始值也有所不同。在栈区(即函数内部)开辟的数组,数组元素的初始化值是未定义的,可能是随机混乱的值或内存中残余的垃圾值。而在堆区(即全局或静态区)开辟的数组,所有元素会自动将每字节都归零(即自动初始化为 0)。
示例代码如下:
在 main() 函数内部,声明了一个名为 b 的整型数组,大小同样为 N。与全局变量 a 不同,局部数组 b 没有被显式初始化,因此它的初始值是不确定的。这些值可能是内存中的任意垃圾值,也可能是编译器自动分配的值。
这段代码展示了如何声明和使用全局和局部数组,并说明了它们的初始化差异。全局数组 a 被初始化为全零,而局部数组 b 的元素值是不确定的。

图 2 一个3行4列的二维数组
例如,以下代码用来创建一个二维数组,并输出数组的一个元素:
在算法竞赛中开数组时,我们一般会多开几个空间,例如题目要求 1000 大小,我们就可以开到 1003,1005,1007 等大小,这在编程时会提供一些便利。
假如想存储一个长度为 n 的字符串,需要创建 n+1 大小的字符数组,如下图所示:

图 3 字符数组
因为字符数组的最后一位存储的是结束符'\0',它的出现意味着字符串到此为止。在 C/C++ 中,用单引号引起来的都是字符常量。字符数组有多种初始化方式,相比其他数组,它更为灵活。
首先,定义了一个字符数组 str,其长度为 N。然后,使用 cin >> str + 1;语句将输入的字符串存储到数组 str 中,从第 1 个位置开始。这里的 +1 表示将输入的字符串存储到数组的第 1 个位置,而不是第 0 个位置。
需要注意的是,为了确保有足够的空间存储输入的字符串以及可能的空字符(字符串结尾的 '\0'),数组 str 的大小应该至少为 N+2。这样,即使输入的字符串长度为 N-1,仍然可以在数组末尾添加一个空字符作为字符串结束标志。
如果只初始化数组的部分元素,未被初始化的元素将被赋予默认值(对于 int 类型,默认值为 0)。例如:
如果想要将所有元素都初始化为同一值,可以使用 std::fill 函数。例如:
当然,最常用的方法是直接用 for 循环对数组进行初始化,这样最为灵活。例如:
需要注意的是,尽管数组名可以作为指针使用,但数组名并不是一个真正的指针,它是一个常量指针,不能更改其值。例如,以下代码是错误的:
在 C++ 中,指针的使用非常普遍,因为它们提供了一种高效的方式来处理内存和数据结构,尤其是在数组、字符串和动态分配的内存处理中。
例如,如果我们有一个整数数组,则可以创建一个指向数组第一个元素的指针,并通过增加指针值来访问数组中的其他元素:
数组是一种线性数据结构,可以存储固定数量的同类型元素。数组中的元素在内存中是连续存储的,每个元素都有一个索引,用于唯一标识该元素,索引(下标)从 0 开始。
例如,我们可以声明一个包含 5 个整数的数组(见下图):
int arr[5];

图 1 包含5个整数的数组
在这个数组中,arr[0] 是第一个元素,arr[4] 是最后一个元素。
C++开辟数组空间
1) 数组的声明
在 C++ 中,我们可以在声明数组时确定其大小。例如,声明一个包含 10 个整数的数组:int arr[10];注意,数组的大小必须是常量,不能使用变量来确定数组的大小。如果想创建一个可变长度的数组,可以使用 STL 中的 vector 容器。
在不同位置开辟的数组,其初始值也有所不同。在栈区(即函数内部)开辟的数组,数组元素的初始化值是未定义的,可能是随机混乱的值或内存中残余的垃圾值。而在堆区(即全局或静态区)开辟的数组,所有元素会自动将每字节都归零(即自动初始化为 0)。
示例代码如下:
const int N = 10; // 全局变量,a = {0, 0, 0, 0, ...}(默认初始化为全 0) int a[N]; int main() { int b[N]; // 局部变量,b = {随机值}(一些随机的值) return 0; // 返回 0 表示程序正常结束 }上述代码首先定义了一个常量整数 N,其值为 10。然后,在全局作用域中声明了一个名为 a 的整型数组,其大小为 N(即 10)。由于 a 是全局变量且未显式初始化,因此数组 a 的所有元素都被默认初始化为 0。
在 main() 函数内部,声明了一个名为 b 的整型数组,大小同样为 N。与全局变量 a 不同,局部数组 b 没有被显式初始化,因此它的初始值是不确定的。这些值可能是内存中的任意垃圾值,也可能是编译器自动分配的值。
这段代码展示了如何声明和使用全局和局部数组,并说明了它们的初始化差异。全局数组 a 被初始化为全零,而局部数组 b 的元素值是不确定的。
2) 二维数组
在实际使用中,还有一个非常重要的数组类型——二维数组,其结构如下图所示:
图 2 一个3行4列的二维数组
例如,以下代码用来创建一个二维数组,并输出数组的一个元素:
const int N = 1003; const int M = 2003; int a[N][M]; // 创建一个1003 × 2003大小的二维数组 cout << a[1][2] << '\n'; // 输出数组a的第1行第2列的元素上述代码首先定义了两个常量 N 和 M,分别赋值为 1003 和 2003。然后声明了一个名为 a 的二维数组,其大小为 1003 行 2003 列。最后,使用 cout 输出数组 a 的第 1 行第 2 列的元素,即 a[1][2]。
在算法竞赛中开数组时,我们一般会多开几个空间,例如题目要求 1000 大小,我们就可以开到 1003,1005,1007 等大小,这在编程时会提供一些便利。
3) 字符数组
关于数组,还有一种字符数组,即 C原生字符串,值得了解。字符数组实际上是一个 char 类型的数组,每个元素占据一个字节(Byte)的存储空间。假如想存储一个长度为 n 的字符串,需要创建 n+1 大小的字符数组,如下图所示:

图 3 字符数组
因为字符数组的最后一位存储的是结束符'\0',它的出现意味着字符串到此为止。在 C/C++ 中,用单引号引起来的都是字符常量。字符数组有多种初始化方式,相比其他数组,它更为灵活。
char s[] = "Hello"; // 字符串长度为5,但字符数组长度为6 // 表示将字符串输入str[1]开始的字符数组中 // 注意此时需要创建n+2大小的字符数组,因为第0位没有被使用 char str[N]; cin >> str + 1;上述代码将输入的字符串存储到一个字符数组中,但从数组的第 1 个位置(索引为 1)开始存储,而不是从第 0 个位置开始。这样做的目的是让数组的第0位保持空白,或用于其他目的。
首先,定义了一个字符数组 str,其长度为 N。然后,使用 cin >> str + 1;语句将输入的字符串存储到数组 str 中,从第 1 个位置开始。这里的 +1 表示将输入的字符串存储到数组的第 1 个位置,而不是第 0 个位置。
需要注意的是,为了确保有足够的空间存储输入的字符串以及可能的空字符(字符串结尾的 '\0'),数组 str 的大小应该至少为 N+2。这样,即使输入的字符串长度为 N-1,仍然可以在数组末尾添加一个空字符作为字符串结束标志。
C++数组初始化
当我们声明数组时,可以同时对其进行初始化。例如:int arr[5] = {1, 2, 3, 4, 5};
如果只初始化数组的部分元素,未被初始化的元素将被赋予默认值(对于 int 类型,默认值为 0)。例如:
int arr[5] = {1, 2}; // 剩余的元素置为0 //arr = {1, 2, 0, 0, 0};
如果想要将所有元素都初始化为同一值,可以使用 std::fill 函数。例如:
int arr[5]; std::fill(arr, arr+5, 1); // 将[arr, arr + 5]这段内存的值初始化为1
当然,最常用的方法是直接用 for 循环对数组进行初始化,这样最为灵活。例如:
int arr[5]; for (int i = 0; i < 5; ++i) arr[i] = 0; // 将数组 arr 初始化为 0 int a[N][M]; // 初始化二维数组 // 将二维数组的 [1 ~ n][1 ~ m] 区域初始化为 0 for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) a[i][j] = 0;
C++数组和指针的关系
在 C++ 中,数组名是一个指向数组第一个元素的指针。例如:int arr[5] = {1, 2, 3, 4, 5}; int *p = arr;此时,p 指向数组 arr 的第一个元素,我们可以通过解引用指针来访问元素:
cout << *p; // 打印结果:1 cout << *(p+1); // 打印结果:2
需要注意的是,尽管数组名可以作为指针使用,但数组名并不是一个真正的指针,它是一个常量指针,不能更改其值。例如,以下代码是错误的:
int arr[5], arr2[5]; arr = arr2; // error: array type 'int [5]' is not assignable
在 C++ 中,指针的使用非常普遍,因为它们提供了一种高效的方式来处理内存和数据结构,尤其是在数组、字符串和动态分配的内存处理中。
例如,如果我们有一个整数数组,则可以创建一个指向数组第一个元素的指针,并通过增加指针值来访问数组中的其他元素:
int arr[] = {1, 2, 3, 4, 5}; int* p = arr; // p指向数组的第一个元素 cout << *p; // 输出1 cout << *(p+1); // 输出2 cout << *(p+2); // 输出3 // 以此类推理解指针的概念对于成为一名熟练的 C++ 程序员至关重要,因为它们在许多高级编程技术和库中都发挥着核心作用。