【问题标题】:Getting the size in bytes or in chars of a member of a struct or union in C/C++?在 C/C++ 中获取结构或联合成员的字节或字符大小?
【发布时间】:2009-12-10 16:25:27
【问题描述】:

假设我想从以下位置获取名称字段的字节或字符大小:

struct record
{
    int id;
    TCHAR name [50];
};

sizeof(record.name) 不起作用。

【问题讨论】:

  • 在 C 中,就大小而言,charbyte 是同义词。

标签: c++ c unicode sizeof


【解决方案1】:

这个问题的解决方案并不像你想象的那么漂亮:

size_in_byte = sizeof(((struct record *) 0)->name)

size_in_chars = _countof(((struct record *) 0)->name)

如果您想在 Windows 以外的其他平台上使用第二个,请尝试:

#define _countof(array) (sizeof(array)/sizeof(array[0]))

【讨论】:

  • 这不一定是可移植的。在 C 中,您需要“offsetof”宏。如果您确实使用此表格,请阅读 c-faq.com/struct/offsetof.html 的 cmets。
  • @Alok:这确实不能保证便携,但offsetof 在这里没有帮助,因为它计算偏移量,并且他需要大小(并且未指定的填充量使得它不可能从一个到另一个)。
  • 是的,我在发布我的愚蠢评论后不久就意识到了这一点(以及对 OP 问题的更愚蠢的回答!)。
【解决方案2】:

如果您先创建一个实例,它将起作用。

record r;
sizeof(r.name);

【讨论】:

  • 至少,它简单便携。
  • 抱歉,这是不可能的,至少在 C 语言中是不可能的。
【解决方案3】:

在 C++ 中:

#include <iostream>
using namespace std;;

struct record
{
    int id;
    char name [50];
};

int main() {
    cout << sizeof( record::name) << endl;
}

编辑: 有几个人指出这是 C++0x 代码,所以我想我必须收回我对 VC++ 的不友好评论。这不是我在自己的 C++ 代码中使用过的编程结构,但我想知道为什么 sizeof 在 C++03 中不能以这种方式工作?你给它一个名字,它就会给你尺寸。我原以为它需要一些努力才能让它不起作用。但这就是 C++ 标准的奇妙之处:-)

【讨论】:

  • 你忘了返回一个整数。
  • 在 C++ 中,main() 不必有特定的返回值。
  • 放弃 cygwin 并切换到 MinGW 是我的建议。
  • sizeof(record::name) 是可能会在下一个 C++ 版本 (C++0x) 中添加的功能。它还不是标准的,也不是广泛可用的。
  • 没有。这里的问题不是限定本身,而是在 C++03 中,在除成员访问或指向成员的指针之外的任何上下文中引用非静态成员都是不合法的。所以p-&gt;f 可以,p-&gt;C::f 可以,&amp;C::f 可以,但C::f 本身不是。对于静态类成员或命名空间非类型成员,C::f 当然是一个合法的表达式,其计算结果为左值,任何表达式都可以是sizeof 的操作数。对于类型成员,C::T 是类型引用,在sizeof 上下文中也是合法的。 C++0x 在这里新增了第三类sizeof
【解决方案4】:

record 是类型的名称,但record.name 不是。您必须以某种方式通过结构的实例访问名称。索林的回答是常用的 C 解法:

sizeof ((struct record*)0)->name;

这会创建一个指向struct record 实例(或指向伪实例的指针)的伪指针,然后访问name 成员,并将该表达式传递给sizeof。它之所以有效,是因为sizeof 不会尝试评估指针表达式,它只是使用它来计算大小。

【讨论】:

    【解决方案5】:

    您可能想阅读this,因为它讨论了相同的问题并提供了该线程中提到的所有选项,以及更多内容。

    【讨论】:

    • 我可能会,也可能不会。也许你可以暗示我为什么会选择前者。
    【解决方案6】:
    struct record
    {
        static const int kMaxNameChars=50;
        int id;
        TCHAR name [kMaxNameChars];
    };
    
    
    sizeof(TCHAR)*record::kMaxNameChars //"sizeof(record.name)"
    //record::kMaxNameChars sufficient for many purposes.
    

    便携、完全安全且 IMO 明确说明原始数组长度是一种很好的做法。

    (编辑:如果编译器对可变数组长度感到不安,您可能必须在 C 中对其进行宏化。如果这样做,请考虑将静态 const int 定义为宏的值!)

    【讨论】:

      猜你喜欢
      • 2016-03-06
      • 2013-05-13
      • 2017-10-22
      • 2018-01-20
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      相关资源
      最近更新 更多