c++中int arr[]形参实际为int*,不保留数组长度,sizeof返回指针大小;须额外传长度或改用std::array(编译期固定长度)或std::vector(运行时动态长度)。

函数参数写 int arr[] 其实就是 int* arr
这是最常被误解的一点:C++ 里形参写成 int arr[] 或 int arr[10],编译器根本不检查数组长度,它自动退化为 int*。你传进去一个 int[5],函数里用 sizeof(arr) 得到的永远是指针大小(通常是 8),不是数组总字节数。
常见错误现象:sizeof(arr) / sizeof(int) 在函数内算出 1 或 2,而不是你期望的元素个数。
- 必须额外传入长度,比如
void process(int arr[], int len) - 如果只写
void process(int arr[]),函数内部无法安全遍历整个数组 -
int arr[10]这种写法纯属心理安慰,对编译器没意义
用 std::array 避免裸指针陷阱
如果你确定数组长度在编译期已知(比如固定存 3 个坐标、4 个颜色分量),std::array 是更安全的选择。它保留长度信息,支持 .size()、范围 for、拷贝语义,且零开销。
使用场景:配置表、状态码映射、小尺寸固定结构体成员。
立即学习“C++免费学习笔记(深入)”;
- 声明为
void process(const std::array<int>& arr)</int>,函数内可直接用arr.size() - 传参时不用取地址,也不用担心退化 —— 它就是值语义的容器
- 注意:模板参数里的长度必须是编译期常量,不能是变量
示例:
std::array<int, 3> coords = {1, 2, 3};<br>process(coords); // OK,长度 3 被完整传递
用 std::vector 处理运行时长度数组
当数组大小不确定、需要增删、或来自用户输入时,std::vector 是唯一合理选择。它把数据和长度绑在一起,内存自动管理,接口统一。
性能影响:小数组(比如
- 不要为了“性能”硬用裸指针配长度参数,除非 profiler 真标出它是瓶颈
- 传
const std::vector<int>&</int>避免拷贝,也禁止意外修改 - 避免返回局部
std::vector的指针或引用 —— 生命周期不匹配
用引用传递裸数组(仅限编译期长度已知)
极少数情况你需要操作原始栈数组且不想用 STL,可以用引用语法强制绑定长度:void process(int (&arr)[5])。这时 sizeof(arr) 返回真实字节数,arr 也不是指针。
容易踩的坑:int a[3]; process(a); 会编译失败,因为类型不匹配 —— 引用声明锁死了长度,没法泛化。
- 适合封装工具函数,比如校验某类固定长度数组的合法性
- 不能用于函数模板自动推导长度(
template<size_t n> void f(int (&)[N])</size_t>可以,但调用端仍受限) - 一旦涉及多维数组(如
int mat[3][4]),语法迅速变得反直觉,不如老实用std::vector<:vector>></:vector>或扁平化 + 显式行列参数
真正麻烦的从来不是“怎么传”,而是“谁负责生命周期”和“长度信息存在哪”。裸数组传参时,长度几乎总是要额外带一个参数;而只要长度不确定,就别硬扛,直接上 std::vector —— 它不是高级功能,是基础生存工具。










