【问题标题】:Is there a way to introspect an array's size?有没有办法自省数组的大小?
【发布时间】:2010-05-22 18:13:55
【问题描述】:

在 C++ 中,给定一个这样的数组:

unsigned char bogus1[] = {
  0x2e, 0x2e, 0x2e, 0x2e
};

有没有办法自省 bogus1 找出是四个字符长?

【问题讨论】:

标签: c++ arrays introspection


【解决方案1】:

当然:

#include <iostream>

int main()
{
  unsigned char bogus1[] = {
    0x2e, 0x2e, 0x2e, 0x2e
  };

  std::cout << sizeof(bogus1) << std::endl;

  return 0;
}

发射4。更一般地说,sizeof(thearray)/sizeof(thearray[0]) 是数组中的项目数。但是,这是一个编译时操作,只能在编译器知道该“项目数”的情况下使用(例如,在将数组作为参数接收的函数中)。为了更通用,您可以使用 std::vector 代替裸数组。

【讨论】:

  • "接收数组作为参数的函数" - 小心,它需要是一个 reference 参数。直接在参数声明中命名数组类型会导致指针类型衰减,这会导致 sizeof 商具有不希望的、实现定义的行为。
  • 所以,如果我执行“std::clog
  • WilliamKF:因为那毫无意义:您应该只使用 std::string 代替。在编译时知道字符串长度的极少数情况不值得您建议增加复杂性。
  • @WilliamKF, std::clog &lt;&lt; ... 是“将数组作为参数接收的函数”的一个示例(通过引用,正如 potatoswatter 提到的那样——在这种情况下特别是 const 引用)——在这种情况下,问题是operator&lt;&lt;(std::ostream&amp;, const char[]&amp;)。正如我所提到的,它不能“反省”其论点的大小。 Stefan 是正确的,你应该使用 std::string 来处理这类事情(我提到 std::vector 是一种更通用的方法,尤其是当项目不是 chars 时;-)。
  • @Alex,是这样吗?我相信该数组已衰减为指向第一个元素的指针,实际匹配的签名是:operator&lt;&lt;( std::ostream&amp;, const char* ) 如果函数通过引用获取数组(无论是否为常量),则必须在参数数组大小中进行模板化对于动态分配的 c 字符串,必须是不同的函数。
【解决方案2】:

sizeof 需要注意的一件事是确保您不会意外地对已衰减为指针的数组进行 sizeof:

void bad(int a[10])
{
    cout << (sizeof(a) / sizeof(a[0])) << endl;
}

int main()
{
    int a[10];
    cout << (sizeof(a) / sizeof(a[0])) << endl;
    bad(a);
}

在我的 64 位机器上,输出如下:

10
2

bad 内部计算的大小不正确,因为a 将衰减为指针。一般来说,不要相信 sizeof 一个作为函数参数传递的数组。

【讨论】:

    【解决方案3】:
    int bogus1_size = sizeof(bogus1) / sizeof(unsigned char);
    

    【讨论】:

    • 我建议写成sizeof(bogus1) / sizeof(bogus1[0]);这样,您就不会在 bogus1 的定义和您的大小计算之间意外地有不同的类型。
    【解决方案4】:

    这解决了指针衰减问题:

    #include <cstddef>
    
    template<typename T, std::size_t N>
    std::size_t array_size(T(&)[N]) { return N; }
    

    除非数组大小已知,否则它不会编译。

    【讨论】:

    • 是的,通过模板使用,std::stringstream 似乎可以了解数组长度,而不是跑完。
    • @William:可能,但它几乎肯定会忽略任何空终止符,这在打印字符串时是出乎意料的。
    猜你喜欢
    • 2020-10-05
    • 1970-01-01
    • 2011-06-12
    • 2020-02-20
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    相关资源
    最近更新 更多