[转] UTF-8 字符数字统计的原理 0x80和0xC0

from: http://blog.sina.com.cn/s/blog_7c4f3b160101dv4p.html

最近在公司看代码,看到一个字符串长度统计的代码,如下

 
int calcLen(const char* _str)
{
int n = 0;

        char ch = 0;

        while ((ch = *_str))

        {

            CC_BREAK_IF(! ch);

            

            if (0x80 != (0xC0 & ch))

            {

                ++n;

            }

            ++_str;

        }

        return n;   

}
 
其中关于0x80 != (0xC0 & ch)的判断,百思不得其解,按照ansi表的标准解释来看,0~127位足以表达对字符数目的统计,也就是说用如下代码
(0x80 & ch) == 0 
足以判断这个ch是不是一个字符,因此那种复杂的写法理论上不只是做ansi字符的判断,最后四处爬资料,最后得到如下信息,在这里写下来以供自己备忘
 
其中关于位运算的知识,各位请自行脑补,度娘,谷哥,我这里只想说那个运算的目的
 
0xC0也就是1100, 这个&运算判断的是下一个ch的头两位是什么字符, 因为11能完全反映出本来的数字
对于普通的ansi字符(非扩展集)而言,他的头一位一定是0(0000 0000 ~ 0111 1111)
对于UTF-8字符而言,因为UTF-8编码是一种多字节序的形式,他采用如下的数字序规律
 
所有10打头的在UTF-8里面,表示都是一个多字节序的子序
 
两个UTF-8字符,打头则是以110开始, 后面跟10XXXXXX, 10YYYYYY表示接下来的字符
三个则是1110开始,后面跟三个10XXXXXX来表示字符
 
所以在计算字符串个数的时候,只需要判断当前字符是不是等于10开头,不等于10开头就一定是一个单字符或者一个多字符,然后计数器+1即可
 
具体有兴趣的童鞋可参阅http://stackoverflow.com/questions/3911536/utf-8-unicode-whats-with-0xc0-and-0x80
原文地址:https://www.cnblogs.com/Arborday/p/11205069.html