数组名作为指针传递,实际传的是首元素地址,函数接收的是指针而非副本,因此无法直接获取数组大小,需额外传参。

在c++中,将数组传递给函数是一个常见但容易误解的问题。很多人误以为可以像普通变量一样直接“传值”给函数,但实际上数组的传递有其特殊性。下面详细说明C++中数组作为函数参数的几种正确方式及其原理。
1. 数组名作为指针传递
当把数组名作为实参传递给函数时,实际上传递的是数组首元素的地址,也就是一个指针。这意味着函数接收到的并不是整个数组的副本,而是指向数组第一个元素的指针。
例如:
void printArray(int arr[], int size) {
for (int i = 0; i std::cout }
std::cout }
调用方式:
立即学习“C++免费学习笔记(深入)”;
int data[] = {1, 2, 3, 4, 5};
printArray(data, 5);
这里 arr[] 的写法只是语法糖,等价于 int* arr。函数内部对 arr 的操作实质上是对原数组的访问,因此修改 arr[i] 会影响原始数组。
2. 显式使用指针参数
为了更清晰地表达意图,可以直接使用指针形式声明参数:
void printArray(int* arr, int size) {
// 与上面完全相同
}
这种写法强调了传参的本质——传递地址。它和 int arr[] 在编译后是完全一样的,选择哪种风格取决于代码可读性的偏好。
3. 引用方式传递数组(保留数组大小信息)
如果希望避免退化为指针,并且让函数知道数组的实际大小,可以使用引用传递:
template <size_t N>
void printArray(int (&arr)[N]) {
for (int i = 0; i std::cout }
std::cout }
这种方式不会发生数组到指针的退化,N 是模板推导出的实际数组长度。调用时无需传 size,编译器自动识别:
int data[] = {1, 2, 3};
printArray(data); // 自动推导 N = 3
注意:该方法只能用于固定大小的数组,不能用于动态分配或指针变量。
4. 使用 std::array 或 std::vector(推荐现代C++做法)
对于现代C++开发,建议使用标准库容器替代原生数组:
#include <array>
#include <vector> void processArray(const std::array<int, 5>& arr) {
for (int x : arr) std::cout }
void processVector(const std::vector<int>& vec) {
for (int x : vec) std::cout << x << ” “;
}
优点包括:
- 支持拷贝、赋值
- 自带大小信息(.size())
- 可被完整传递,不会退化为指针
- 更安全,不易越界
特别是 std::vector,适用于大小不固定的场景;而 std::array 适合固定长度且追求性能的情况。
基本上就这些。理解数组传参的关键在于明白“数组名作为函数参数时会退化为指针”,若需保留维度或类型信息,应使用引用或标准库容器。不复杂但容易忽略细节。