如何找到阵列的长度?

Max*_*xpm 496 c++ arrays

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

Oli*_*rth 479

如果你的意思是C风格的数组,那么你可以这样做:

int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
Run Code Online (Sandbox Code Playgroud)

但这不适用于指针,即它不适用于以下任何一种情况:

int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
Run Code Online (Sandbox Code Playgroud)

要么:

void func(int *p)
{
    std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}

int a[7];
func(a);
Run Code Online (Sandbox Code Playgroud)

在C++中,如果你想要这种行为,那么你应该使用容器类; 可能std::vector.

  • 如果您将数组传递给另一个函数并尝试在那里执行它也不起作用:) (81认同)
  • @San Jacinto:不,无论你使用什么函数,都可以(在*数组*上).将一个可变长度的数组作为参数传递给函数是不可能的(它会衰变成指针) - 但如果你在结构中传递一个数组,然后按预期工作. (19认同)
  • @A_Matar - 您无法在C或C++中按值传递数组. (5认同)
  • @ 123iamking:因为上述适用于任何类型. (3认同)

Mot*_*tti 130

正如其他人所说,你可以使用sizeof(arr)/sizeof(*arr)但是这会给你错误的答案,指针类型不是数组.

template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
Run Code Online (Sandbox Code Playgroud)

这具有很好的属性,无法编译非数组类型(visual studio有_countof这样做).这constexpr使得它成为一个编译时表达式,因此它对宏没有任何缺点(至少我不知道).

您还可以考虑std::array在C++ 11中使用,它暴露其长度而不会在本机C数组上产生任何开销.

C++ 17具有std::size()<iterator>其中做同样的和适用于STL容器太(感谢报头@乔恩Ç).

  • @yau是你如何写一个_reference到array_,[见这个答案](http://stackoverflow.com/a/10008405/3848).我的版本看起来有点不同,因为我遗漏了参数的名称,因为没有使用参数,只需要它的类型.用一个名字就是`T(arg&)[N]`. (3认同)
  • https://blogs.msdn.microsoft.com/the1/2004/05/07/how-would-you-get-the-count-of-an-array-in-c-2/ (2认同)
  • @IsaacPascual我对`extent`并不熟悉,现在来看它有两个特性,使其不如上面的功能有用(对于本用例)。(1)指针返回零(而不是编译错误)。(2)它需要一个类型参数,因此要检查变量,您必须执行`decltype`。 (2认同)

Mah*_*ive 79

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

  • 不适用于指针持有的C++"新"数组.如果取消引用它,您将获得指针的大小(4个字节)或其第一个元素的大小. (4认同)
  • 这是一个非常简单易用的解决方案,可以克服看似古老的问题. (3认同)

Pra*_*rav 53

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

是!

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

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

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

PS:在C++中总是使用std::vector.有几个内置功能和扩展功能.

  • 矢量+1.很少有强大的案例可以使用旧式C++数组.除非数组的大小永远不会改变,但即使这样,你也应该使用数组容器类.最好使用像vector这样的容器类来进行动态数组存储.使用容器类的优点远远超过必须管理自己的内存的缺点. (3认同)

小智 46

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

#include <iterator>

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

  • 在 C++20 中,`std::ssize()` 可以将任何范围的 `std::size()` 作为有符号整数,这对于避免在循环中包裹恐怖、避免前者的详细转换等很有用。 (2认同)

eq-*_*eq- 28

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

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

  • 舌头可能是脸,但这几乎肯定是正确的方法. (10认同)
  • @dbliss这是因为OP询问了*数组的长度*和eq-告诉他们如何获得*vector*的长度,这在C++中是另一回事.但是,它在更深层次上是正确的,因为[如果你需要在运行时获得长度,向量是一个更好的选择](http://stackoverflow.com/q/15079057/243712). (6认同)
  • 这个答案的特别之处在于您可以使用数组文字初始化向量或列表。 (2认同)

Juk*_*kaP 26

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信这个只适用于堆栈上的局部变量. (9认同)

Jae*_*ege 23

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

  • std::rank<T>::value

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

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

    如果T是数组类型,则提供成员常量值,该常量值等于N数组中第th维的元素数,如果N是[0,则std::rank<T>::value].对于任何其他类型,或者如果T是第一维的未知边界数组且N为0,则值为0.

  • std::remove_extent<T>::type

    如果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;
}
Run Code Online (Sandbox Code Playgroud)

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

constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
Run Code Online (Sandbox Code Playgroud)

或者把它放在一个功能模板中:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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


met*_*tal 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
Run Code Online (Sandbox Code Playgroud)


gpr*_*our 16

这是一个非常古老和传奇的问题,已经有很多惊人的答案。但是随着时间的推移,语言中会添加新功能,因此我们需要根据可用的新功能不断更新内容。

我只是注意到有人还没有提到 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;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

PS 这个方法也适用vector

老的

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

#include <iostream>

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

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

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

正如您已经知道的那样,该sizeof()函数给出了字节数,因此在其他函数中,它将返回为指针而不是整个数组分配的字节数。所以这种方法行不通。

但是我相信您可以根据您的要求找到一种很好的方法来做到这一点。

快乐编码。


Mr.*_*ots 9

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

 int x[2] = {0,1,2};
Run Code Online (Sandbox Code Playgroud)

你应该使用数组类和数组模板.尝试:

#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Run Code Online (Sandbox Code Playgroud)

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

Name_of_Array.size();
Run Code Online (Sandbox Code Playgroud)

这应该返回数组中元素的长度.


小智 7

答案

int number_of_elements = sizeof(array)/sizeof(array[0])
Run Code Online (Sandbox Code Playgroud)

说明

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

int number_of_elements = sizeof(array)/sizeof(array[0]) 这相当于

number_of_elements = 720/24

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

  • 2019 年不需要这种过时且容易出错的方法。 /sf/answers/4137637451/ 而且它只是现有答案的重复。 (2认同)

Tar*_*nti 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;
}
Run Code Online (Sandbox Code Playgroud)

实际上,数组类有很多其他函数可以让我们使用数组作为标准容器.
引用1到C++ std :: array类
引用2到std :: array类
引用中的示例很有帮助.

  • 尼斯; 我看到你有很多技巧; 并且......很棒的方法.我想也应该自己写出这些着名问题的更多答案;-) (2认同)

Dav*_*son 5

sizeof(array_name)给出整个数组sizeof(int)的大小并给出每个数组元素的数据类型的大小。

因此,将整个数组的大小除以数组中单个元素的大小得出数组的长度

 int array_name[] = {1, 2, 3, 4, 5, 6};
 int length = sizeof(array_name)/sizeof(int);
Run Code Online (Sandbox Code Playgroud)


Ito*_*Ito 5

您有很多选项可用于获取 C 数组大小。

int myArray[] = {0, 1, 2, 3, 4, 5, 7};

1) sizeof(<array>) / sizeof(<type>):

std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;
Run Code Online (Sandbox Code Playgroud)

2) sizeof(<array>) / sizeof(*<array>):

std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;
Run Code Online (Sandbox Code Playgroud)

3) sizeof(<array>) / sizeof(<array>[<element>]):

std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
Run Code Online (Sandbox Code Playgroud)