如何找到int []的大小?

ada*_*dam 43 c++ arrays

我有

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

如何获得大小list

我知道对于char数组,我们可以strlen(array)用来查找大小,或者'\0'在数组末尾检查.


我尝试sizeof(array) / sizeof(array[0])了一些答案,但它只适用于主?例如:

int size(int arr1[]){
    return sizeof(arr1) / sizeof(arr1[0]);
}

int main() {
    int list[] = {1, 2, 3};

    int size1 = sizeof(list) / sizeof(list[0]); // ok
    int size2 = size(list_1); // no
    // size1 and size2 are not the same
}
Run Code Online (Sandbox Code Playgroud)

为什么?

Pra*_*rav 53

试试这个:

sizeof(list) / sizeof(list[0]);
Run Code Online (Sandbox Code Playgroud)

因为这个问题被标记为C++,所以总是建议std::vector在C++中使用而不是使用传统的C风格数组.


一个array-type被隐式转换成pointer-type当您将它传递给一个函数.看看 这个.

为了在任何函数内正确打印数组的大小,通过引用该函数传递数组(但您需要事先知道该数组的大小).

对于一般情况,你会这样做

template<typename T,int N> 
//template argument deduction
int size(T (&arr1)[N]) //Passing the array by reference 
{
   return sizeof(arr1)/sizeof(arr1[0]); //Correctly returns the size of 'list'
   // or
   return N; //Correctly returns the size too [cool trick ;-)]
}
Run Code Online (Sandbox Code Playgroud)


Car*_*icz 13

"标准"C方式是这样做的

sizeof(list) / sizeof(list[0])
Run Code Online (Sandbox Code Playgroud)

  • 显然是的,因为你问的是C++.很多其他答案. (2认同)

ava*_*kar 10

您可以使用boost::size,这基本上是这样定义的:

template <typename T, std::size_t N>
std::size_t size(T const (&)[N])
{
    return N;
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果要将大小用作常量表达式,则必须使用该sizeof a / sizeof a[0]惯用法或等待下一版本的C++标准.

  • C++不是最棒的语言吗?:) (3认同)

Meh*_*ari 8

对于动态分配的数组(或指针),您不能这样做.对于静态数组,您可以使用sizeof(array)以字节为单位获取整个数组大小,并将其除以每个元素的大小:

#define COUNTOF(x) (sizeof(x)/sizeof(*x))
Run Code Online (Sandbox Code Playgroud)

要获得动态数组的大小,您必须手动跟踪它并将其传递给它,或者使用sentinel值终止它(如在空终止字符串中使用'\ 0').

更新:我意识到你的问题被标记为C++而不是C.你应该考虑std::vector在C++中使用而不是数组,如果你想传递一些东西:

std::vector<int> v;
v.push_back(1);
v.push_back(2);
std::cout << v.size() << std::endl; // prints 2
Run Code Online (Sandbox Code Playgroud)


Dir*_*tel 5

除了 Carl 的回答之外,“标准”C++ 方法不是使用 Cint数组,而是使用 C++ STL 之类的东西std::vector<int> list,您可以查询list.size().


Jer*_*fin 5

由于您已将其标记为C ++,所以值得一提的是,还有一种比C样式宏更好的方法:

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

这样做的好处是,如果您不小心尝试将非数组的内容传递给它,则代码将根本无法编译(而将指针传递给C宏将进行编译,但会产生不好的结果。缺点是这样做不会) t给你一个编译时常量,所以你不能做这样的事情:

int a[20];

char x[countof(a)];
Run Code Online (Sandbox Code Playgroud)

在C ++ 11或更高版本中,您可以添加constexpr以获取编译时常量:

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

如果您真的想在较​​旧的编译器上支持相同的功能,则有一种方法最初由AFAIK的Ivan Johnson发明:

#define COUNTOF(x)  (                                           \
  0 * sizeof( reinterpret_cast<const ::Bad_arg_to_COUNTOF*>(x) ) +  \
  0 * sizeof( ::Bad_arg_to_COUNTOF::check_type((x), &(x))      ) +  \
  sizeof(x) / sizeof((x)[0])  )                                  


class Bad_arg_to_COUNTOF
{
public:
   class Is_pointer;
   class Is_array {};  
   template<typename T>
   static Is_pointer check_type(const T*, const T* const*);
   static Is_array check_type(const void*, const void*);
};
Run Code Online (Sandbox Code Playgroud)

就像C宏一样,它使用sizeof(x)/ sizeof(x [0])计算大小,因此它提供了一个编译时常数。区别在于,如果您传递的不是数组名称,则它首先使用一些模板魔术来导致编译错误。它通过重载check_type以返回指针的不完整类型,但返回数组的完整类型来实现。然后(真正棘手的部分)实际上根本没有调用该函数-它只占用函数将返回的类型的大小,对于返回完整类型的重载,该大小为零,但不允许(强制执行不完整的类型。

IMO,这是模板元编程的一个很酷的例子-尽管老实说,结果是毫无意义的。如果使用数组,实际上只需要该大小作为编译时间常数,在任何情况下通常都应避免使用该大小。使用std::vector,可以在运行时提供大小(并在需要时调整向量的大小)。