共计 1751 个字符,预计需要花费 5 分钟才能阅读完成。
为什么数组传参让人头疼?
刚学 C ++ 时,我以为这样传数组很合理:
void printArray(int arr[]) {for(int i=0; i<sizeof(arr)/sizeof(arr[0]); i++) {std::cout << arr[i] << ' ';
}
}
直到运行时发现 sizeof(arr) 得到的永远是指针大小(比如 8 字节),才意识到数组在传参时会 退化为指针。这种隐式转换导致:

- 丢失数组长度信息
- 无法进行边界检查
- 必须额外传递 size 参数
三种传统传参方式对比
1. 形参声明为数组语法(最危险)
void func(int arr[5]); // 实际等价于 int* arr
编译器会静默转换,中括号里的数字甚至会被忽略。我在 VS2022 测试时,传长度 3 的数组也能编译通过!
2. 显式使用指针(最通用)
void func(int* arr, size_t size);
需要手动传递大小,但能处理动态数组。适合 C 风格接口,但缺少类型安全性。
3. 数组引用(最安全但死板)
template<size_t N>
void func(int (&arr)[N]); // N 会被自动推导
能保留数组类型和长度,但只能接受固定大小的栈数组。在需要灵活性的场景受限。
现代 C ++ 的救星
std::array(C++11 起)
void process(const std::array<int, 5>& arr) {for(auto val : arr) {/* 安全遍历 */}
}
– 自带 size()方法
– 支持迭代器
– 值传递时不会退化为指针
std::span(C++20 起)
void analyze(std::span<int> data) {std::cout << "元素个数:" << data.size();
}
– 可接受原生数组、std::array、vector 等
– 自动记录长度
– 非拥有视图,零成本抽象
避坑实战指南
错误 1:越界访问
错误代码:
int arr[3] = {1,2,3};
for(int i=0; i<=3; i++) { // 最后一次访问越界
arr[i] *= 2;
}
修复方案:
// 方法 1:range-for(C++11)for(auto& elem : arr) {elem *= 2;}
// 方法 2:使用 span(C++20)auto view = std::span(arr);
for(size_t i=0; i<view.size(); i++) {view[i] *= 2; }
错误 2:混淆静态 / 动态数组
错误代码:
int* arr = new int[10];
size_t wrongLen = sizeof(arr); // 返回指针大小而非数组长度
正确做法:
// 动态数组必须自己记录长度
const size_t len = 10;
int* dynArr = new int[len];
delete[] dynArr; // 注意匹配 new[]/delete[]
错误 3:错误的多维数组传递
错误代码:
void print2D(int arr[][]) {/*...*/} // 编译错误
正确写法:
// 必须指定第二维大小
void print2D(int arr[][10], int rows);
// 更推荐用 vector 或 array 嵌套
using Matrix = std::vector<std::array<int, 10>>;
性能优化建议
通过 Compiler Explorer 观察不同传参方式的汇编代码:
- 传指针 + 大小:生成代码最精简,适合高频调用
- std::array 引用:与原生数组性能相当,但更安全
- std::span:在开启优化时几乎无额外开销
在热路径代码中,可以这样优化:
// 对已知大小的数组使用模板
template<size_t N>
void fastProcess(const int (&arr)[N]);
// 对性能敏感场景标记为 inline
inline void quickHandle(std::span<int> data);
思考与实践
最后留个思考题:如何设计一个同时接受以下输入的函数?
int cArr[5];
std::array<int, 5> stdArr;
std::vector<int> vec(5);
提示:可以结合模板和 C ++17 的 if constexpr 实现编译期分支。当你掌握这个技巧,就能写出真正通用的容器操作函数了!
希望这篇笔记能帮你避开我踩过的坑。数组传参看似简单,但魔鬼都在细节里。
正文完
