How do I find the length of an array?
有没有办法找出一个数组有多少个值?检测我是否已经到达数组的末尾也是有效的。
如果您是指C样式数组,那么您可以执行以下操作:
1 2 | int a[7]; std::cout <<"Length of array =" << (sizeof(a)/sizeof(*a)) << std::endl; |
但是,这在指针上不起作用,也就是说,它对以下任何一种都不起作用:
1 2 | int *p = new int[7]; std::cout <<"Length of array =" << (sizeof(p)/sizeof(*p)) << std::endl; |
或:
1 2 3 4 5 6 7 | void func(int *p) { std::cout <<"Length of array =" << (sizeof(p)/sizeof(*p)) << std::endl; } int a[7]; func(a); |
在C++中,如果你想要这种行为,那么你应该使用容器类;可能是EDCOX1(0)。
正如其他人所说,您可以使用
1 2 | template<class T, size_t N> constexpr size_t size(T (&)[N]) { return N; } |
这有一个很好的特性,即无法为非数组类型编译(Visual Studio有执行此操作的
您还可以考虑使用来自C++ 11的EDCOX1的10度,它暴露了它的长度,而在原生C数组上没有开销。
C++ 17在EDCOX1×12 12的头中有EDOCX1×11,它同样适用于STL容器(感谢@乔恩C)。
执行
Is there a way to find how many values an array has?
对!
试试
Detecting whether or not I've reached the end of an array would also work.
除非您的数组是一个字符数组(即字符串),否则我看不到任何实现这一点的方法。
P.S:在C++中总是使用EDCOX1〔0〕。有几个内置功能和扩展功能。
这是一个老问题,它值得更新C++ 17的答案。在标准库中,现在有模板化函数
1 2 3 4 5 | #include <iterator> uint32_t data[] = {10, 20, 30, 40}; auto dataSize = std::size(data); // dataSize == 4 |
(是的,这是半开玩笑的回答)
1 2 3 4 5 6 7 8 9 | #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; } |
自从C++ 11以来,引入了一些新的模板来帮助减少处理数组长度时的痛苦。所有这些都在标题
std::rank ::value 如果
T 是数组类型,则提供等于数组维数的成员常量值。对于任何其他类型,值为0。std::extent ::value 如果
T 是数组类型,那么如果N 在〔0〕中,std::rank 中,则提供等于沿数组的::value N 维元素数的成员常量值。对于任何其他类型,或者如果T 是沿其第一维度绑定的未知数组,并且N 为0,则值为0。std::remove_extent ::type 如果
T 是某个类型X 的数组,则提供成员typedef类型等于X ,否则类型为T 。注意,如果T 是多维数组,则只删除第一个维度。std::remove_all_extents ::type 如果
T 是某种类型X 的多维数组,则提供成员typedef类型等于X ,否则类型为T 。
为了获得多元素数组的任何维的长度,可以使用
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 29 30 31 32 33 34 35 36 37 | #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 << ' '; // Old way constexpr auto la2 = sizeof(a) / sizeof(*a); constexpr auto lpa2 = sizeof(*a) / sizeof(**a); std::cout << la2 << ' ' << lpa2 << ' '; return 0; } |
bty,要获取多提及数组中的元素总数,请执行以下操作:
1 | constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type); |
或者将其放入函数模板中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #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) << ' ';? return 0; } |
通过以下链接可以找到更多关于如何使用它们的示例。
还有Tr1/c++ 11 /c++ 17方式(见CyrURUBKBD上的LIFE):
1 2 3 4 5 6 7 8 9 | 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 <<" "; // Prints 3 3 3 |
而不是使用内置数组函数aka:
1 | int x[2] = {0,1,2}; |
您应该使用数组类和数组模板。尝试:
1 2 | #include array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {}; |
所以现在如果你想找到数组的长度,你需要做的就是使用数组类中的size函数。
1 | Name_of_Array.size(); |
这将返回数组中元素的长度。
在C++中,使用STD::数组类声明数组,可以很容易地找到数组的大小,也可以找到最后一个元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include<iostream> #include 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; } |
实际上,array类有很多其他的函数,我们可以使用array作为标准容器。参考文献1到C++ STD::数组类引用2到std::array类参考文献中的例子很有用。
对于C++/CX(当在VisualStudio中使用C++编写UWP应用程序)时,我们可以通过简单地使用EDCOX1×26函数来找到数组中的值个数。
源代码:
1 2 | string myArray[] = {"Example1","Example2","Example3","Example4" }; int size_of_array=size(myArray); |
如果你用
1 | >>> 4 |
1 | length = sizeof(array_name)/sizeof(int); |
下面是来自Google Protobuf的
1 2 3 4 5 6 7 8 | #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.
使用泛型的好解决方案:
1 2 | template <typename T,unsigned S> inline unsigned arraysize(const T (&v)[S]) { return S; } |
然后简单地调用
来源
对于旧的G++编译器,可以这样做
1 2 3 4 5 6 7 8 9 10 | template <class T, size_t N> char (&helper(T (&)[N]))[N]; #define arraysize(array) (sizeof(helper(array))) int main() { int a[10]; std::cout << arraysize(a) << std::endl; return 0; } |
我在这里提供了一个棘手的解决方案:
您始终可以将
1 2 3 4 5 6 7 8 9 | // malloc/new arr[0] = length; arr++; // do anything. int len = *(arr-1); free(--arr); |
成本是当调用
您可以通过以下方式找到数组的长度:
1 2 3 4 | int arr[] = {1, 2, 3, 4, 5, 6}; int size = *(&arr + 1) - arr; cout <<"Number of elements in arr[] is"<< size; return 0; |
您有许多选项可用于获取C数组大小。
int myarray[]=0,1,2,3,4,5,7_
1 | std::cout <<"Size:" << sizeof(myArray) / sizeof(int) << std::endl; |
1 | std::cout <<"Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl; |
1 | std::cout <<"Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl; |
避免将类型与sizeof一起使用,因为如果更改数组的类型,
在Visual Studio中,如果
只是一个想法,但只是决定创建一个计数器变量并将数组大小存储在位置[0]。我删除了函数中的大部分代码,但在退出循环后,prime[0]将被赋值为"a"。我试过使用向量,但2013年的vs Express并不是很喜欢。还要注意,"a"从一开始以避免覆盖[0],并且它在开始时已初始化以避免错误。我不是专家,只是想和大家分享。
1 2 3 4 5 6 | int prime[] = {0}; int primes(int x, int y){ using namespace std; int a = 1; for (int i = x; i <= y; i++){prime[a] = i; a++; } prime[0] = a; return 0; } |
只需使用以下代码段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <iostream> #include <string> #include using namespace std; int main() { array<int,3> values; cout <<"No. elements in valuea array:" << values.size() <<" elements." << endl; cout <<"sizeof(myints):" << sizeof(values) << endl; } |
参考文献如下:http://www.cplusplus.com/reference/array/array/size/
最常见的一个原因是您希望将数组传递给函数,而不必为其大小传递另一个参数。您通常也希望数组大小是动态的。该数组可能包含对象,而不是基元,并且对象可能很复杂,因此()的大小对于计算计数是不安全的选项。
正如其他人所建议的,考虑在中使用std::vector或list等,而不是使用基元数组。然而,在旧的编译器上,通过简单地这样做,您仍然没有可能想要的最终解决方案,因为填充容器需要一堆丑陋的push-back()行。如果你和我一样,想要一个包含匿名对象的单行解决方案。
如果使用STL容器替代基元数组,那么post可能会用于初始化它的方法:用硬编码元素初始化std::vector最简单的方法是什么?
下面是一个我正在使用的方法,它将在编译器和平台上通用:
创建一个结构或类作为对象集合的容器。为<<定义运算符重载函数。
1 2 3 4 5 6 7 8 9 10 11 | class MyObject; struct MyObjectList { std::list<MyObject> objects; MyObjectList& operator<<( const MyObject o ) { objects.push_back( o ); return *this; } }; |
可以创建将结构作为参数的函数,例如:
1 | someFunc( MyObjectList &objects ); |
然后,可以调用该函数,如下所示:
1 | someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) ); |
这样,您就可以在一个干净的行中将动态大小的对象集合构建并传递给一个函数!
我个人建议(如果您因任何原因无法使用专门的函数)首先扩展数组类型兼容性,使其超过您通常使用的类型(如果您存储的值大于等于0:
1 | unsigned int x[] -> int x[] |
比数组1元素的大小还要大。对于最后一个元素,您将放置一些包含在扩展类型说明符中但通常不会使用的类型,例如使用上一个示例,最后一个元素将是-1。这允许您(通过使用for循环)查找数组的最后一个元素。
假设在页面顶部声明了一个全局数组
1 | int global[] = { 1, 2, 3, 4 }; |
要知道数组类型中有多少元素(C++中)有以下代码:
1 | sizeof(global) / 4; |
sizeof(name ou array)/4将返回给定数组名的元素数。