C Library User 手册(3)

240 篇文章 11 订阅

3.2 Escape sequences

在字符常数和字符串字面中,你可以写出各种转义序列。每个转义序列决定了单个字符的代码值。你使用转义序列来表示字符代码。
■你无法以其他方式书写的字符(如:n):
■难以正确阅读的字符(如\t)。
■在不同的目标字符集中可能会改变数值(如:\a)。
■在不同的目标环境中不能改变值(如0)。
一个转义序列的形式如图所示。
在这里插入图片描述

3.2.1 Numeric escape sequences

你也可以用八进制或十六进制的数字编写数字转义序列。八进制转义序列有以下几种形式:

\d or \dd or \ddd

转义序列产生的代码值是反斜杠后面的1位、2位或3位八进制数字的数字值。
反斜杠()后面的八位数的数值。每个d可以是0-7范围内的任何数字。十六进制的转义序列有以下几种形式:

\xh or \xhh or ...

转义序列产生的代码值是反斜杠(\)后面任意长度的十六进制数字的数值。每个h可以是任何十进制数字0-9,或任何字母a-f或A-F。这些字母代表数字值10-15,其中a或A的值为10。
一个数字转义序列以不符合数字模式的第一个字符为终点。下面是一些例子:
■你可以把空字符写成’\0’。
■你可以在一个字符串字面中写一个换行符(NL),方法是写。
“hi/n “会变成数组{‘h’, ‘i’, ‘\n’, 0}。
■你可以写一个以特定数值开始的字符串字面。”\3abc “会变成数组
{3, ‘a’, ‘b’, ‘c’, 0}。
■你可以写一个包含十六进制转义序列\xF的字符串字面。
后面是数字3,写两个字符串字面。”\xF”“3”,成为数组
{0xF, ‘3’, 0}

3.3 Trigraphs

三段式是一个由三个字符组成的序列,以两个问号(??)开始。你使用三段式来编写C语言源文件,其字符集不包含某些标点符号的方便图形表示。(由此产生的C源文件不一定更可读,但它是不含糊的)。
所有定义的三段式的列表是:
在这里插入图片描述
这些是唯一的三叉戟。译者不会改变任何其他以两个问号开头的序列。
例如,表达式的语句:
printf(“Case ?=3 is done??/n”)。
printf(“你说什么???/n”)。
相当于:
printf(“Case #3 is done\n”)。
printf(“You said what??\n”)。
在翻译的早期阶段,翻译器将每个三段式替换为其对应的单字符表示。你总是可以把三段式当作一个单一的源字符。

3.4 Multibyte characters

源字符集或目标字符集也可以包含多字节字符(一个或多个字节的序列)。每个序列代表扩展字符集中的一个字符。你用多字节字符来表示大的字符集,如汉字。一个多字节字符可以是一个单字节序列,它是基本C语言字符集中的一个字符,一个额外的单字节序列,它是由实现定义的,或者是由两个或多个字节组成的额外序列。
任何包含两个或更多字节的序列的多字节编码,在字节之间的解释取决于由字符序列中较早的字节决定的转换状态。在初始转换状态下,如果紧随其后的字节与基本C语言字符集中的一个字符相匹配,则该字节必须代表该字符。
例如,EUC编码是ASCII的一个超集。区间[0xA1, 0xFE]中的一个字节值是一个两字节序列(其第二个字节值在区间[0x80, 0xFF]中)的第一个。所有其他的字节值都是一个字节的序列。由于基本C语言字符集的所有成员在ASCII中的字节值都在[0x00, 0x7F]范围内,所以EUC符合标准C语言中多字节编码的要求。这样的序列在[0xA1, 0xFe]区间的字节值之后,并不处于初始转换状态。如果第二个字节值不在[0x80, 0xFF]的区间内,那么它就不成立。
多字节字符也可以有一个依赖于状态的编码。在这样的编码中,你如何解释一个字节取决于转换状态,其中包括解析状态(如前所述)和移位状态(由字符序列中的早期字节决定)。在一个新的多字节字符的开始,初始移位状态也是初始转换状态。随后的移位序列可以确定一个备用的移位状态,之后所有的字节序列(包括一个字节的序列)可以有不同的解释。然而,一个含有零值的字节,总是代表空字符。它不能作为另一个多字节字符的任何一个字节出现。
例如,JIS编码是ASCII的另一个超集。在初始移位状态下,每个字节代表一个字符,除了两个三字节的移位序列:
■三字节序列"\x1B$B “转变为两字节模式。随后,两个连续的字节(数值都在[0x21, 0x7E]范围内)构成一个多字节的字符。
■三字节序列”\x1B(B) "转移回初始转移状态。
JIS也符合标准C中对多字节编码的要求,这样的序列在三字节移位序列的中途或在两字节模式下,不处于初始转换状态。
(修正案1增加了mbstate_t类型,它描述了一个可以存储转换状态的对象。它还放宽了上述通用多字节字符的规则,描述了广泛的宽流的编码规则)。
你可以在C源文本中写入多字节字符,作为注释、字符常量、字符串字面或包含指令中的文件名的一部分。这类字符如何打印是由实现定义的。你写的每个多字节字符序列必须以初始移位状态开始和结束。程序也可以在几个库函数使用的空尾C字符串中包含多字节字符,包括printf和scanf的格式字符串。每个这样的字符串都必须在初始移位状态下开始和结束。

3.4.1 Wide-character encoding

扩展字符集中的每个字符也有一个整数表示,称为宽字符编码。每个扩展字符都有一个唯一的宽字符值。零值总是对应于空的宽字符。类型定义wchar_t指定了代表宽字符的整数类型。
你把一个宽字符常数写成L’mbc’,其中mbc代表一个单一的多字节字符。你把一个宽字符字符串的字头写成L “mbs”,其中mbs代表一个零或多个多字节字符的序列。宽字符字符串字头L "xyz "成为一串存储在连续的字节内存中的宽字符常数,后面是一个空的宽字符:

 {L'x', L'y', L'z', L'\0'}

以下库函数可以帮助你在扩展字符的多字节和宽字符表示法之间进行转换:btowc, mblen, mbrlen, mbrtowc, mbsrtowcs, mbstowcs, mbtowc, wcrtomb, wcsrtombs, wcstombs, wctob, 和 wctomb。
宏MB_LEN_MAX指定了在所支持的地区中,实现所定义的单个字符所需的最长的多字节序列的长度。宏MB_CUR_MAX指定了代表当前语言定义的单个字符所需的最长的多字节序列的长度。
例如,字符串字面意义 "hello "成为一个6个字符的数组:

{'h', 'e', 'l', 'l', 'o', 0}

而宽字符字符串字头L "hello "变成了一个由6个wchar_t类型的整数组成的数组:

{L'h', L'e', L'l', L'l', L'o', 0}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值