在过去的几天里,我一直在阅读有关 Unicode 和 UTF-8 的内容,并且经常遇到与此类似的按位比较:
int strlen_utf8(char *s)
{
int i = 0, j = 0;
while (s[i])
{
if ((s[i] & 0xc0) != 0x80) j++;
i++;
}
return j;
}
有人可以澄清与 0xc0 的比较并检查它是否是最高有效位吗?
谢谢你!
编辑:ANDed,而不是比较,使用了错误的词;)
这不是比较0xc0
,这是一个逻辑与运算0xc0
.
位掩码0xc0
is 11 00 00 00
所以 AND 所做的只是提取前两位:
ab cd ef gh
AND 11 00 00 00
-- -- -- --
= ab 00 00 00
然后将其与0x80
(二进制10 00 00 00
)。换句话说,if
语句正在检查值的前两位是否不等于10
.
“为什么?”,我听到你问。嗯,这是个好问题。答案是,在 UTF-8 中,所有以位模式开头的字节10
是多字节序列的后续字节:
UTF-8
Range Encoding Binary value
----------------- -------- --------------------------
U+000000-U+00007f 0xxxxxxx 0xxxxxxx
U+000080-U+0007ff 110yyyxx 00000yyy xxxxxxxx
10xxxxxx
U+000800-U+00ffff 1110yyyy yyyyyyyy xxxxxxxx
10yyyyxx
10xxxxxx
U+010000-U+10ffff 11110zzz 000zzzzz yyyyyyyy xxxxxxxx
10zzyyyy
10yyyyxx
10xxxxxx
所以,这个小片段所做的就是遍历 UTF-8 字符串的每个字节,并计算所有不是连续字节的字节(即,它获取字符串的长度,如广告所示)。看这个维基百科链接 http://en.wikipedia.org/wiki/UTF-8欲了解更多详细信息和Joel Spolsky 的优秀文章 http://www.joelonsoftware.com/articles/Unicode.html作为底漆。
顺便说一句有趣的。您可以按如下方式对 UTF-8 流中的字节进行分类:
- 将高位设置为
0
,它是一个单字节值。
- 将两个高位设置为
10
,它是一个连续字节。
- 否则,它是多字节序列的第一个字节和前导的数量
1
位表示该序列总共有多少字节(110...
表示两个字节,1110...
表示三个字节等)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)