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操作。

位掩码0xc011 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...表示三个字节等)。