如何找到阵列的长度?

时间:2010-11-05 17:15:54

标签: c++ arrays

有没有办法找到一个数组有多少个值?检测我是否已到达阵列的末尾也可以。

27 个答案:

答案 0 :(得分:449)

如果您的意思是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

答案 1 :(得分:121)

正如其他人所说,你可以使用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)。

答案 2 :(得分:76)

执行sizeof( myArray )将获得为该阵列分配的总字节数。然后,您可以通过除以数组中一个元素的大小来找出数组中元素的数量:sizeof( myArray[0] )

答案 3 :(得分:50)

  

有没有办法找到一个数组有多少个值?

是!

尝试sizeof(array)/sizeof(array[0])

  

检测我是否已到达阵列的末尾也可以。

除非您的数组是一个字符数组(即字符串),否则我没有看到任何方法。

P.S:在C ++中总是使用std::vector。有几个内置函数和扩展功能。

答案 4 :(得分:40)

虽然这是一个老问题,但值得更新C ++ 17的答案。在标准库中,现在有模板化函数std::size(),它返回std容器或C样式数组中的元素数。例如:

#include <iterator>

uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4

答案 5 :(得分:27)

std::vector有一个方法size(),它返回向量中的元素数。

(是的,这是诙谐的回答)

答案 6 :(得分: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;
}

答案 7 :(得分:23)

从C ++ 11开始,引入了一些新模板来帮助减少处理数组长度时的痛苦。所有这些都在标题<type_traits>中定义。

  • std::rank<T>::value

    如果T是数组类型,则提供的成员常量值等于数组的维数。对于任何其他类型,值为0.

  • std::extent<T, N>::value

    如果T是一个数组类型,如果N位于[0,{{},则提供的成员常量值等于数组N维上的元素数。 {1}})。对于任何其他类型,或者如果std::rank<T>::value是沿其第一维的未知边界数组且T为0,则值为0.

  • std::remove_extent<T>::type

    如果N是某种类型T的数组,则提供的成员typedef类型等于X,否则键入X。请注意,如果T是多维数组,则只删除第一个维度。

  • std::remove_all_extents<T>::type

    如果T是某种类型T的多维数组,则提供的成员typedef类型等于X,否则键入X

要获得多维数组的任何维度的长度,T可用于与decltype结合使用。例如:

std::extent

BTY,获取多维数组中的元素总数:

#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;
}

或者将其放在功能模板中:

constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);

可以通过以下链接找到更多如何使用它们的示例。

答案 8 :(得分:17)

还有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

答案 9 :(得分:10)

这是一个古老而又传奇的问题,已经有许多惊人的答案。但是随着时间的流逝,语言中增加了新的功能,因此我们需要根据可用的新功能继续进行更新。

我只是注意到还没有任何人提到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中,(在那时)有一种更好的方法,用于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;
}

P.S。此方法也适用于vector

许多其他答案中已经提到了这种传统方法。

#include <iostream>

int main() {
    int array[] = { 1, 2, 3 };
    std::cout << sizeof(array) / sizeof(array[0]);
    return 0;
}

仅供参考,如果您想知道为什么在将数组传递给另一个函数时此方法不起作用。原因是,

在C ++中,数组不按值传递,而是传递指向数组的指针。由于在某些情况下,传递整个阵列可能是昂贵的操作。您可以通过将数组传递给某个函数并对该数组进行一些更改,然后再次在main中打印该数组来进行测试。您将获得更新的结果。

并且您已经知道,sizeof()函数提供字节数,因此在其他函数中,它将返回为指针分配的字节数,而不是整个数组。所以这种方法行不通。

但是我敢肯定,根据您的要求,您可以找到一种很好的方法。

快乐编码。

答案 10 :(得分:9)

而不是使用内置数组函数aka:

 int x[2] = {0,1,2};

您应该使用数组类和数组模板。尝试:

#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};

所以现在如果你想要找到数组的长度,你只需要使用数组类中的size函数。

Name_of_Array.size();

并且应该返回数组中元素的长度。

答案 11 :(得分:6)

在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 class
Reference 2 to std::array class
参考文献中的示例很有帮助。

答案 12 :(得分:3)

对于C ++ / CX(在Visual Studio中使用C ++编写UWP应用程序时),我们只需使用size()函数即可找到数组中的值数。

源代码:

string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);

如果您cout输出size_of_array

>>> 4

答案 13 :(得分:2)

以下是来自Google ProtobufArraySize的一个实现。

#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)))to size_t以确保最终结果    结果有类型size_t。

     

这个宏并不完美,因为它错误地接受了某些    指针,即指针大小可被指针整除的位置    尺寸。由于我们所有的代码都必须通过32位编译器,    其中指针是4个字节,这意味着所有指向其类型的指针    大小为3或大于4将被(正当)拒绝。

答案 14 :(得分:2)

 length = sizeof(array_name)/sizeof(int);

答案 15 :(得分:1)

使用泛型的好解决方案:

template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }

然后只需调用arraysize(_Array);即可获得数组的长度。

Source

答案 16 :(得分:1)

您可以通过以下步骤找到数组的长度:

int  arr[] = {1, 2, 3, 4, 5, 6}; 
int size = *(&arr + 1) - arr; 
cout << "Number of elements in arr[] is "<< size; 
return 0;

答案 17 :(得分:1)

我在这里提供了一个棘手的解决方案:

您始终可以将length存储在第一个元素中:

// malloc/new

arr[0] = length;
arr++;

// do anything. 
int len = *(arr-1);

free(--arr); 

费用是您在调用--arr

时必须free

答案 18 :(得分:1)

对于旧的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;
}

答案 19 :(得分:0)

避免将sizeof与sizeof一起使用,如sizeof(array)/sizeof(char),如果更改数组类型,则会突然损坏。

在visual studio中,您具有等效的sizeof(array)/sizeof(*array)。 您只需输入_countof(array)

即可

答案 20 :(得分:0)

最终寻找此问题的最常见原因之一是因为您希望将数组传递给函数,而不必为其大小传递另一个参数。您通常也希望数组大小是动态的。该数组可能包含对象,而不是基元,并且对象可能很复杂,因此size_of()是计算计数的不安全选项。

正如其他人所建议的那样,考虑使用std :: vector或list等代替原始数组。但是,在旧的编译器中,你仍然不会想到你可能想要的最终解决方案,因为填充容器需要一堆丑陋的push_back()行。如果你像我一样,想要一个包含匿名对象的单行解决方案。

如果你使用STL容器替代原始数组,这个SO帖子可能对你有用,可以用来初始化它: What is the easiest way to initialize a std::vector with hardcoded elements?

这是我使用的一种方法,它可以在编译器和平台上普遍使用:

创建一个结构或类作为对象集合的容器。为&lt;&lt;。

定义运算符重载函数
class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.push_back( o );
        return *this; 
    }
};

您可以创建将struct作为参数的函数,例如:

someFunc( MyObjectList &objects );

然后,您可以调用该函数,如下所示:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

这样,您可以在一个简洁的行中构建动态大小的对象集合并将其传递给函数!

答案 21 :(得分: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;

}

这是参考文献:http://www.cplusplus.com/reference/array/array/size/

答案 22 :(得分:0)

您有很多选项可用于获取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;

答案 23 :(得分:0)

答案:“整型数== sizeof(array)/ sizeof(array [0])”

EXPLANATION:由于编译器会为每种数据类型预留一个特定大小的内存块,而数组只是其中的一组,因此您只需将数组的大小除以数据类型的大小即可。如果我有一个由30个字符串组成的数组,那么我的系统会为该数组的每个元素(字符串)留出24个字节。在30个元素上,总共有720个字节。 720/24 == 30个元素。小型而紧凑的算法是:

“ int number_of_elements == sizeof(array)/ sizeof(array [0])”,等于;

“元素数== 720/24”

请注意,即使它是自定义数据类型,也不需要知道数组是什么数据类型。

答案 24 :(得分:0)

只是一个想法,但只是决定创建一个计数器变量并将数组大小存储在位置[0]。我删除了函数中的大部分代码,但是在退出循环后你会看到,prime [0]被分配了&#39; a&#39;的最终值。我试过使用矢量,但VS Express 2013并不是那么喜欢它。另请注意&#39; a&#39;从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;
}

答案 25 :(得分:-1)

我个人会建议(如果你因为某种原因无法使用专门的函数)首先将数组类型兼容性扩展到你通常使用它的范围之外(如果你存储值≥0:

unsigned int x[] -> int x[]

比你要使数组1元素大于你需要的数组。对于最后一个元素,您可以放置​​一些包含在扩展类型说明符中的类型,但是您通常不会使用例如使用前面的示例,最后一个元素将是-1。这使您(通过使用for循环)可以找到数组的最后一个元素。

答案 26 :(得分:-3)

假设您在页面顶部声明了一个全局数组

int global[] = { 1, 2, 3, 4 };

要找出数组中有多少元素(在c ++中),请输入以下代码:

sizeof(global) / 4;

sizeof(NAME_OF_ARRAY)/ 4将返回给定数组名称的元素数。