在C语言中,sizeof返回的是一个类型所占用的字节数或八位组数?

24

简单来说,对于 C 和其变体(不像 Java 那样使用虚拟机),原始数据类型在不同目标上的大小可以差异很大,并且只有在使用 stdint.h 中定义的固定宽度类型时才能保证,即使如此,你的实现也必须支持它们。

假设(因为在大多数现代计算机中一个字节是八位,用于网络目的我假设是 ASCII),sizeof 返回数据类型的大小是以字节还是以八位字节为单位?


3
字节是计算机存储单位,一个字节可以用一个字符(char)表示,一个字符有CHAR_BITS位。如果你想要知道一个类型T占用的八位组数(octets),可以使用公式sizeof(T) * CHAR_BITS / 8。在大多数平台上,CHAR_BITS等于8 - GManNickG
2
@GManNickG CHAR_BIT(没有S) :) - Praetorian
浮点数 octetPercent = sizeof(T) * CHAR_BIT / 8.0; - awiebe
1
请注意,POSIX和Windows(即基本上99.999%的非DSP系统)都要求一个字节是八位字节,因此这个问题主要是出于追求严谨性/语言法律方面的兴趣。 - R.. GitHub STOP HELPING ICE
1
你理解得很好,这就是为什么它说是假设的。 - awiebe
4个回答

29

答案: sizeof运算符返回字节数而非位数。


例如:sizeof(char)一定是1,但这并不意味着它是一个八位组(8 bits)。


标准证明:

在6.5.3.4的第2点中:

sizeof运算符得出其操作数的大小(以字节为单位),其可以是表达式或类型的括号名称。大小由操作数的类型确定。结果是一个整数。如果操作数的类型是变长数组类型,则对操作数进行求值;否则,不对操作数求值,结果是一个整数常量。

...

当应用于类型为char、unsigned char或signed char(或其限定版本)的操作数时,结果为1。 当应用于具有数组类型的操作数时,结果是数组中的总字节数。当应用于具有结构或联合类型的操作数时,结果是此对象中的所有字节的总数,包括内部和尾随填充。

另外,在第3.6节的第3点中:

一个字节由一系列连续的比特组成,其数量由实现定义


为什么sizeof(char) = 1? - Connor Fuhrman
1
@ConnorFuhrman 这是定义:3.7.1: 字符:单字节字符,对于sizeof:6.5.3.4 sizeof运算符:[...] 当应用于具有char、unsigned char或signed char类型(或其限定版本)的操作数时,结果为1 - Z4-tier

7

sizeof 总是返回以字节为单位的大小。但根据wikipedia

在编程语言 C 和 C++ 中,一元运算符 sizeof 用于计算任何数据类型的大小,以表示该类型所需的字节数为度量单位。在此上下文中,一个字节与无符号字符相同,可能大于8位,尽管这种情况并不常见


7

sizeof 会返回以字节为单位的大小。然而需要注意的是,“byte”是C标准中的技术术语,并且被定义为 sizeof(char) == 1


2

从我的经验来看,在使用带有奇特“C”编译器的嵌入式微控制器上工作时,我见过:

sizeof( uint8 )

返回1

sizeof( uint16 )

返回1

sizeof( uint32 )

返回 2

显然,我处理的是一个最小可寻址单元为16位的机器,所以sizeof不符合C89或C99标准。

我会说,在主流的C89和C99兼容系统上,接受的答案是正确的。 不幸的是,即使它不符合25年前的标准,仍然可以称之为“C”编译器。我希望这个答案能够在考虑到更奇特的系统时有所帮助。


1
你为什么认为这不符合标准?如果char宽度为16位,那么这正是我所期望的。如果最小可寻址实体为16位,那么uint8_t必须占用至少16位(因此sizeof(uint8_t) == sizeof(uint16_t))也是有道理的。 - Al Gebra
1
这是一个很好的答案,它揭示了微妙之处。要点是:检查<limits.h>中的CHAR_BIT并将其与sizeof(char)进行比较以供参考。在所有严格技术情况下,字节都是8位,除非(软件表示不是)CHAR_BIT不等于8。由于“C”从CHAR_BIT派生出其字节定义。在您的16位最小可寻址大小的情况下,我敢打赌CHAR_BIT被设置为16。你能证实一下吗? - Timothy L.J. Stewart

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