【问题标题】:c++ sizeof(array) return twice the array's declared lengthc++ sizeof(array) 返回数组声明长度的两倍
【发布时间】:2012-11-02 18:27:22
【问题描述】:

我有一段代码声明了两个数组,其大小分别为 6 和 13,但是当使用 'sizeof()' 时,长度返回为 12 和 26。

#include <iostream>
using namespace std;

int main(){

    enum charRaces {DWARF,ELF,GNOME,HALFELF,HALFLING,HUMAN};
    enum classes{WARRIOR,FIGHTER,RANGER,PALADIN,WIZARD,MAGE,ILLUSIONIST,PRIEST,CLERIC,DRUID,ROGUE,THEIF,BARD};

    short int races[6] = {DWARF,ELF,GNOME,HALFELF,HALFLING,HUMAN};
    short int classes[13] = {WARRIOR,FIGHTER,RANGER,PALADIN,WIZARD,MAGE,ILLUSIONIST,PRIEST,CLERIC,DRUID,ROGUE,THEIF,BARD};

    cout << "sizeof(races)\t"  << sizeof(races) << endl;
    cout << "sizeof(classes)\t"  << sizeof(classes) << endl;

    system("pause");

    return(0);
}

【问题讨论】:

  • 在您听取了以下每个人的建议并使用sizeof(array_var)/sizeof(array_var[0]) 之后,请记住,当您将 array_var 替换为 pointer_var 时,它不起作用。如果这听起来让您感到困惑,我建议您阅读更多关于数组、指针以及它们之间的区别的内容。
  • 看看你在做什么:你声明了两个数组,一个有 6 个项目,一个有 13 个项目。然后在这些数组上调用 sizeof,可以预见的是,它返回数组中元素的数量乘以每个元素的大小。由于您将数组声明为 short int,在您的平台上,每个数组都是 16 位(或 2 个字节),编译器正确地返回 12(或 2 * 6)和 26(或 2 * 13)字节的比赛和类分别。

标签: c++ sizeof


【解决方案1】:

sizeof 返回变量的大小(在本例中为数组),其中 sizeof(char) 为 1。由于 char 是一个字节宽,sizeof 返回变量的大小(以字节为单位)。由于每个short int 在您的系统上都是两个字节宽,因此包含 6 个的数组大小为 12,包含 13 个的数组大小为 26。

【讨论】:

  • 是的,但在这种情况下,“字节”仅在无符号字符为 8 位长时表示“8 位”。
  • @slavik262 在 C 中,一切都是根据 sizeof(char) 定义的,即定义为 1。如果字符大于 1 字节,您将拥有一个平台,其中没有足够小的类型来表示1 个字节。这是合法的,但很奇怪。
  • 无符号字符中的位数由limits.h中的CHAR_BIT指定。 sizeof (unsigned char) 将始终计算为 1。
  • @slavik262, John Kugelman: sizeof(char) 在 §5.3.3 中定义为 1。在 C++11(第 1.7 节)中,一个字节至少为 8 位宽。
  • @JohnKugelman 这不合法;正如 DyP 所说,C++ 定义 sizeof 以“以字节为单位”返回大小(对于 C++ 自己的字节定义),sizeof(char) 为 1。当然,C++ 定义的字节可能不是硬件工程师的字节对于给定的平台会想到它。
【解决方案2】:

sizeof 返回以字节为单位的大小,对于数组来说,它是项目数 × 每个项目的大小。得到项目数除以一个元素的大小。

sizeof(races) / sizeof(races[0])

对此要小心。它仅适用于在编译时大小已知的数组。这不起作用:

void func(short int array[])
{
    // DOES NOT WORK
    size_t size = sizeof(array) / sizeof(array[0]);
}

这里array实际上是一个short int *,而sizeof(array)不返回数组的实际大小,这在编译时是未知的。

这是在 C++ 中使用 std::vectorstd::array 而不是原始数组的众多原因之一。

【讨论】:

  • 在什么情况下会用到这个?如果您正在分配一个非固定大小的数组,您会知道(或在某些时候计算)成员的数量。更好的是,您可以使用vector
  • @slavik262 如果您在某处有一个常量数组,这种代码将使您不必分别更新数组和项目数。
  • 你也可以使用std::array
  • @slavik262 是的,你知道大小。但是,如果没有除法,您必须记住在发生变化时更新数组和大小字段。
  • @slavik262 OP 可以省略明确的613,这个技巧仍然有效。
【解决方案3】:

sizeof 返回数组使用的实际内存(以字节为单位)。一个相当常见的习惯用法是这样做:

short int races[6] = {DWARF,ELF,GNOME,HALFELF,HALFLING,HUMAN};
size_t num_races = sizeof(races) / sizeof(races[0]);

num_races 然后将数组中的元素数存储在其中。

【讨论】:

    【解决方案4】:

    sizeof 是 C++ 中的一个运算符,用于测量字节数的大小。我认为在您的机器整数中占用 2 个字节,这就是为什么它显示数组大小的两倍。

    【讨论】:

    • 它显示 2x,因为他使用的是无符号 short 整数数组,在他的平台上是 16 位宽。他平台上的机器整数可能是 32 位。
    【解决方案5】:

    sizeof 运算符以单位为单位测量,因此 unsigned char 为 1 个单位。

    在您的平台上,short 是 char 的两倍,因此是您看到的结果。

    要正确确定数组长度,您可以使用如下宏:

    #define ARRAY_LEN(ary) (sizeof (ary) / sizeof (ary[0]))
    

    【讨论】:

      【解决方案6】:

      sizeof 运算符返回表示类型所需的字节大小(在编译时)。

      double array[10]; // type of array is: double[10]
      

      sizeof(array)sizeof(double[10])含义相同,等于:

      sizeof(double) * 10
      

      这是一个可以容纳 10 个双精度值的数组。 sizeof(array[0]) 表示:数组中单个元素的大小,与这里的sizeof(double) 相同。要获得实际的元素数量,您必须将数组的大小除以单个元素的大小:

      size_t num_elem = sizeof(array) / sizeof(array[0]);
      

      但是,这不适用于指针!

      double* p = array;
      

      sizeof(p) 实际上转换为sizeof(double*)。它的大小与 double 的大小或它指向的数组的大小无关。 相反,它是将地址存储到内存位置所需的大小(32 位操作上的 32 位)。元素个数的信息丢失了!

      如果你想安全地获取数组中的元素个数,可以使用这个模板:

      template<typename T, size_t N>
      size_t inline static_arrlen(T (&)[N]) {
          return N;
      }
      

      在编译时,推导出类型 T 和元素个数 N,返回 N。

      size_t num_elem = static_arrlen(array); // T=double, N=10
      

      如果您试图从指针获取数组大小,它将无法编译:

      static_arrlen(p); // ERROR: could not deduce template argument 
                        // for 'T (&)[N]' from 'double *'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-16
        • 2013-02-17
        • 2012-12-17
        相关资源
        最近更新 更多