有没有办法找出数组有多少个值?检测我是否已经到达数组的末尾也可以。
有没有办法找出数组有多少个值?检测我是否已经到达数组的末尾也可以。
如果您指的是C风格数组,那么可以这样做:
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
这个方法对指针无效(即以下两种情况都不起作用):
int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
或:
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
如果你想在C++中实现这种行为,那么你应该使用一个容器类,可能是std::vector
。
如其他人所说,你可以使用 sizeof(arr)/sizeof(*arr)
,但是对于不是数组的指针类型,这将会给出错误的答案。
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
这个方法有一个不错的特点,它对于非数组类型无法编译(Visual Studio有一个名为_countof
的函数也有这个特性)。constexpr
使它成为编译时表达式,因此与宏相比没有任何缺陷(至少我不知道有哪些)。
你还可以考虑使用C++11的std::array
,它在本地C数组上没有额外开销并公开了其长度。
C++17在<iterator>
头文件中提供了std::size()
函数,可以用于STL容器和具有相同功能(感谢@Jon C)。
extent
,现在看了一下,发现它有两个特点使得它对于这种用例来说不如上面的函数实用。第一,它对于指针返回零(而不是编译错误)。第二,它需要一个类型参数,因此为了检查一个变量,你必须使用 decltype
。 - Motti虽然这是一个老问题,但值得更新到C++17的答案。在标准库中,现在有了模板函数std::size()
,它返回std容器或C风格数组中元素的数量。例如:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
std::ssize()
函数获取任何范围的std::size()
作为有符号整数,这对于在循环中避免包装错误、冗长的强制转换等非常有用。 - underscore_d使用 sizeof myArray
可以获取为该数组分配的总字节数。然后,通过将其除以数组中一个元素的大小,可以找出数组中元素的数量:sizeof myArray[0]
因此,您会得到类似以下的东西:
size_t LengthOfArray = sizeof myArray / sizeof myArray[0];
sizeof
会计算出一个size_t
类型的值,所以LengthOfArray
的结果也将是这种类型。
有没有办法找出数组有多少个值?
有的!
尝试使用 sizeof(array)/sizeof(array[0])
检测我是否已经到达了数组的末尾也可以。
除非你的数组是字符数组(即字符串),否则我看不到任何方法可以实现这一点。
P.S:在C++中,始终使用std::vector
。它有几个内置函数和扩展功能。
array[0]
使用sizeof
运算符进行求值,因为它实际上并不在运行时计算,只是在编译时找到它的类型以获取大小。 - CoffeeTableEspresso#include <iostream>
int main ()
{
using namespace std;
int arr[] = {2, 7, 1, 111};
auto array_length = end(arr) - begin(arr);
cout << "Length of array: " << array_length << endl;
}
std::vector
有一个方法size()
,它返回向量中元素的数量。
(是的,这是一个开玩笑的答案)
这是一道古老而传奇的问题,已经有很多令人惊叹的答案了。但随着时间的推移,语言中不断添加新的功能,所以我们需要根据可用的新功能不断更新。
我刚刚注意到还没有人提到C++20。所以我想写下答案。
在C++20中,标准库中新增了一种更好的方法来查找数组的长度,即std:ssize()
。该函数返回一个有符号值
。
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
在C++17中,对于相同的操作有了更好(那个时候)的方式,即std::size()
,该函数被定义在iterator
中。
#include <iostream>
#include <iterator> // required for std::size
int main(){
int arr[] = {1, 2, 3};
std::cout << "Size is " << std::size(arr);
return 0;
}
另外,这种方法同样适用于vector
。
这种传统方法已经在许多其他答案中提到过了。
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
只是想告知一下,如果你想知道为什么这种方法在将数组传递给另一个函数时会失效。原因是:
C++ 中并不是按值传递数组,而是传递指向数组的指针。因为在某些情况下,传递整个数组可能是昂贵的操作。您可以通过将数组传递给某个函数,并在该函数中对数组进行一些更改,然后再次在主函数中打印数组来测试此操作,您将获得更新后的结果。
正如你已经知道的那样,sizeof()
函数返回字节数,因此在其他函数中,它将返回分配给指针的字节数,而不是整个数组的字节数。所以这种方法行不通。
但我相信你可以根据自己的需求找到好的解决方法。
祝编码愉快!
<type_traits>
中。
如果T
是数组类型,则提供成员常量值等于数组维度数。对于任何其他类型,值为0。
如果T
是数组类型,则提供成员常量值等于数组沿第N
个维度的元素数量,如果N
在[0,std::rank<T>::value
)之间。对于任何其他类型,或者如果T
是沿其第一个维度具有未知边界的数组,并且N
为0,则值为0。
如果T
是某种类型X
的数组,则提供成员typedef type等于X
,否则类型为T
。请注意,如果T
是多维数组,则仅删除第一个维度。
std::remove_all_extents<T>::type
如果T
是某种类型X
的多维数组,则提供成员typedef type等于X
,否则类型为T
。
要获取多维数组中任何维度的长度,可以使用decltype
与std::extent
结合使用。例如:
#include <iostream>
#include <type_traits> // std::remove_extent std::remove_all_extents std::rank std::extent
template<class T, size_t N>
constexpr size_t length(T(&)[N]) { return N; }
template<class T, size_t N>
constexpr size_t length2(T(&arr)[N]) { return sizeof(arr) / sizeof(*arr); }
int main()
{
int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
// New way
constexpr auto l1 = std::extent<decltype(a)>::value; // 5
constexpr auto l2 = std::extent<decltype(a), 1>::value; // 4
constexpr auto l3 = std::extent<decltype(a), 2>::value; // 3
constexpr auto l4 = std::extent<decltype(a), 3>::value; // 0
// Mixed way
constexpr auto la = length(a);
//constexpr auto lpa = length(*a); // compile error
//auto lpa = length(*a); // get at runtime
std::remove_extent<decltype(a)>::type pa; // get at compile time
//std::remove_reference<decltype(*a)>::type pa; // same as above
constexpr auto lpa = length(pa);
std::cout << la << ' ' << lpa << '\n';
// Old way
constexpr auto la2 = sizeof(a) / sizeof(*a);
constexpr auto lpa2 = sizeof(*a) / sizeof(**a);
std::cout << la2 << ' ' << lpa2 << '\n';
return 0;
}
顺便提一下,要获取多维数组中元素的总数:
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
#include <iostream>
#include <type_traits>
template<class T>
constexpr size_t len(T &a)
{
return sizeof(a) / sizeof(typename std::remove_all_extents<T>::type);
}
int main()
{
int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
constexpr auto ttt = len(a);
int i;
std::cout << ttt << ' ' << len(i) << '\n';
return 0;
}
您可以通过跟随链接找到更多如何使用它们的示例。
还有 TR1/C++11/C++17 的方法(参见 Coliru 上的实例):
const std::string s[3] = { "1"s, "2"s, "3"s };
constexpr auto n = std::extent< decltype(s) >::value; // From <type_traits>
constexpr auto n2 = std::extent_v< decltype(s) >; // C++17 shorthand
const auto a = std::array{ "1"s, "2"s, "3"s }; // C++17 class template arg deduction -- http://en.cppreference.com/w/cpp/language/class_template_argument_deduction
constexpr auto size = std::tuple_size_v< decltype(a) >;
std::cout << n << " " << n2 << " " << size << "\n"; // Prints 3 3 3