C++如何获取数组的长度?(sizeof与模板方法)

C++中获取数组长度需区分原生数组与指针:原生数组用sizeof(arr)/sizeof(arr[0]);模板函数或C++17的std::size可类型安全推导;函数参数中数组会退化为指针,应使用引用、std::array或std::vector。

在C++中,获取数组长度不能像Python那样直接调用len(),但有几种可靠方式——关键在于区分“原生数组”和“指针”,因为一旦数组退化为指针(比如传入函数后),sizeof就失效了。

用 sizeof 计算原生数组长度

sizeof(array) / sizeof(array[0]) 是最常用、最直接的方法,但它只对定义在当前作用域的原生数组有效(即未退化为指针)。

  • 原理:sizeof(数组名) 返回整个数组占用的字节数,sizeof(数组元素) 得到单个元素大小,相除即元素个数
  • 必须确保 array 是真正的数组类型,不是 int* 或函数参数(后者 sizeof 返回指针大小,通常是 4 或 8)
  • 示例:int arr[] = {1, 2, 3, 4}; size_t n = sizeof(arr) / sizeof(arr[0]); // 结果为 4

用模板推导实现类型安全的数组长度

模板方法能避免误用于指针,且支持编译期计算,更健壮:

  • 利用模板参数推导数组类型(含长度),例如:template constexpr size_t array_size(T (&)[N]) { return N; }
  • 调用时自动推导 N,即使元素类型复杂(如 std::string[5])也能正确返回 5
  • 若传入指针会编译失败,提前暴露错误,比 sizeof 更安全
  • C++17 起可直接用 std::size(arr)(需 #include ),本质就是该模板的标准化封装

注意:函数参数中数组会退化为指针

这是最容易出错的地方。形如 void func(int arr[])void func(int* arr) 中,arr 已是 int*sizeof(arr) 不再是数组总大小。

立即学习“C++免费学习笔记(深入)”;

  • 解决方案:传入数组时用引用形式,例如 template void func(int (&arr)[N]),这样能保留长度信息
  • 或改用 std::arraystd::vector,它们自带 .size() 成员函数,语义清晰且无退化问题

std::array 和 std::vector 的推荐用法

现代C++中,优先考虑标准容器替代裸数组:

  • std::array arr = {1,2,3,4,5}; —— 编译期定长,arr.size() 安全、直观、constexpr 友好
  • std::vector vec = {1,2,3}; —— 运行期可变长,vec.size() 返回当前元素数
  • 二者都支持范围 for、迭代器,且不会隐式转成指针,规避了裸数组的大部分陷