(1)字节序列是什么意思,C中的一个char位?UTF-16是字节序列,还是什么?(2)为什么字节序列与可变长度无关?
您似乎在误解什么是字节序问题。这是一个简短的摘要。
一个32位整数占用4个字节。现在,我们知道了这些字节的逻辑顺序。如果您使用的是32位整数,则可以使用以下代码获取其高字节:
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
一切都很好。问题开始的地方是各种硬件如何存储和从内存中检索整数。
按照Big Endian顺序,将读取您作为32位整数读取的4字节内存,第一个字节为高字节:
[0][1][2][3]
按照Little Endian的顺序,将读取您作为32位整数读取的4字节内存,第一个字节为低字节:
[3][2][1][0]
如果您有一个指向32位值的指针,则可以执行以下操作:
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
根据C / C ++,其结果是不确定的。可能是0x81。也可以是0x32。从技术上讲,它可以返回任何内容,但对于实际系统,它将返回一个或另一个。
如果您有指向内存地址的指针,则可以将该地址读取为32位值,16位值或8位值。在大字节序的机器上,指针指向高字节。在一点字节序的机器上,指针指向低字节。
请注意,这全部是关于对内存的读写。它与内部C / C ++代码无关。代码的第一个版本,即C / C ++未声明为未定义的版本,将始终可以获取高字节。
问题是当您开始读取字节流时。如来自文件。
16位值与32位值存在相同的问题;它们只有2个字节而不是4个字节。因此,文件可以包含以大端或小端顺序存储的16位值。
UTF-16被定义为16位值的序列。实际上,它是一个uint16_t[]
。每个单独的代码单元都是一个16位值。因此,为了正确加载UTF-16,您必须知道数据的字节顺序。
UTF-8定义为8位值的序列。这是一个uint8_t[]
。每个单独的代码单元的大小为8位:一个字节。
现在,UTF-16和UTF-8都允许多个代码单元(16位或8位值)组合在一起以形成Unicode代码点(“字符”,但这不是正确的术语;这是一种简化) )。的顺序形成一个码点这些代码单元是由UTF-16和UTF-8编码的决定。
在处理UTF-16时,您将读取16位值,进行任何需要的字节序转换。然后,您检测它是否是一个代理对。如果是,那么您将读取另一个16位值,将两者结合起来,然后从中获得Unicode代码点值。
处理UTF-8时,读取的是8位值。由于只有一个字节,因此无法进行字节序转换。如果第一个字节表示多字节序列,那么您将读取多字节序列中规定的一些字节。每个单独的字节都是一个字节,因此没有字节序转换。该顺序的这些字节的序列中,就如同代理对在UTF-16的顺序,由UTF-8定义。
因此,UTF-8不会有字节序问题。