我如何find数组的长度?
有没有办法find一个数组有多less个值? 检测我是否已经到达数组的末尾也将工作。
如果你的意思是一个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)
但这会给你指针types不是数组的错误答案。
template<class T, size_t N> constexpr size_t size(T (&)[N]) { return N; }
这有一个很好的属性,无法编译非数组types(Visual Studio有_countof
这样做的)。 constexpr
使得这是一个编译时expression式,所以它没有超过macros的任何缺点(至less我没有知道)。
你也可以考虑使用C ++ 11中的std::array
,它暴露了它的长度,没有比本地C数组更高的开销。
做sizeof( myArray )
会得到分配给该数组的字节总数。 然后可以通过除以数组中的一个元素的大小来找出数组中元素的数量: sizeof( myArray[0] )
有没有办法find一个数组有多less个值?
是!
试试sizeof(array)/sizeof(array[0])
检测我是否已经到达数组的末尾也将工作。
我没有看到任何方式,除非你的数组是一个字符数组(即string)。
PS:在C ++中总是使用std::vector
。 有几个内置function和一个扩展function。
std::vector
有一个方法size()
,它返回vector中元素的个数。
(是的,这是口舌相传的答案)
#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; }
还有TR1 / C ++ 11 / C ++ 17的方法(见Coliru上的Live ):
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
自C ++ 11以来,引入了一些新的模板来帮助减less处理数组长度时的痛苦。 所有这些都在标题<type_traits>
中定义。
-
std::rank<T>::value
如果
T
是数组types,则提供等于数组维数的成员常数值。 对于任何其他types,值为0。 -
std::extent<T, N>::value
如果
T
是一个数组types,如果N
在[0,std::rank<T>::value
)中,则提供成员常数值等于沿着数组第N
维的元素数。 对于任何其他types,或者如果T
是沿着它的第一维的未知边界的数组,并且N
是0,则值是0。 -
std::remove_extent<T>::type
如果
T
是某个types为X
的数组,则提供成员typedeftypes等于X
,否则types为T
请注意,如果T
是一个multidimensional array,则只会删除第一个维度。 -
std::remove_all_extents<T>::type
如果
T
是某个typesX
的multidimensional array,则提供成员typedeftypes等于X
,否则types为T
要获得multidimensional array的任何维度的长度,可以使用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,获取multidimensional array中元素的总数:
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; }
关于如何使用它们的更多例子可以通过下面的链接find。
而不是使用内置的数组函数:
int x[2] = {0,1,2};
你应该使用数组类和数组模板。 尝试:
#include <array> array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
所以现在如果你想查找数组的长度,所有你必须使用数组类的尺寸函数。
Name_of_Array.size();
并且应该返回数组中元素的长度。
在C ++中,使用std :: array类声明一个数组,可以很容易地find一个数组的大小,也是最后一个元素。
#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; }
事实上,数组类有很多其他的function,让我们使用数组的标准容器。
参考1到C ++ std :: array类
参考2到std :: array类
参考中的例子是有帮助的。
这是来自Google 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)通过检查sizeof(arr)(数组中的字节数)和sizeof(*(arr))(一个数组元素中的字节数)来工作。 如果前者可以被后者整除,也许arr确实是一个数组,在这种情况下,除法结果是数组中元素的数量。 否则,arr不可能是一个数组,并且我们生成一个编译器错误,以防止编译代码。
由于bool的大小是实现定义的,我们需要将!(sizeof(a)&sizeof(*(a)))转换为size_t,以确保最终结果的types为size_t。
这个macros并不完美,因为它错误地接受了某些指针,也就是说指针大小可以被指针大小整除。 由于我们所有的代码必须经过一个32位的编译器,其中一个指针是4个字节,这意味着指向一个大小为3或大于4的types的指针将被(正确地)拒绝。
一个使用generics的好方法:
template <typename T,unsigned S> inline unsigned arraysize(const T (&v)[S]) { return S; }
然后简单地调用arraysize(_Array);
获取数组的长度。
资源
在visual studio 2015中,我们可以通过简单地使用size()
函数来find数组中值的个数。
源代码:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" }; int size_of_array=size(myArray);
如果你输出size_of_array
,输出结果是:
>>> 4
只是一个想法,但只是决定创build一个计数器variables,并将数组大小存储在位置[0]。 我删除了函数中的大部分代码,但是在退出循环之后会看到prime [0]被赋予了最终的'a'值。 我尝试使用vector,但VS Express 2013并不是那么喜欢。 另外请注意,'a'从一开始以避免覆盖[0],并在开始时初始化以避免错误。 我不是专家,只是以为我会分享。
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; }
最终寻找这个的最常见的原因之一是因为你想传递一个数组到一个函数,而不必传递另一个参数的大小。 你一般也喜欢数组的大小是dynamic的。 该数组可能包含对象,而不是基元,对象可能很复杂,以至于size_of()对于计算计数来说是不安全的选项。
正如其他人所build议的,考虑使用一个std ::向量或列表等,而不是原始数组。 然而,在旧的编译器上,尽pipe如此,仍然不会有最终的解决scheme,因为填充容器需要一堆难看的push_back()行。 如果你像我一样,想要一个包含匿名对象的单行解决scheme。
如果你使用STL容器替代原始数组,那么这个SOpost可能对你初始化它的方法有用: 什么是用硬编码元素初始化一个std :: vector最简单的方法?
下面是一个我正在使用的方法,这个方法可以在编译器和平台上普遍使用:
创build一个结构或类作为您的对象集合的容器。 为<<定义一个运算符重载函数。
class MyObject; struct MyObjectList { std::list<MyObject> objects; MyObjectList& operator<<( const MyObject o ) { objects.push_back( o ); return *this; } };
你可以创build把你的结构作为参数的函数,例如:
someFunc( MyObjectList &objects );
然后,你可以调用这个函数,像这样:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
这样,你可以build立一个dynamic的大小的对象集合在一个简单的行中传递给一个函数!
避免与sizeof一起使用该types,因为sizeof(array)/sizeof(char)
,如果更改数组的types,会突然变坏。
在Visual Studio中,如果sizeof(array)/sizeof(*array)
是等价的。 你可以简单地键入_countof(array)
对于旧的g ++编译器,你可以这样做
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; }
length = sizeof(array_name)/sizeof(int);
我个人会build议(如果你不能以任何理由使用专门的函数)首先扩展数组types的兼容性超过你通常使用它(如果你是存储值≥0:
unsigned int x[] -> int x[]
比你要使数组1元素大于你所需要的。 对于最后一个元素,你会放入一些types,包含在扩展types说明符中,但通常不会使用,例如使用前面的示例,最后一个元素将是-1。 这使您(通过使用for循环)查找数组的最后一个元素。
比方说,你有一个全局数组声明在页面的顶部
int global[] = { 1, 2, 3, 4 };
要找出数组中有多less个元素(在c ++中),请键入以下代码:
sizeof(global) / 4;
sizeof(NAME_OF_ARRAY)/ 4将返回给定数组名称的元素数目。