UTF-8和Unicode,0xC0和0x80是什么?
在过去的几天里,我一直在阅读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
的逻辑AND操作。
位掩码0xc0
是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-8string的每个字节,并计算所有不是连续字节的字节(即获得广告string的长度)。 看到这个维基百科链接更多的细节和Joel Spolsky的优秀文章的底漆。
旁边有一个有趣的事情。 您可以按如下方式对UTF-8stream中的字节进行分类:
- 高位设置为
0
,它是单字节值。 - 将两个高位设置为
10
,这是一个连续字节。 - 否则,它是多字节序列的第一个字节,前导
1
位的数目表示这个序列总共有多less字节(110...
表示两个字节,1110...
表示三个字节等)。