数据类型的大小和sizeof(数据类型)之间的区别

4
我正在学习C++,遇到了以下问题。我只是一个初学者,感到困惑。sizeof()函数不应该返回数据类型的大小吗?为什么数据对象的大小可以与其sizeof()不同?我不理解答案的解释。
假设在一个虚拟机器中,char的大小为32位。sizeof(char)会返回什么?
a)4
b)1
c)实现相关
d)机器相关
答案:b
解释:标准并不要求char为8位,但要求sizeof(char)返回1。

4
不,根据定义,'char' 是 1 字节。在那个系统中,一个字节是 32 位。 - Keith Thompson
即使在那种情况下,它也不会是“32”。最坏的情况下可能会认为它是“4 = 32/8”。 - Eugene Sh.
1
@KennethChen:你的老师们错了。一个有8个比特的类型是八位组。字节的宽度取决于机器。只是大多数架构现在都有8位/字节而已。几十年前,例如9位是相当常见的。在一些DSP上,它仍然有例如24位的情况。 - too honest for this site
1
@Olaf:一个人永远不会太老去学习。我在大约20年后放弃了这个习惯...;-) - alk
1
@alk:在Plasma中:按下Alt-F2(命令行弹出),输入例如wp:byte(回车);实际上是小写。将打开带有给定搜索短语的WP。对于例如gg:byteleo:nette sache也是如此。如果我不得不在Windows上工作,我最想念的事情之一。它实际上被称为“Webshortcuts” /“Web-Kürzel”。 - too honest for this site
显示剩余28条评论
6个回答

12
sizeof 运算符返回一个类型的大小,以字节为单位。其中,一个字节被定义为 char 的大小。因此,sizeof(char) 始终是1,无论在给定平台上 char 有多少个位。
这适用于C和C++。
从C11标准的6.5.3.4中可知:
2. sizeof 运算符返回其操作数的大小(以字节为单位),其操作数可以是表达式或带括号的类型名称。大小是从操作数的类型确定的...
根据规则:
4. 当 sizeof 应用于具有类型 char、unsigned char 或 signed char(或它们的限定版本)的操作数时,结果为1。
从C++11标准的5.3.3中可知:
sizeof 运算符返回其操作数的对象表示中的字节数。 操作数是表达式,它是未评估的操作数(第5条),或者是带有括号的类型标识符... ...
重点是:sizeof(char)sizeof(signed char)sizeof(unsigned char) 都是1。

@alk 可能是对 C 和 C++ 标准不熟悉的人 :-) - juanchopanza
@ Slava我已经说过字节的意思了。它是char的大小。这应该很容易理解。 - juanchopanza
1
不,这并不简单易懂。如果您说硬盘在 char 由 32 位表示的平台上是 2TB,那么这是否意味着该硬盘上的每个字节都是 32 位? - Slava
@juanchopanza,我知道怎么读,我只是试图向你解释,对于某些人来说,你的答案可能会误导他们,因为“byte”一词被广泛使用。看看Superlokkus的答案,他说这种对“byte”理解是普遍的,这至少值得怀疑。所以肯定存在困惑。 - Slava
不仅仅是因为有人不喜欢你对“字节”这个定义的解释,所以你很可能会被踩。 - Slava
显示剩余7条评论

3

5.3.3 [expr.sizeof]规定:

sizeof操作符返回其操作数的对象表示所占用的字节数。 操作数可以是表达式(未求值的操作数(Clause 5))或带括号的类型标识符。 不得将sizeof操作符应用于具有函数或不完整类型的表达式,枚举类型在所有枚举器声明之前其基础类型未固定,带有此类类型名称的带括号表达式或指代位域的glvalue。sizeof(char), sizeof(signed char)和sizeof(unsigned char)都为1。[...]

以上强调部分为本人添加

因此,无论一个char占用多少位,它的大小始终为1。


@juanchopanza 在这个情境下,字节/位数真的很重要吗? - πάντα ῥεῖ
2
@πάνταῥεῖ 是的,因为“一个字符占用多少字节”只能是一个。 - juanchopanza
2
@πάνταῥεῖ:当然很重要。为什么不重要呢? - Keith Thompson

3
你只是混淆了字节和八位组之间的区别
一个字节是一个字符的大小。这导致始终为真的 sizeof(char) == 1,因为sizeof返回的是以字节为单位的大小。
而一个八位组8位组成。
在几乎所有现代平台上,字节的大小巧合地与八位组的大小相同。这就是为什么混淆它们是一种常见的错误,甚至连书籍作者和教授也会犯这个错误的原因。

我担心你会让它变得更加混乱。术语“byte”不仅在C或C++中使用,那里它的意思与“octet”相同。 - Slava
@Slava,你能证明在C/C++标准中,字节的大小是固定的吗? - Superlokkus
我指的是其他地方,不是C/C++。抱歉让您感到困惑。 - Slava
不,byte != octet它们有不同的定义,了解区别有时很重要。但我以为他的第三条评论(也是我的答案)是他发的,所以我打错了赌注。 - Superlokkus
在C/C++中,byte不等于octet。在Java和C#中,byte等于8位。当你说硬盘大小为2TB时,byte等于8位。我认为C/C++并不是使用这个术语的垄断者。 - Slava

2

sizeof(x) 返回的是以 char 大小为单位表示的 x 的大小。


0

没有计算机的sizeof(char)是4。它总是1个字节。该字节可能包含32位,但就C编译器而言,它是一个字节。

"8个比特"的正确名称是八位组。C标准使用“字节”一词表示char大小的对象。其他人可能在不同的情况下使用“字节”这个词,通常是指“八位组”,但在C(和C++或Objective-C)中,它表示“char大小的对象”。Char可能超过8位,或超过一个八位组,但它始终是一个字节。


-1

这个问题应该是——在一个假想的机器中,字长(寄存器大小)为32位。那么sizeof(char)会返回什么?

答案是1字节

在计算机领域,字是指特定处理器设计所使用的自然数据单位。字是按指令集或处理器硬件处理的一块固定大小的数据单元。字中的位数(字长或字宽)是任何特定处理器设计或计算机体系结构的重要特征。--https://en.wikipedia.org/wiki/Word_%28computer_architecture%29

在您的情况下,字长将是32位。同时

历史上,字节是用于在计算机中编码单个字符文本的比特数,因此在许多计算机体系结构中,它是最小的可寻址内存单元。--https://en.wikipedia.org/wiki/Byte

1字节是内存中最小可寻址单元,它可以是8位、9位或16位,具体取决于硬件规格。

sizeof而言,它首先确定参数的类型,最终计算出以字节为单位的大小。因此,以下两个C++语句将产生相同的结果。

  int n;
  std::cout<<sizeof(int);
  std::cout<<sizeof(n);

2
给出的问题是完全有效的。它假设char是32位。这与字或寄存器的大小无关。 - Keith Thompson
标准还规定了charCHAR_BIT位,其中CHAR_BIT >= 8。而一个“字”可以由多个字节组成,因此你认为问题应该指定字长的建议并不太合理。 - Keith Thompson
@GautamJha 根据C语言规定,char类型的大小为1字节,而不是反过来。因此,无论char使用多少空间(可能是32位),它始终返回1。 - Srujan Barai
根据C语言的定义,char类型的大小为一个字节,而字节的定义超出了C语言的范围。因此,这个说法是错误的。 - g-217
不,"byte"的定义并不是“超出C的范围”。ISO C标准的最新草案是N1570.pdf。"byte"的定义在第3.6节中:“可寻址的数据存储单元,足以容纳执行环境基本字符集中的任何成员。”C++标准有类似的定义。在其他上下文中,“byte”这个词可能会被使用得不同,但这就是C和C++标准中它的用法。 - Keith Thompson
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接