所谓的 “数组长度”,指的就是数组中一共包含多少个元素。当数组里的元素比较多,或者初始化时省略了中括号 [] 里的数字时,靠人工一个个去数不仅麻烦,还很容易数错。
在 C++ 中,让程序自动获取数组长度常用的有 2 种方式:① 使用标准库提供的 std::size() 函数;② 使用 sizeof 运算符相除计算。
使用 std::size() 获取长度(推荐)
在现代 C++ 开发中,我们优先推荐使用标准库提供的 std::size() 函数来获取数组的长度。
语法:
std::size(数组名)说明:
在使用 std::size() 函数之前,我们需要先通过 #include <iterator> 引入头文件。调用该函数后,std::size() 会直接返回数组中包含的元素个数。
示例 1:使用 std::size() 获取长度
#include <iostream>
#include <iterator>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int len = std::size(arr);
std::cout << len;
return 0;
}运行结果如下。
5分析:
std::size(arr) 表示直接获取数组 arr 中元素的个数,因此输出结果为 5。即使我们在初始化时省略了 [] 里的数字,std::size() 依然能准确算出元素个数。后续如果往花括号里增删了初始元素,它也会自动算出新的长度。
这里有一点需要留意:数组长度指的是创建数组时确定的 “总元素个数”。哪怕采用部分初始化,比如写成 int arr[5] = {10, 20} 只给前两个元素赋初值,std::size(arr) 算出来的依然是总长度 5,而不是手写了几个数字。
在实际开发中,获取到数组长度之后,除了后面遍历数组时会经常用到之外,还有一个常见用途是结合下标访问数组的 “最后一个元素”。如果数组的长度为 len,那么最后一个元素的下标就是 len - 1。
示例 2:获取最后一个元素
#include <iostream>
#include <iterator>
int main() {
int arr[] = {12, 25, 38, 41, 56, 60};
int len = std::size(arr);
std::cout << "第 1 个元素:" << arr[0] << '\n';
std::cout << "最后一个元素:" << arr[len - 1];
return 0;
}运行结果如下。
第 1 个元素:12
最后一个元素:60分析:
在这个例子中,std::size(arr) 算出数组长度 len 为 6。由于数组下标是从 0 开始计算的,最后一个元素的下标是 len - 1,也就是 5,因此 arr[len - 1] 访问的就是 arr[5],输出结果为 60。
这里小伙伴们要注意,访问最后一个元素时不能直接写成 arr[len]。因为下标 len 已经超出了 0 ~ len - 1 的合法范围,会导致数组下标越界,下面这种写法就是错误的:
std::cout << arr[len]; // 下标越界使用 sizeof 计算长度
std::size() 是从 C++17 标准才开始引入的。在此之前的早期 C++ 代码中,并没有直接获取数组长度的函数,当时我们通常会借助 sizeof 运算符来计算数组长度。
语法:
sizeof(数组名) / sizeof(数组名[0])说明:
一个数组虽然包含多个元素,但数组本身也可以看作一个整体。因此,我们可以使用 sizeof(数组名) 获取整个数组在内存中占用的总字节数,再用 sizeof(数组名[0]) 获取第 1 个元素占用的字节数。
由于同一个数组中所有元素的数据类型都相同,每个元素占用的字节数也完全一样。这就好比已知整箱苹果重 20 斤、每个苹果重 4 斤,将 “数组总字节数” 除以 “单个元素的字节数”,算出来的结果自然就是数组的元素个数了。
示例 3:使用 sizeof 计算长度
#include <iostream>
int main() {
double prices[] = {12.5, 8.8, 19.9, 6.5};
int len = sizeof(prices) / sizeof(prices[0]);
std::cout << "数组总字节数:" << sizeof(prices) << '\n';
std::cout << "单个元素字节数:" << sizeof(prices[0]) << '\n';
std::cout << "数组长度:" << len;
return 0;
}运行结果如下。
数组总字节数:32
单个元素字节数:8
数组长度:4分析:
从运行结果可以直观地看到:每个 double 元素占 8 个字节,4 个元素一共占 32 个字节。sizeof(prices) 得到总字节数 32,sizeof(prices[0]) 得到单个元素的字节数 8,两者相除 32 ÷ 8 就算出了数组长度 4。
可能有些小伙伴看到数组元素的类型是 double,会想着把除号后面直接写成 sizeof(double)。我们可以对比一下下面这 2 种方式:
// 方式 1(推荐)
int len = sizeof(prices) / sizeof(prices[0]);
// 方式 2(不推荐)
int len = sizeof(prices) / sizeof(double);方式 2 虽然在这里也能算出正确结果,但如果后续把数组的元素类型改成了 float 或 int,我们还得记得手动修改除号后面的类型名,一旦漏改就会算错长度。
相比之下,方式 1 除以的是第 1 个元素 prices[0] 的大小。不管以后把数组元素改成什么类型,它都能自动算出正确的数组长度,因此在实际开发中我们更推荐使用方式 1。
提示 编写现代 C++(C++17 及以上)代码时,优先使用 std::size(arr) 即可。而在阅读早期 C++ 或 C 语言代码时,经常会遇到 sizeof(arr) / sizeof(arr[0]),建议大家两种写法都掌握。
