C++ 如何在函数中获取作为参数的数组的长度?

308 天前
 rabbbit

除了传个长度参数进去还有别的办法吗?

#include <iostream>
using namespace std;

void f(int nums[]) 
{
	cout << sizeof(nums) << endl;
}

int main()
{
	int nums[5] = {1,2,3,4,5};
	f(nums);
	return (0);
}
5834 次点击
所在节点    C++
36 条回复
marat1ren
308 天前
用向量,别用数组
shyrock
308 天前
也可以在数组尾部加入一个约定的结尾符
rabbbit
308 天前
数组和指针的关系?
翻了些资料。有人说是一个东西,有人说不是。搞不懂。

#include <iostream>
using namespace std;

int main()
{
int nums[5] = { 1,2,3,4,5 };
int* foo = nums;
int bar = *foo;
cout << foo << endl;
cout << bar << endl; // 1
cout << bar + 1 << endl; // 2
}
rabbbit
308 天前
cout << bar + 1 << endl;
->
cout << *(foo + 1) << endl;
ripperdev
308 天前
这种写法的话,在 f 函数里的 nums 数组已经退化成指针了。
如果是 C++20 标准的话,可以这么写
```cpp
#include <iostream>
using namespace std;

void f(auto &&nums)
{
cout << std::distance(std::begin(nums), std::end(nums)) << endl;
}

int main()
{
int nums[5] = { 1,2,3,4,5 };
f(nums);
return (0);
}

```
geelaw
308 天前
void foo(int nums[]) 和 void foo(int *nums) 没啥区别,要同时知道长度的话,用 template <size_t n> void foo(int (&nums)[n])
ripperdev
308 天前
不过仍然建议在 C++里面用 array 或者 vector
leonshaw
308 天前
std::span
ershierdu
308 天前
从问题和给的样例来看,OP 应该是刚入门?
建议先学习一下 STL ,也就是 std::vector 之类的。楼上说的其他方案都更高阶了,可能不是现阶段你需要的
mainjzb
308 天前
int nums[] 在 go 里其实是对应的 C++ 的 std::vector 。
那么 C++为什么没有这么做呢,因为出道太早。很多旧代码已经写成这样了。贸然改动会导致旧代码崩溃。所以只能引入新的名词,导致新人难以理解。
这就是大家经常抱怨 C++历史包袱太多的表现之一。
GeruzoniAnsasu
308 天前
见 #8 的标准方法

然而这个方法不是用来传你理解的数组的,这个传数组引用的方法几乎都发生在 constexpr / consteval 场景中,传入普通的「静态大小」(而非「编译期计算」) array 会导致实例化出大量一次性代码,严重增加目标可执行文件的冗余



以你现在刚开始入门的阶段建议先好好啃啃 c++ primer ,以前觉得 primer 上来就是模板库太抽象了,但现代版本的 c++ 确实就是大量依赖模板打造的编译期约束上的。
GeruzoniAnsasu
308 天前
@GeruzoniAnsasu 我看走眼了…… 在说 #6
manyfreebug
308 天前
在 C++ 中,当数组传递给函数时,数组会退化为指针,因此在函数中使用 sizeof 来获取数组的长度是不准确的。在这种情况下,可以通过传递数组的长度作为额外的参数来解决。

如果你不想显式传递数组长度,你可以考虑使用 C++ 中的 std::array 或者 std::vector 。这两者都包含了一个成员函数 size(),可以方便地获取数组的长度。

下面是一个使用` std::array` 的例子:
```
#include <iostream>
#include <array>

void f(std::array<int, 5>& nums)
{
std::cout << nums.size() << std::endl;
}

int main()
{
std::array<int, 5> nums = {1, 2, 3, 4, 5};
f(nums);
return 0;
}
```

或者使用 `std::vector:`
```
#include <iostream>
#include <vector>

void f(std::vector<int>& nums)
{
std::cout << nums.size() << std::endl;
}

int main()
{
std::vector<int> nums = {1, 2, 3, 4, 5};
f(nums);
return 0;
}
```
这样就可以方便地获取数组的长度而不必显式传递长度参数。
Hackerl
308 天前
std::span<int>
iOCZS
308 天前
sizeof 能求得静态分配内存的数组的长度,sizeof 不能求得动态分配的内存的大小。
所以得用 STL 里容器
yolee599
308 天前
用 C 语言的方案:
1. 函数再加一个 length 参数,传参的时候传进去。
2. 数组最后一个元素加一个特别的值,然后在函数内对数组元素进行遍历计数。

用 c++ 语言的方案:
使用 std::vector 。
roycestevie6761
308 天前
不就是最简单的数组引用传递? C++ Primer 有讲,最基础的模板参数的使用,楼上 geelaw 说的是对的,其他人的回答我看着真是头晕,应该没有一个真正用过 C++写项目的
mainjzb
308 天前
? 楼上在发言什么叼言论,绝大部分人根本不需要使用模板。
前面所有人说的基本都没啥问题。
不用模板=没真正用过 C++写项目
66666666666
我也来发表偏激: 正是你们这些模板瞎用的人才导致编译贼慢,建议尽快铲除这些异类。
littlewing
308 天前
请使用 std::array 或 std::vector
imKiva
308 天前
template <typename T, size_t N>
size_t length(const T (&array) [N]) {
return N;
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1012152

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX