因为数组不能拷贝,所以函数不能返回数组,不过,函数可以返回数组的指针或引用。在现代 C++ 中,我们应该优先使用标准库容器而不是 C 风格的原始数组和指针,比如std::array
和std::vector
。
方法一:C 风格的语法(不推荐,但需要了解)
C 风格数组指针的返回类型语法非常晦涩。
1. 直接声明(最复杂)
语法为:元素类型 (*函数名())[数组大小]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include <iostream>
int (*get_arr())[5] { static int arr[5] = {1, 2, 3, 4, 5}; return &arr; }
int main() { int (*ptr_to_arr)[5] = get_arr();
for (int i = 0; i < 5; ++i) { std::cout << (*ptr_to_arr)[i] << " "; } std::cout << std::endl; }
|
语法解析:
get_arr()
:表示 get_arr
是一个函数。
*get_arr()
:表示函数返回一个指针。
(*get_arr())[5]
:括号确保 *
和 get_arr()
先结合,说明返回的是一个指向大小为 5 的数组的指针。
int (*get_arr())[5]
:这个数组的元素类型是 int
。
2. 使用类型别名 (using
或 typedef
)(推荐的 C 风格写法)
为了简化复杂的语法,可以使用类型别名,让代码可读性大大提高。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream>
using Array_t = int[5];
Array_t* get_arr_aliased() { static int arr[5] = {10, 20, 30, 40, 50}; return &arr; }
int main() { Array_t* ptr_to_arr = get_arr_aliased(); for (int i = 0; i < 5; ++i) { std::cout << (*ptr_to_arr)[i] << " "; } std::cout << std::endl; }
|
这种方法清晰地将复杂的类型定义与函数签名分开,是 C 风格中最好的选择。
3. 使用尾返回类型 (auto
和 ->
) (C++11)
这是另一种简化语法的方式,让返回类型的书写更符合阅读顺序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <iostream>
auto get_arr_trailing() -> int (*)[5] { static int arr[5] = {11, 22, 33, 44, 55}; return &arr; }
int main() { auto ptr_to_arr = get_arr_trailing(); for (int i = 0; i < 5; ++i) { std::cout << (*ptr_to_arr)[i] << " "; } std::cout << std::endl; }
|
方法二:现代 C++ 的方法(强烈推荐)
在现代 C++ 中,我们应该优先使用标准库容器而不是 C 风格的原始数组和指针。
1. 返回 std::array
(大小固定的数组)
std::array
是对 C 风格数组的封装,类型安全,有关联的大小信息,并且可以轻松地按值或按引用返回。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream> #include <array>
std::array<int, 5> get_std_array() { std::array<int, 5> arr = {1, 2, 3, 4, 5}; return arr; }
std::array<int, 5>& get_std_array_ref() { static std::array<int, 5> arr = {10, 20, 30, 40, 50}; return arr; }
int main() { auto my_arr = get_std_array(); for (int val : my_arr) { std::cout << val << " "; } std::cout << std::endl;
auto& my_arr_ref = get_std_array_ref(); for (int val : my_arr_ref) { std::cout << val << " "; } std::cout << std::endl; }
|
2. 返回 std::vector
(大小可变的数组)
如果数组大小是动态的,std::vector
是最佳选择。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream> #include <vector>
std::vector<int> get_vector() { return {100, 200, 300}; }
int main() { std::vector<int> my_vec = get_vector(); for (int val : my_vec) { std::cout << val << " "; } std::cout << std::endl; }
|
总结
方法 |
优点 |
缺点/适用场景 |
推荐度 |
C 风格 - 直接声明 |
C/C++ 兼容 |
语法极其晦涩,易错 |
不推荐 |
C 风格 - 类型别名 |
极大提高可读性 |
仍是 C 风格,不含大小信息,不安全 |
在必须用 C 风格数组时推荐 |
C 风格 - 尾返回 |
提高可读性 |
C++11+ 限定,本质仍是 C 风格指针 |
在必须用 C 风格数组时推荐 |
现代 C++ - std::array |
类型安全,语法简单,自带大小 |
大小需在编译期确定 |
强烈推荐 (固定大小) |
现代 C++ - std::vector |
类型安全,语法简单,大小动态 |
有堆内存分配开销 |
强烈推荐 (动态大小) |
结论:除非有特殊理由(如与 C 库交互),否则请始终优先使用 std::array
或 std::vector
。