UTF-8和Unicode,0xC0和0x80是什么?

vds*_*dsf 49 unicode utf-8

我在过去几天一直在阅读有关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;
}
Run Code Online (Sandbox Code Playgroud)

有人可以澄清与0xc0的比较并检查它是否是最重要的位?

谢谢!

编辑:ANDED,而不是比较,使用了错误的单词;)

pax*_*blo 86

这不是一个比较0xc0,它是一个逻辑AND操作0xc0.

位掩码0xc011 00 00 00AND正在做的只是提取前两位:

    ab cd ef gh
AND 11 00 00 00
    -- -- -- --
  = ab 00 00 00
Run Code Online (Sandbox Code Playgroud)

然后将其与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
Run Code Online (Sandbox Code Playgroud)

所以,这个小片段正在做的是遍历你的UTF-8字符串的每个字节,并计算所有不是连续字节的字节(即,它正在获得字符串的长度,如所宣传的那样).请参阅此维基百科链接以获取更多详细信息,以及Joel Spolsky的优秀文章.


旁边一个有趣的方式.您可以按如下方式对UTF-8流中的字节进行分类:

  • 将高位设置为0,它是单字节值.
  • 将两个高位设置为10,它是一个连续字节.
  • 否则,它是多字节序列的第一个字节,前导1位数表示该序列总共有多少字节(110...表示两个字节,1110...表示三个字节等).