有没有办法找出一个数组有多少个值?检测是否已经到达数组的末尾也可以工作。


当前回答

虽然这是一个老问题,但值得将答案更新到c++ 17。在标准库中,现在有一个模板化函数std::size(),它返回std容器或c风格数组中的元素数量。例如:

#include <iterator>

uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4

其他回答

你有很多选项可以用来获取C数组的大小。

int myArray[] = {0, 1, 2, 3, 4, 5, 7};

1) sizeof(<array>) / sizeof(<type>):

std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;

2) sizeof(<array>) / sizeof(*<array>):

std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;

3) sizeof(<数组>)/ sizeof(<数组>[<元素>]):

std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;

正如其他人所说,您可以使用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)。

避免将类型与sizeof一起使用,因为如果改变数组类型,sizeof(array)/sizeof(char)会突然被破坏。

在visual studio中,你有等效的if sizeof(array)/sizeof(*array)。 你可以输入_countof(array)

vector有一个size()方法,该方法返回vector中元素的数量。

(是的,这是半开玩笑的回答)

从c++ 11开始,引入了一些新的模板来帮助减少处理数组长度时的痛苦。它们都定义在header <type_traits>中。

std::rank<T>::value If T is an array type, provides the member constant value equal to the number of dimensions of the array. For any other type, value is 0. std::extent<T, N>::value If T is an array type, provides the member constant value equal to the number of elements along the Nth dimension of the array, if N is in [0, std::rank<T>::value). For any other type, or if T is array of unknown bound along its first dimension and N is 0, value is 0. std::remove_extent<T>::type If T is an array of some type X, provides the member typedef type equal to X, otherwise type is T. Note that if T is a multidimensional array, only the first dimension is removed. std::remove_all_extents<T>::type If T is a multidimensional array of some type X, provides the member typedef type equal to X, otherwise type is 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;
}

BTY,获取多维数组中元素的总数:

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;
}

更多如何使用它们的例子可以通过以下链接找到。