有没有办法找到一个数组有多少个值?检测我是否已经到达数组末尾也可以。
有没有办法找到一个数组有多少个值?检测我是否已经到达数组末尾也可以。
Answers:
如果您的意思是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
使得它成为一个编译时表达式,因此它在宏上没有任何缺点(至少我不知道)。
您还可以考虑使用std::array
C ++ 11,它可以在没有本地C数组开销的情况下公开其长度。
C ++ 17具有std::size()
在<iterator>
其中做同样的和适用于STL容器太(感谢报头@乔恩Ç)。
extent
,现在来看它有两个特征,这些特征使其比上面的功能(对于本用例)有用。(1)指针返回零(而不是编译错误)。(2)它需要一个类型参数,因此要检查变量,您必须做decltype
这样做sizeof( myArray )
将为您提供分配给该数组的字节总数。然后,可以通过除以数组中一个元素的大小来找出数组中的元素数:sizeof( myArray[0] )
尽管这是一个老问题,但值得更新C ++ 17的答案。标准库中现在有模板化函数std::size()
,该函数返回std容器或C样式数组中的元素数。例如:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
有没有办法找到一个数组有多少个值?
是!
尝试 sizeof(array)/sizeof(array[0])
检测我是否已经到达数组末尾也可以。
除非您的数组是字符数组(即字符串),否则我看不到任何方法。
PS:在C ++中始终使用std::vector
。有几个内置功能和扩展功能。
std::vector
有一个size()
返回向量元素数量的方法。
(是的,这是嘲讽的答案)
#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开始,引入了一些新模板来帮助减少处理数组长度时的麻烦。所有这些都在header中定义<type_traits>
。
如果T
为数组类型,则提供等于数组维数的成员常量值。对于任何其他类型,值均为0。
如果T
为数组类型,则提供成员常量值,该值等于N
数组第th维上的元素数,如果N
为[0,std::rank<T>::value
)。对于任何其他类型,或者如果T
为沿其第一维绑定的未知数组且N
值为0,则值为0。
如果T
是某个类型的数组X
,则提供等于typedef的成员类型X
,否则类型为T
。请注意,如果T
是多维数组,则仅删除第一维。
std::remove_all_extents<T>::type
如果T
是某种类型的多维数组X
,则提供成员typedef类型等于的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;
}
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;
}
通过链接可以找到更多有关如何使用它们的示例。
还有TR1 / C ++ 11 / C ++ 17的方式(请参阅参考资料Live on 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
在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;
}
实际上,数组类还有很多其他功能,可以让我们将数组用作标准容器。
对C ++ std :: array类的参考1对std :: array类的
参考2参考中
的示例很有帮助。
这是一个古老而又传奇的问题,已经有许多惊人的答案了。但是随着时间的流逝,语言中增加了新功能,因此我们需要根据可用的新功能继续进行更新。
我只是注意到尚未有人提到C ++ 20。所以想写答案。
在C ++ 20中,标准库中添加了一种新的更好的方法,用于查找数组的长度,即std:ssize()
。此函数返回signed value
。
#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;
}
PS此方法也适用vector
。
许多其他答案中已经提到了这种传统方法。
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
仅供参考,如果您想知道为什么将数组传递给另一个函数时这种方法不起作用。原因是,
在C ++中,数组不按值传递,而是传递指向数组的指针。由于在某些情况下,传递整个阵列可能是昂贵的操作。您可以通过将数组传递给某个函数并对该数组进行一些更改,然后再次在main中打印该数组来进行测试。您将获得更新的结果。
就像您已经知道的那样,该sizeof()
函数提供字节数,因此在其他函数中,它将返回为指针分配的字节数,而不是整个数组。所以这种方法行不通。
但是,我敢肯定,根据您的要求,您可以找到一种不错的方法。
编码愉快。
您有很多选择可用于获取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(<array>) / sizeof(<array>[<element>]):
std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
这是一个实现的ArraySize
,从谷歌的Protobuf。
#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,以确保最终结果的类型为size_t。
这个宏不是完美的,因为它错误地接受了某些指针,即指针大小可以被指针大小整除。由于我们所有的代码都必须经过一个32位编译器(指针为4个字节),这意味着(正确地)拒绝指向大小为3或大于4的所有类型的指针。
int nombres[5] = { 9, 3 };
此函数返回5
而不是2
。
对于C ++ / CX(在Visual Studio中使用C ++编写例如UWP应用程序时),我们只需使用size()
函数就可以找到数组中的值数。
源代码:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
如果您cout
的size_of_array
输出将是:
>>> 4
sizeof(array_name)
给出整个数组的大小,并sizeof(int)
给出每个数组元素的数据类型的大小。
因此,将整个数组的大小除以数组单个元素的大小即可得出数组的长度。
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
回答:
int number_of_elements = sizeof(array)/sizeof(array[0])
说明:
由于编译器会为每种数据类型预留一个特定大小的内存块,而数组只是其中的一组,因此您只需将数组的大小除以数据类型的大小即可。如果我有一个由30个字符串组成的数组,那么我的系统会为该数组的每个元素(字符串)留出24个字节。在30个元素上,总共有720个字节。720/24 == 30个元素。小型而紧凑的算法是:
int number_of_elements = sizeof(array)/sizeof(array[0])
等于
number_of_elements = 720/24
请注意,即使它是自定义数据类型,也无需知道数组是什么数据类型。
只是一个想法,但只是决定创建一个计数器变量并将数组大小存储在位置[0]。我删除了函数中的大部分代码,但退出循环后会看到,prime [0]被分配了最终值'a'。我尝试使用矢量,但VS Express 2013不太喜欢。还要注意,“ a”从1开始以避免覆盖[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;
}
一个使用泛型的好的解决方案:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
然后只需调用arraysize(_Array);
即可获取数组的长度。
constexpr
是修复程序。inline
不是。constexpr
虽然很现代。您确定测试程序没有使用另一个新功能,即可以声明其长度由变量指定的本地数组吗?尝试使用两个全局数组。
我在这里提供了一个棘手的解决方案:
您始终可以存储length
在第一个元素中:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
成本是您--arr
调用时必须free
arr
类型与兼容int
且数组的长度不超过该类型的最大值时,该方法才有效。例如,使用此技巧,Pascal字符串实际上是字节数组。Pascal中字符串的最大长度为255个字符。
您可以通过以下步骤找到数组的长度:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
只需使用以下代码段即可:
#include <iostream>
#include <string>
#include <array>
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;
}
避免与sizeof一起使用类型,因为sizeof(array)/sizeof(char)
如果更改数组的类型,突然会损坏。
在Visual Studio中,等价于sizeof(array)/sizeof(*array)
。您只需键入_countof(array)
您最终会找到此结果的最常见原因之一是,因为您想要将数组传递给函数,而不必为其大小传递另一个参数。您通常还希望数组大小是动态的。该数组可能包含对象,而不是基元,并且对象可能很复杂,因此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) );
这样,您可以在一条简单的代码行中生成动态大小的对象集合并将其传递给函数!
假设您在页面顶部声明了一个全局数组
int global[] = { 1, 2, 3, 4 };
要找出数组中(在c ++中)有多少个元素,请输入以下代码:
sizeof(global) / 4;
sizeof(NAME_OF_ARRAY)/ 4将为您返回给定数组名称的元素数。