【发布时间】:2009-12-10 16:25:27
【问题描述】:
假设我想从以下位置获取名称字段的字节或字符大小:
struct record
{
int id;
TCHAR name [50];
};
sizeof(record.name) 不起作用。
【问题讨论】:
-
在 C 中,就大小而言,
char和byte是同义词。
假设我想从以下位置获取名称字段的字节或字符大小:
struct record
{
int id;
TCHAR name [50];
};
sizeof(record.name) 不起作用。
【问题讨论】:
char 和 byte 是同义词。
这个问题的解决方案并不像你想象的那么漂亮:
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]))
【讨论】:
offsetof 在这里没有帮助,因为它计算偏移量,并且他需要大小(并且未指定的填充量使得它不可能从一个到另一个)。
如果您先创建一个实例,它将起作用。
record r;
sizeof(r.name);
【讨论】:
在 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++ 标准的奇妙之处:-)
【讨论】:
sizeof(record::name) 是可能会在下一个 C++ 版本 (C++0x) 中添加的功能。它还不是标准的,也不是广泛可用的。
p->f 可以,p->C::f 可以,&C::f 可以,但C::f 本身不是。对于静态类成员或命名空间非类型成员,C::f 当然是一个合法的表达式,其计算结果为左值,任何表达式都可以是sizeof 的操作数。对于类型成员,C::T 是类型引用,在sizeof 上下文中也是合法的。 C++0x 在这里新增了第三类sizeof。
record 是类型的名称,但record.name 不是。您必须以某种方式通过结构的实例访问名称。索林的回答是常用的 C 解法:
sizeof ((struct record*)0)->name;
这会创建一个指向struct record 实例(或指向伪实例的指针)的伪指针,然后访问name 成员,并将该表达式传递给sizeof。它之所以有效,是因为sizeof 不会尝试评估指针表达式,它只是使用它来计算大小。
【讨论】:
您可能想阅读this,因为它讨论了相同的问题并提供了该线程中提到的所有选项,以及更多内容。
【讨论】:
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 定义为宏的值!)
【讨论】: