如何检查函数中的数组长度?

时间:2020-09-08 06:23:26

标签: c++

在我的文件中,我创建了函数长度,该函数长度必须返回自动类型数组的长度,而不是每次返回1时都要正确回答。

Use one of the following commands:
clickhouse local [args] 
clickhouse client [args] 
clickhouse benchmark [args] 
clickhouse server [args] 
clickhouse extract-from-config [args] 
clickhouse compressor [args] 
clickhouse format [args] 
clickhouse copier [args] 
clickhouse obfuscator [args] 

4 个答案:

答案 0 :(得分:2)

您正在使用C样式数组,并且无法复制此类型。 如果我们假设您的编译器的版本支持 auto个参数,就好像它有一个template参数 在这里可以推导为int *,因为相反 复制后,C样式的数组会衰减为int *

在这种情况下,sizeof(arr)sizeof(int *),可能是 在32位系统上为4,在64位系统上为8。 sizeof(*arr)sizeof(int),在大多数系统上可能是4。 因此,sizeof(arr)/sizeof(arr[0])中的length() 总是给1或2。

如果要使用这样的函数返回元素数 数组,您可以使用std::array()类型 评论建议。

另一种方法是提供模板功能 知道数组的常量(在编译时已知)大小。

/**
  g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
      -pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
      -g -O0 -UNDEBUG -fsanitize=address,undefined
**/

#include <iostream>

template<typename T,
         int N>
int
length([[maybe_unused]] const T(&arr)[N])
{
  return N;
}

int 
main()
{
  int arr[] = {1,2,3,4,5,0};
  std::cout << length(arr) << '\n'; 
  return 0;
}

答案 1 :(得分:1)

是的,您已经成为经典阵列衰减问题的受害者。

当具有接收数组的函数时,C会将其作为指针传递,因为“数组”不是可传递的数据类型。您得到1是因为sizeof(arr) == sizeof(size_t) == sizeof(*arr) == sizeof(int),所以sizeof(arr) / sizeof(*arr) == 1

不幸的是,无法在子函数中找到C样式数组的长度。但是,您可以执行一些操作:

  1. 您也可以将长度传递给函数。不幸的是,如果您要一个长度函数,这是很失败的。但是,它用于许多需要支持空字节的C样式应用程序。

  2. 您可以使用C ++样式std::array,该样式允许您使用size()查找数组的大小。这使您无需使用C恶作剧就可以创建数组。您还可以使用std::vector,它是可变大小而不是固定大小。

答案 2 :(得分:1)

将数组直接传递给函数是不可能的(按值表示),尝试这样做是将指针传递给它的第一个元素。其他答案已经解释了这一点。

您可以做的是传递参考:

int length(const auto &arr)
{
    return sizeof(arr) / sizeof(*arr);
}

这适用于数组,但对于指针,标准容器等却给出错误的结果。

要使其更加防弹,可以对其进行重写以使其仅接受对数组的引用:

template <typename T, std::size_t N>
std::size_t length(const T (&)[N])
{
    return N;
}

但是我们已经有一个标准函数可以执行此操作,它称为std::size。而且使用容器也很麻烦。

答案 3 :(得分:1)

您的代码完全可以编译是因为您的编译器(gcc?)支持非标准扩展。

最好使用标准容器(例如,Output如果大小在运行时确定,或者std::vector<int>如果大小在编译时确定)。

但是,对于使用原始数组并给出其大小的函数,您可以简单地传递引用;

std::array<int, 6>

 int length(const auto &arg) {return sizeof(arr)/sizeof(*arr);}

根据您的需要,也可以将功能设置为 template<int N> int length(const int (&arr)[N]) { return N; } constexpr

在C ++ 17和更高版本中,只需使用辅助函数noexcept(在各种标准标头中提供,例如std::size(),并可以使用原始数组和标准容器)

<iterator>