有没有办法找出一个数组有多少个值?检测是否已经到达数组的末尾也可以工作。
当前回答
在c++中,使用std::array类来声明数组,可以很容易地找到数组的大小以及最后一个元素。
#include<iostream>
#include<array>
int main()
{
std::array<int,3> arr;
//To find the size of the array
std::cout<<arr.size()<<std::endl;
//Accessing the last element
auto it=arr.end();
std::cout<<arr.back()<<"\t"<<arr[arr.size()-1]<<"\t"<<*(--it);
return 0;
}
事实上,数组类有很多其他函数,让我们使用数组作为标准容器。 参考1到c++ std::array类 引用2到std::array类 参考文献中的例子很有帮助。
其他回答
下面是谷歌Protobuf中ArraySize的一个实现。
#define GOOGLE_ARRAYSIZE(a) \
((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
// test codes...
char* ptr[] = { "you", "are", "here" };
int testarr[] = {1, 2, 3, 4};
cout << GOOGLE_ARRAYSIZE(testarr) << endl;
cout << GOOGLE_ARRAYSIZE(ptr) << endl;
ARRAYSIZE(arr) works by inspecting sizeof(arr) (the # of bytes in the array) and sizeof(*(arr)) (the # of bytes in one array element). If the former is divisible by the latter, perhaps arr is indeed an array, in which case the division result is the # of elements in the array. Otherwise, arr cannot possibly be an array, and we generate a compiler error to prevent the code from compiling. Since the size of bool is implementation-defined, we need to cast !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final result has type size_t. This macro is not perfect as it wrongfully accepts certain pointers, namely where the pointer size is divisible by the pointee size. Since all our code has to go through a 32-bit compiler, where a pointer is 4 bytes, this means all pointers to a type whose size is 3 or greater than 4 will be (righteously) rejected.
如果你指的是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;
or:
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
在c++中,如果你想要这种行为,那么你应该使用容器类;可能std::向量。
最常见的原因之一是,您希望将数组传递给函数,而不必为其大小传递另一个参数。您通常也希望数组大小是动态的。该数组可能包含对象,而不是原语,而且对象可能很复杂,因此size_of()是计算计数的不安全选项。
正如其他人建议的那样,考虑使用std::vector或list等来代替原始数组。然而,在旧的编译器上,您仍然不能通过简单地这样做得到您可能想要的最终解决方案,因为填充容器需要大量丑陋的push_back()行。如果你像我一样,想要一个包含匿名对象的单行解决方案。
如果你使用STL容器替代原始数组,那么这篇SO文章可能会对你有用,让你知道如何初始化它: 用硬编码的元素初始化std::vector最简单的方法是什么?
下面是我使用的一个方法,它将在编译器和平台上普遍工作:
为对象集合创建一个结构体或类作为容器。为<<定义运算符重载函数。
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
你可以创建以你的结构体作为参数的函数,例如:
someFunc( MyObjectList &objects );
然后,你可以调用这个函数,像这样:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
这样,您就可以在一行代码中构建并将动态大小的对象集合传递给函数!
使用泛型的一个好的解决方案:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
然后简单地调用arraysize(_Array);来获取数组的长度。
源
从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;
}
更多如何使用它们的例子可以通过以下链接找到。