C11标准(及更高版本)的3.6节将“字节”定义为“用于保存...字符的数据存储的可寻址单元”。
C ++ 11标准的1.7节(及更高版本)将“字节”定义为“内存模型中的基本存储单元,以包含...字符”。
两种定义都没有说“字节”是最小可寻址单元。这是因为标准有意要从特定计算机中抽象吗?您能否提供一个机器的真实示例,其中C / C ++编译器被确定为“字节”长于或短于最小可寻址单元?
字节是严格符合C代码的最小可寻址单元。与C实现在其上执行程序的机器是否支持寻址较小的单元无关。 C实现必须提供一个视图,其中字节是严格符合C代码的最小可寻址单元。
C实现可能支持将较小的单元作为扩展来寻址,例如仅通过定义某些指针操作的结果即可,否则这些指针是C标准未定义的。
8051系列是最小可寻址单元小于一个字节的真实计算机及其编译器的一个示例。我习惯的一个编译器是Keil C51。
最小可寻址单元是一点。您可以定义此类型的变量,可以对其进行读写。但是,定义变量的语法是非标准的。当然,C51需要几个扩展来支持所有这些。顺便说一句,not允许指向位的指针。
例如:
unsigned char bdata bitsAdressable;
sbit bitAddressed = bitsAdressable^5;
void f(void) {
bitAddressed = 1;
}
bit singleBit;
void g(bit value) {
singleBit = value;
}
两个定义都没有说“字节”是最小可寻址单元。
那是因为他们不需要。按字节类型(char
,unsigned char
,std::byte
等)具有强制执行此要求的足够限制。
按字节类型的大小为explicitly defined to be precisely 1:
sizeof(char),sizeof(有符号字符)和sizeof(无符号字符)为1。
按字节类型is the smallest alignment possible的对齐:
此外,窄字符类型(6.9.1)应具有最弱的对齐要求
当然,这不必是1的对齐方式。除了...确实如此。
例如,如果对齐方式大于1,则意味着简单的字节数组将无法工作。数组索引基于指针算法,指针算法根据sizeof(T)
确定下一个地址。但是,如果alignof(T)
大于sizeof(T)
,则T
的任何数组中的第二个元素都将未对齐。不允许的。
因此,即使标准没有明确指出字节类型的对齐方式是1,其他要求也必须确保它必须是。
总体上,这意味着指向对象的每个指针都具有至少与按字节类型一样严格的对齐方式。因此,相对于按字节类型的对齐,没有对象指针可以对齐。因此,所有有效的非NULL指针(指向活动对象或末尾指针的指针)必须至少足够对齐以指向char
。
类似地,两个指针之间的差异为defined in C++,因为这些指针所指向的元素的数组索引之间的差异(C ++中的指针算法要求两个指针指向同一数组)。如前所述,附加指针算法基于所指向的类型sizeof
。
鉴于所有这些事实,即使实现的指针地址可以小于char
的值,从功能上[[不可能 C ++抽象模型生成指针,并且该指针计数仍然有效(指向对象/函数,数组的末尾或为NULL)。您可以使用从整数强制转换来创建这样的指针值。但是您将创建一个无效的指针值。
显然,编译器扩展可以执行任何操作。但是就符合标准的程序而言,根本不可能生成针对字节类型未对齐的有效指针。
[C0并没有真正直接访问各个位的方法,因为从(标准)C语言的角度来看,该字节仍然是前一篇文章中指出的最小单位。
因此,如果要读取/写入C语言中的位流,则需要一次(至少)读取和写入一个字节并缓冲(例如,在编写算术或霍夫曼编码器时)。