C++数组长度获取:多种实现方式的原理、差异及疑问
C++数组长度获取方法的差异解析
我在LeetCode上看到三种获取C++数组长度的代码,由于还没掌握指针概念,搞不懂其中原理,想请教这几种实现方式的差异,以及为什么获取数组长度会有多种形式。
三种实现代码及原理
第一种方法:sizeof(a1) / sizeof(*a1)
#include <iostream> int main() { int a1[5] = {1, 2, 3}; // 未初始化的元素会被设为默认值 int size = sizeof(a1) / sizeof(*a1); std::cout << "The size of a1 is: " << size << std::endl; }
原理:
sizeof(a1)计算整个数组占用的总字节数,这里a1是长度为5的int数组,多数系统中int占4字节,总字节数为5*4=20。sizeof(*a1)计算数组第一个元素的字节数,*a1等价于取数组首元素a1[0],结果为4字节。- 总字节数除以单个元素字节数,得到数组的元素个数(20/4=5)。
第二种方法:sizeof(myNumbers) / sizeof(myNumbers[0])
#include <iostream> using namespace std; int main() { int myNumbers[5] = {10, 20, 30, 40, 50}; int getArrayLength = sizeof(myNumbers) / sizeof(myNumbers[0]); cout << getArrayLength; return 0; }
原理和第一种完全一致,只是把*a1换成了myNumbers[0],本质都是取单个元素的字节数。这种写法更直观,新手更容易理解是“拿第一个元素的大小来除”。
第三种方法:end(arr) - begin(arr)
#include<iostream> #include<array> using namespace std; int main() { // 给定数组 int arr[] = { 11, 22, 33, 44 }; cout<<"The Length of the Array is : "<<end(arr)-begin(arr); // 获取长度 return 0; }
原理:
begin(arr)是C++11引入的标准库函数,返回指向数组第一个元素的迭代器(可理解为指向元素的标记)。end(arr)返回指向数组末尾之后位置的迭代器,这个位置不存储元素,仅用于标记数组结束。- 原生数组的迭代器属于“随机访问迭代器”,两个迭代器相减的结果就是数组的元素个数。
三种方法的核心差异
兼容性与历史渊源
- 前两种是从C语言继承的写法,兼容所有C++版本和C语言,属于传统“C风格”实现。
- 第三种是C11及以后支持的现代写法,更贴合C的STL编程风格。
适用场景限制
- 三种方法都只能直接用于栈上的原生数组:如果数组作为函数参数传递(此时数组会退化成指针),前两种方法会失效——
sizeof(指针)得到的是指针本身的字节数(比如8字节),除以元素大小会得到错误结果;第三种方法也无法对指针使用begin/end。 - 第三种方法扩展性更好:如果把原生数组换成
std::array(C++11标准容器),begin/end的写法完全通用,而前两种方法需要调整为sizeof(arr)/sizeof(arr[0])或直接用arr.size()。
- 三种方法都只能直接用于栈上的原生数组:如果数组作为函数参数传递(此时数组会退化成指针),前两种方法会失效——
可读性
- 第三种写法更直观,直接表达“从数组开头到结尾的元素个数”,符合现代C++编码习惯。
- 前两种写法需要理解
sizeof的计算逻辑,对新手门槛稍高。
为什么会有多种实现形式?
- 历史迭代:C++基于C语言发展而来,保留了C语言获取数组长度的方式,同时随着语言进化,引入了更符合面向对象/泛型编程的新方法。
- 编码习惯差异:不同项目的编码规范不同,老项目可能更倾向于C风格的
sizeof方法,新项目则更愿意用现代C++的迭代器写法。 - 场景适配:
sizeof方法不需要引入额外头文件,在极简环境下更实用;而在需要和STL容器配合的场景中,begin/end的一致性更好。
内容的提问来源于stack exchange,提问作者Eliaz Bobadilla
相关产品推荐
相关产品推荐

