如何找到数组的长度?
Posted
技术标签:
【中文标题】如何找到数组的长度?【英文标题】:How do I find the length of an array? 【发布时间】:2011-05-05 17:33:24 【问题描述】:有没有办法找出一个数组有多少个值?检测我是否已经到达数组的末尾也可以。
【问题讨论】:
数组从何而来?通常带数组的函数也会带一个长度参数来处理这个问题。 好吧,我正在制作一个“疯狂的库”程序,其中包含一个包含所有文本的数组,以及用户必须填写的名词/动词的位置。我想要使用函数遍历整个数组,将“[noun]”和“[verb]”值替换为用户输入的文本。 Computing length of array 的可能重复项 请注意,在 C 中,数组不是对象或结构。因此,默认情况下,它们在任何地方都没有存储长度参数。如果您想将它们作为 C++ 中的对象使用,请尽可能使用 C++ 对象 std::vector 或 C++11 的 std::array。如果您必须使用指针,请始终将数组的长度作为第二个参数传递给每个使用它的函数。 如果您使用的是 C++20,那么我也为此添加了答案。很容易错过,因为这里有很多答案。 【参考方案1】:您可以使用 sizeof() 运算符,用于相同目的。
见下面的示例代码
#include <iostream>
using namespace std;
int main()
int arr[] = 10,20,30,40,50,60;
int arrSize = sizeof(arr)/sizeof(arr[0]);
cout << "The size of the array is: " << arrSize;
return 0;
【讨论】:
【参考方案2】:如果你的意思是一个 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
。
【讨论】:
如果您将数组传递给不同的函数并尝试在那里执行它也不起作用:) @San :在这种情况下创建一个function template
@San Jacinto:不,无论您在哪个函数中,这都有效(在 arrays 上)。但是,将可变长度的数组作为参数传递给函数,是不可能的(它衰减成一个指针) - 但是如果你在一个结构中传递一个数组,那么这将按预期工作。
@OliverCharlesworth 如果您将数组按值传递给另一个函数并在那里尝试,它不会工作,对吧?问题是为什么
@A_Matar - 您不能在 C 或 C++ 中按值传递数组。【参考方案3】:
执行sizeof myArray
将获得为该数组分配的总字节数。然后,您可以通过除以数组中一个元素的大小来找出数组中元素的数量:sizeof myArray[0]
所以,你会得到类似的东西:
size_t LengthOfArray = sizeof myArray / sizeof myArray[0];
由于sizeof
产生size_t
,结果LengthOfArray
也将属于这种类型。
【讨论】:
这是一个非常简单易行的解决方案,可以克服似乎是一个古老的问题。 不适用于由指针保存的 C++“新”数组。如果取消引用,您将获得指针的大小(4 个字节)或第一个元素的大小。 @DragonLord 是的,尽管任何使用关键字 new 声明数组大小的人都会在运行时知道数组的大小,因此无需使用 sizeof 运算符来查找数组的大小在这种情况下数组。我相信你知道这一点。这只是为了任何不这样做的人的利益。 @surega 它不会崩溃【参考方案4】:正如其他人所说,您可以使用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)。
【讨论】:
编译时出现两个错误(我什至没有尝试使用它):错误 C2265:'T(arg&)[N]
。
谢谢莫蒂!遗漏的参数名称对我来说已经很清楚了。但令人难以置信的是,我以前从未使用过 refs/pointers to arrays。并且将来可能不会,因为这样的数组正在消亡得更多。
如果使用 C++11 不是 std::extent 更好的解决方案???? en.cppreference.com/w/cpp/types/extent
@IsaacPascual 我不熟悉extent
,现在看它有两个特点,使它不如上面的函数有用(对于这个用例)。 (1) 它为指针返回零(而不是编译错误)。 (2) 它需要一个类型参数,所以为了检查一个变量你必须做decltype
【参考方案5】:
回答:
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
请注意,您不需要知道数组是什么数据类型,即使它是自定义数据类型。
【讨论】:
在 2019 年不需要这种过时且容易出错的方法。***.com/a/59109106/560648 这只是现有答案的欺骗。 然而,它简单、雄辩、快速、低需求、独立于平台,并且不需要包含向量或指针。至于重复其他答案,似乎只有一个具有相同算法的其他答案,并且没有像我的答案那样解释问题的基本机制。我恭敬地建议,它不是容易出错,而是相当健壮。【参考方案6】:而不是使用内置数组函数aka:
int x[3] = 0, 1, 2;
您应该使用数组类和数组模板。试试:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = ;
所以现在如果你想找到数组的长度,你所要做的就是使用数组类中的size函数。
Name_of_Array.size();
这应该返回数组中元素的长度。
【讨论】:
【参考方案7】:sizeof(array_name)
给出整个数组的大小,sizeof(int)
给出每个数组元素的数据类型的大小。
因此,将整个数组的大小除以数组中单个元素的大小,就得到了数组的长度。
int array_name[] = 1, 2, 3, 4, 5, 6;
int length = sizeof(array_name)/sizeof(int);
【讨论】:
虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请包括对您的代码的解释,因为这确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因【参考方案8】:这是一个非常古老且具有传奇色彩的问题,并且已经有许多令人惊叹的答案。但随着时间的推移,语言中添加了新功能,因此我们需要根据可用的新功能不断更新内容。
我刚刚注意到有人还没有提到 C++20。所以想写答案。
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
在 C++17 中,有一个更好的方法(当时)同样是在 iterator
中定义的 std::size()
。
#include <iostream>
#include <iterator> // required for std::size
int main()
int arr[] = 1, 2, 3;
std::cout << "Size is " << std::size(arr);
return 0;
附:此方法也适用于vector
。
旧
许多其他答案中已经提到了这种传统方法。
#include <iostream>
int main()
int array[] = 1, 2, 3 ;
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
仅供参考,如果您想知道为什么这种方法在将数组传递给另一个函数时不起作用。原因是,
在 C++ 中,数组不是按值传递的,而是传递指向数组的指针。在某些情况下,传递整个数组可能是昂贵的操作。您可以通过将数组传递给某个函数并在那里对数组进行一些更改来测试这一点,然后再次在 main 中打印该数组。您将获得更新的结果。
正如您已经知道的那样,sizeof()
函数给出了字节数,因此在其他函数中它将返回分配给指针的字节数,而不是整个数组。所以这种方法行不通。
但我相信您可以根据您的要求找到一种好方法。
快乐编码。
【讨论】:
【参考方案9】:您有很多选项可用于获取 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;
【讨论】:
【参考方案10】:您最终会寻找这个的最常见原因之一是因为您想将数组传递给函数,而不必传递另一个参数来确定其大小。您通常还希望数组大小是动态的。该数组可能包含对象,而不是基元,并且对象可能很复杂,因此 size_of() 不是计算计数的安全选项。
正如其他人所建议的,考虑使用 std::vector 或列表等代替原始数组。但是,在旧的编译器上,您仍然无法通过简单的方式获得您可能想要的最终解决方案,因为填充容器需要一堆丑陋的 push_back() 行。如果您像我一样,想要一个涉及匿名对象的单行解决方案。
如果您使用 STL 容器替代原始数组,则此 SO 帖子可能对您有用,以了解初始化它的方法: What is the easiest way to initialize a std::vector with hardcoded elements?
这是我正在使用的一种方法,它将在编译器和平台上通用:
为您的对象集合创建一个结构或类作为容器。为 定义一个运算符重载函数
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) );
这样,您可以在一条干净的行中构建动态大小的对象集合并将其传递给函数!
【讨论】:
【参考方案11】:你可以使用这个sn-p:
#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;
这是参考:http://www.cplusplus.com/reference/array/array/size/
【讨论】:
【参考方案12】:您可以通过以下方式找到数组的长度:
int arr[] = 1, 2, 3, 4, 5, 6;
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
【讨论】:
简化为 (&arr)[1] - arr;【参考方案13】:我在这里提供了一个棘手的解决方案:
您始终可以将length
存储在第一个元素中:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
代价是调用free
时必须--arr
【讨论】:
只有当arr
的类型与int
兼容并且数组不超过该类型的最大值时才有效。例如。 Pascal 字符串实际上是使用此技巧的字节数组; Pascal 中字符串的最大长度为 255 个字符。
我想可以在每个数组的开头保留 8 个字节,如果他们想存储对象,可以使用 unsigned long。我认为向量可能更容易。但对于嵌入式系统来说绝对是一个很好的解决方案。【参考方案14】:
虽然这是一个老问题,但值得更新 C++17 的答案。在标准库中现在有模板化函数std::size()
,它返回标准容器或 C 样式数组中的元素数。例如:
#include <iterator>
uint32_t data[] = 10, 20, 30, 40;
auto dataSize = std::size(data);
// dataSize == 4
【讨论】:
并使用 C++20,std::ssize()
将任何范围的 std::size()
获取为有符号整数,这对于避免在循环中包装恐怖、避免前者的冗长强制转换等很有用。
【参考方案15】:
对于 C++/CX(例如在 Visual Studio 中使用 C++ 编写 UWP 应用程序时),我们可以通过简单地使用 size()
函数来查找数组中值的数量。
源代码:
string myArray[] = "Example1", "Example2", "Example3", "Example4" ;
int size_of_array=size(myArray);
如果你 cout
size_of_array
输出将是:
>>> 4
【讨论】:
【参考方案16】:我个人建议(如果您由于某种原因无法使用专门的函数)首先扩展数组类型的兼容性,使其超出您通常使用的范围(如果您存储的值 ≥ 0:
unsigned int x[] -> int x[]
比你使数组 1 元素比你需要的大。对于最后一个元素,您将放置一些包含在扩展类型说明符中但通常不会使用的类型,例如使用前面的示例,最后一个元素将是 -1。这使您能够(通过使用 for 循环)找到数组的最后一个元素。
【讨论】:
【参考方案17】:对于旧的 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;
【讨论】:
这是正确答案。在 C++ 版本中非常便携,不适用于指针,而且答案在编译时可用【参考方案18】:还有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
【讨论】:
【参考方案19】:从 C++11 开始,引入了一些新模板来帮助减少处理数组长度时的痛苦。它们都在标题<type_traits>
中定义。
std::rank<T>::value
如果T
是数组类型,则提供等于数组维数的成员常量值。对于任何其他类型,值为 0。
std::extent<T, N>::value
如果T
是数组类型,如果N
在[0, std::rank<T>::value
) 中,则提供等于数组N
th 维度上的元素数的成员常量值。对于任何其他类型,或者如果T
是沿其第一个维度的未知边界数组并且N
为0,则值为0。
std::remove_extent<T>::type
如果T
是某个类型X
的数组,则提供等于X
的成员typedef type,否则type 为T
。请注意,如果T
是多维数组,则仅删除第一个维度。
std::remove_all_extents<T>::type
如果T
是某个类型X
的多维数组,则提供成员typedef type等于X
,否则type是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;
点击链接可以找到更多如何使用它们的示例。
【讨论】:
【参考方案20】:避免将 type 与 sizeof 一起使用,如 sizeof(array)/sizeof(char)
,如果更改数组的类型会突然损坏。
在 Visual Studio 中,您有等效的 if sizeof(array)/sizeof(*array)
。
你可以直接输入_countof(array)
【讨论】:
【参考方案21】:在 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;
实际上,数组类还有很多其他功能,可以让我们使用数组作为标准容器。Reference 1 to C++ std::array classReference 2 to std::array class 参考资料中的示例很有帮助。
【讨论】:
不错;我看到你有很多技能;和......很好的方法。我认为自己也应该为这些著名问题写更多答案;-)【参考方案22】:使用泛型的好解决方案:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) return S;
然后只需调用arraysize(_Array);
即可获取数组的长度。
Source
【讨论】:
@bobbogo 与 inline 或 constexpr 一起使用,也许您关闭了 inline 或者它是可选的? ideone.com/VxogJ4 @QentinUKconstexpr
是解决方法。 inline
不是。 constexpr
虽然很现代。您确定您的测试程序没有使用另一个现代功能,您可以在其中声明一个长度由变量给出的本地数组吗?尝试使用两个全局数组。【参考方案23】:
这是来自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 是 确实是一个数组,在这种情况下,除法结果是# of 数组中的元素。否则, arr 不可能是数组, 我们生成一个编译器错误以防止代码 编译。
由于 bool 的大小是实现定义的,我们需要转换 !(sizeof(a) & sizeof(*(a))) 到 size_t 以确保最终 结果的类型为 size_t。
这个宏并不完美,因为它错误地接受了某些 指针,即指针大小可以被指针整除的地方 尺寸。由于我们所有的代码都必须经过 32 位编译器, 其中一个指针是 4 个字节,这意味着所有指向一个类型的指针 size 为 3 或大于 4 将被(正确地)拒绝。
【讨论】:
具有如下整数数组:int nombres[5] = 9, 3 ;
此函数返回5
而不是2
。
GOOGLE_ARRAYSIZE(new int8_t)
在我的测试环境中返回8
,而不是引发错误。铸造的部分似乎是多余的,更不用说尖叫的 C 宏了。 sizeof(a) / sizeof(*a)
足以作为旧版解决方案。【参考方案24】:
#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;
【讨论】:
我相信这个只适用于堆栈上的局部变量。 这是最好的答案。 @DragonLord,它也适用于成员变量。见cpp.sh/92xvv。【参考方案25】:假设您在页面顶部声明了一个全局数组
int global[] = 1, 2, 3, 4 ;
要找出数组中有多少元素(在 c++ 中),请键入以下代码:
sizeof(global) / 4;
sizeof(NAME_OF_ARRAY) / 4 将返回给定数组名称的元素数。
【讨论】:
sizeof(int) 取决于平台。不能保证它会是 4(尽管这是最常见的情况) 谢谢你的补充。 幻数!!【参考方案26】:只是一个想法,但只是决定创建一个计数器变量并将数组大小存储在位置 [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;
【讨论】:
【参考方案27】:std::vector
有一个方法size()
,它返回向量中元素的数量。
(是的,这是半开玩笑的回答)
【讨论】:
这可能是面面相觑,但几乎可以肯定这是正确的方法。 你为什么说它是在开玩笑?对我(一个 c++ 新手)来说,这似乎是正确的答案。 @dbliss 这是开玩笑的,因为 OP 询问了 array 的长度,而 eq- 告诉他们如何获取 vector,这在 C++ 中是另一回事。但是,在更深层次上它是正确的,因为if you need to get the length at run time, a vector is a much better choice. 你也可以使用 std::list 或者我相信的其他容器。 这个答案特别棒的地方在于,您可以使用数组字面量初始化向量或列表。【参考方案28】:有没有办法找出一个数组有多少个值?
是的!
试试sizeof(array)/sizeof(array[0])
检测我是否已经到达数组的末尾也可以。
除非您的数组是字符数组(即字符串),否则我看不到任何方法。
P.S : 在 C++ 中总是使用std::vector
。有几个内置功能和扩展功能。
【讨论】:
这不适用于可变的单个数组大小 +1 表示向量。很少有强有力的案例可以再使用旧式 C++ 数组了。除非数组的大小永远不会改变,但即便如此,您也应该使用数组容器类。最好使用像vector这样的容器类来进行动态数组存储。使用容器类的好处远远超过必须管理自己的内存的坏处。 @MartynShutt 当你被缓存绑定时,比如在游戏开发中,你有时不能使用向量。 如果一个数组有0个元素,那么array[0]合法吗?以上是关于如何找到数组的长度?的主要内容,如果未能解决你的问题,请参考以下文章