/*
* 转义字符
*/
在C语言中,一个字符除了可以用它的实体(也就是真正的字符)表示,还可以用编码值表示。
这种使用编码值来间接地表示字符的方式称为转义字符(Escape Character)。
(1)C语言中一般用 \ 字符表示转义,后边紧跟者的为要转义的字符。
(2)C语言中定义了一些字母前加 \ 来表示一些不能显示的ASCII字符,所有的ASCII码都可以用 \ 加数字来表示。
转义字符以\或者\x开头,以\开头表示后跟八进制形式的编码值,以\x开头表示后跟十六进制形式的编码值。
"对于转义字符来说,只能使用八进制或者十六进制。"
/*
* 转义字符及其含义
*/
转义字符 释义
\? 在书写连续多个问号时使用,防止他们被解析成三字母词
\’ 用于表示字符常量 ’
\" 用于表示一个字符串内部的双引号 "
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符
\a 警告字符,蜂鸣
\b 退格符
\f 进纸符
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制的数字。 如: \130(八进制)----->X(对应ASCII码字符)
\xdd dd表示2个十六进制数字。 如: \x30(十六进制)---->0(对应ASCII码字符)
\0 空字符(NUL)
注意:
a.区分斜杠:"/"与反斜杠"\",此处不可互换。
b.\xhh 十六进制转义不限制字符个数'\x0000000000000F' == '\xF'
char a = '\61'; //字符1
char b = '\141'; //字符a
char c = '\x31'; //字符1
char d = '\x61'; //字符a
char *str1 = "\x31\x32\x33\x61\x62\x63"; //字符串"123abc"
char *str2 = "\61\62\63\141\142\143"; //字符串"123abc"
char *str3 = "The string is: \61\62\63\x61\x62\x63" //混用八进制和十六进制形式
转义字符的初衷是用于 ASCII 编码,所以它的取值范围有限:
八进制形式的转义字符最多后跟三个数字,也即\ddd,最大取值是\177; (127)
十六进制形式的转义字符最多后跟两个数字,也即\xdd,最大取值是\x7f。 (127)
超出范围的转义字符的行为是未定义的,当看到有使用超出范围的转义字符时,需弄清楚字符集类型,再去查此字符集的定义。
/*
* 大于127的转义字符
*/
字符型变量占用一个字节,表示整数的范围是-128~127,用超过这个范围的数比如300赋值时,
计算机会在寄存器中取得300这个数0x12C,然后将低位字节2c赋值给字符型变量,高位被舍弃,就如同赋值:c1=44 的效果一样。
由于一般申请的字符变量是char是有符号的,如果申请 unsigned char 类型为0~255
300D = 1 0010 1100 B,分为两个字节存放,高位字节8位为 0000 0001 B 低位字节为 0010 1100 B,
如果给字符型变量赋值会取低位字节 00101100B (即0x2C)赋值而舍弃高位字节。
// 把300-256=44,那就是逗号,把400-256=144那就是问号
由于ASCII码小于等于127的是常用字符,而高于的是扩展字符,扩展字符被显示成了问号。
这种扩增字符一般用于汉字显示,一个汉字要两个大于127的字符来表示,只给一半则无法显示,只能用问号表示不全。
还需看字符集,如果是无符号字符是E,有符号有可能无法找到对应字符因此显示问号,可以肯定144没有对应到扩展ASCII字符集上。
\376 这是一个8进制数 相当于10进制的 254 , ASCII 标准码只用7位2进制位表示,即0-127,超出这个范围的是扩充的,
// 编码在127以上的都显示为"?"
编号在128~255的是扩展的编码,原本就不是作为显示用的,当然在不同的终端上显示就不一致,这完全取决于不同的显示终端的处理。在些ic厂商会重新做液晶显示的驱动,将大于127的ascii码做成想要的图标。比如一个充满电的电池图标,一个表示加锁的图标。
/*
* "\342\224\202" (U+2502, Vertical line drawing char)
*/
UTF-8 字符集。
Unicode (The Unicode Standard)译作万国码、统一字元码、统一字符编码,是信息技术领域的业界标准,其整理、编码了世界上大部分的文字系统,使得电脑能以统一字符集来处理和显示文字,不但减轻在不同编码系统间切换和转换的困扰,更提供了一种跨平台的乱码问题解决方案。
Unicode 编码是一个二进制字符集,其只规定了字符的二进制代码,却没有规定这些二进制代码应该如何存储。
UTF-8是UNICODE的一种变长度的编码表达方式《一般UNICODE为双字节(指UCS2)》,它由Ken Thompson于1992年创建,现在已经标准化为RFC 3629。UTF-8就是以8位为单元对UCS进行编码,而UTF-8不使用大尾序和小尾序的形式,每个使用UTF-8存储的字符,除了第一个字节外,其余字节的头两个位都是以"10"开始,使文字处理器能够较快地找出每个字符的开始位置。
但为了与以前的ASCII码兼容(ASCII为一个字节),因此UTF-8选择了使用可变长度字节来存储Unicode:
ISO8859-1:一个字节
GBK: 两个字节包含了英文字符和扩展的中文ISO8859-1+中文字符
UTF-8 万国码:1~3个字节不等长。英文存的是1个字节,中文存的是3个字节,是为了节省空间。
UTF-8的英文全称是(8-bit Unicode Transformation Format),其为 Unicode 的实现方式之一,也是目前互联网上使用最广的一种 Unicode 编码的实现方式。
UCS-4编码 UTF-8字节流
U+00000000 – U+0000007F 0xxxxxxx /* 0 ~ 127 */
U+00000080 – U+000007FF 110xxxxx 10xxxxxx /* 128 ~ 2047 */
U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx /* 2048 ~ 65535 */
U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx /* 65536 ~ 2097151 */
U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx /* 2097152 ~ 67108863 */
U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx /* 67108864 ~ 2147483647 */
在ASCII码的范围,用一个字节表示,超出ASCII码的范围就用字节表示,这就形成了我们上面看到的UTF-8的表示方法,这様的好处是当UNICODE文件中只有ASCII码时,存储的文件都为一个字节,所以就是普通的ASCII文件无异,读取的时候也是如此,所以能与以前的ASCII文件兼容。
大于ASCII码的,就会由上面的第一字节的前几位表示该unicode字符的长度,
比如110xxxxxx前三位的二进制表示告诉我们这是个2BYTE的UNICODE字符;1110xxxx是个三位的UNICODE字符,依此类推;
xxx的位置由字符编码数的二进制表示的位填入。越靠右的x具有越少的特殊意义。
只用最短的那个足够表达一个字符编码数的多字节串。注意在多字节串中,第一个字节的开头"1"的数目就是整个串中字节的数目。
ASCII字母继续使用1字节存储,重音文字、希腊字母或西里尔字母等使用2字节来存储,而常用的汉字就要使用3字节。辅助平面字符则使用4字节。
在UTF-8文件的开首,很多时都放置一个U+FEFF字符(UTF-8以EF,BB,BF代表),以显示这个文字文件是以UTF-8编码。