首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

编写C++语句要使用基本源字符集,这些是在C++源文件中可以显式使用的字符集。显然,用于定义名称的字符集是上述字符集合的一个子集。当然,基本源字符集并没有限制代码中使用的字符数据。程序可以用各种方式创建没有包含在该字符集中的字符串,基本源字符集包括下述字符:

● 大小写字母A~Z和a~z

● 数字0~9

● 控制字符,如换行符、水平和垂直制表符、换页符

● 字符_{}[]#()<>%:;.?*+-/^&~!=,\" '

这很直观。我们一共可以使用96个字符,这些字符可以满足大多数要求。

在C++中使用的字符定义并没有说明字符的编码方式。编译器将决定用于编写C++源代码的字符在计算机上如何表示。在PC上,这些字符一般在机器上显示为ASCII码(例如ISO Latin-1),也可以使用其他的字符编码方式。

大多数情况下,基本源字符集足够用了,但偶尔需要使用不包含在基本集合中的字符。前面就提到,可以在名称中包含UCS字符。还可以在程序的其他部分包含UCS字符,例如指定字符数据。下一节将详细介绍UCS。

1.8.1 通用字符集

通用字符集 (Universal Character Set,UCS)由ISO/IEC 10646标准指定,定义了目前在所有语言中使用的字符编码和其他内容。ISO/IEC 10646标准定义了几种字符编码形式,最简单的形式是UCS-2,它把字符表示为16位码,所以可以包含65536个不同的字符编码,这些字符编码可以写为4个16进制数dddd。这种编码描述为基本多语言平台,因为它包含目前使用的所有语言的字符。UCS-4是ISO/IEC 10646标准中的另一个编码,它把字符表示为32位码,32位码可以写为8个16进制数dddddddd。UCS-4包含40多亿个不同的编码,能容纳所有需要的字符集。

但这并不是UCS的所有内容。例如,另一个16位编码叫做UTF-16(UTF,Unicode Transformation Format),它与UCS-2不同,可以包含的字符超过了65535个,通过所谓16位码值的代理对给65535个以后的字符编码。UCS还有其他字符编码。一般说来,给定的字符在任何UCS编码中的码值都相同,US_ASCII中的码值与UCS字符编码中的码值相同。

无论编译器是否支持扩展字符集来编写源语句,都可以在源代码中包含UCS中的字符,把它们指定为编码的16进制表示\udddd或\Udddddddd(其中d是一个16进制数)。注意第一种形式使用小写u,第二种形式使用大写U。但是,不能以这种方式指定基本源字符集中的字符。这是因为这些字符的编码由编译器决定,它们可能与UCS编码并不一致。

如果编译器支持扩展字符集和超出基本源字符集中的字符,就可以在源代码中使用这些字符,编译器在开始编译之前,会把它们转换为内部的表示方式。

注意:

由UCS标准定义的字符编码与Unicode定义的编码相同,所以Unicode实际上是UCS的另一个名称。如果读者希望了解UCS和Unicode详细信息,可以参考http://www.unicode.org。

1.8.2 三字符序列

三字符序列不太常见,但C++标准允许把某些字符指定为三字符序列。三字符序列就是用于表示另一个字符的三个字符序列。以前为了表示键盘上没有的字符,这是必不可少的一种方法。表1-1列出了以这种方式在C++中指定的字符。

表1-1 三字符序列的字符

字 符

三字符序列

#

??=

[

??(

]

??)

\

??/

{

??<

}

??>

^

??'

|

??!

??-

编译器会用对应的字符替代它们,再对源代码进行其他处理。

1.8.3 转义序列

在程序中使用字符常量时,某些字符是会出问题的。字符常量是程序以某种方式使用的数据项,它可以是一个字符,也可以是一个字符串,例如前面例子中使用的字符串。显然,不能直接把newline或tab这样的字符输入为字符常量,因为它们只完成自己该做的工作:在源代码文件中换行或进入下一个制表位置。字符常量中应包含该字符的相应编码。

通过转义序列可以把控制字符输入为字符常量。转义序列是指定字符的一种间接方式,通常以一个反斜杠\开头。表示控制字符的转义序列如表1-2所示。

表1-2 表示控制字符的转义序列

转 义 序 列

控 制 字 符

\n

换行符

\t

水平制表符

\v

垂直制表符

\b

退格字符

\r

回车字符

\f

换页字符

\a

警告字符

还有其他一些字符在直接表示时会出问题。显然,表示反斜杠字符本身是很困难的,因为它表示转义序列的开头。其他控制字符也有其特殊的含义。可以用转义序列指定的“问题”字符如表1-3所示。

表1-3 用转义序列指定的“问题”字符

转 义 序 列

字 符

\\

反斜杠

\'

单引号

\"

双引号

\?

问号

由于反斜杠表示转义序列的开始,因此把反斜杠字符输入为一个字符常量的惟一方式是使用两个连续的反斜杠。

转义序列还提供了用键盘不支持的语言来表示字符的一种通用方式,因为可以使用十六进制(基数是16)或八进制(基数是8)数字前置一个反斜杠来指定字符的编码。由于使用了数字编码,可以用这种方式指定任何字符。在C++中,十六进制数据以x或X开头,\x99A和\XE3都是以这种方式进行转义的序列。

还可以使用至多3个八进制数字前置一个反斜杠来表示字符,例如\165。没有x或X,就表示该编码应解释为一个八进制数字。

程序示例1.1—— 使用转义序列

下面创建一个程序示例,使用转义序列来指定要显示在屏幕上的消息。要查看该程序的结果,需要输入、编译、链接和执行下面的程序。

如前言所述,如何执行这些步骤取决于编译器,读者可以查看编译器的说明文档,以了解更多的信息。如果查找“编辑”、“编译”和“链接”(在一些编译器中是“建立”),就可以找到需要的信息。

//Program 1.2 Using escape sequences

#include <iostream>

using std::cout;

int main() {

cout<<"\n\"Least said\n\t\tsoonest mended.\"\n\a";

return 0;

}

在编译、链接和运行这个程序时,会显示如下结果:

"Least said

soonest mended."

还会听到一声鸣响或计算机配备的声音输出设备发出的声音。

例子的说明

所得的输出由语句中双引号之间的内容确定:

cout<<"\n\" Least said\n\t\tsoonest mended.\ "\n\a";

原则上,上述语句中外部双引号之间的所有内容都会发送给cout。双引号之间的字符串称为字符串字面量。双引号字符表示该字符串字面量的开始和结束;它们不是字符串的一部分。这里说“原则上”是因为字符串字面量中的转义序列会被编译器转换为它表示的字符,所以该字符会发送给cout,而不是发送转义序列。字符串字面量中的反斜杠总是表示转义序列的开始,所以发送给cout的第一个字符是\n,即换行符,它将屏幕光标定位到下一行的开头。

字符串中的下一个字符由另一个转义序列\"指定,所以给cout发送一个双引号,并显示在屏幕上,其后是字符串Least said。接着是另一个换行符\n,因此光标移动到下一行的开头。然后给cout发送两个制表符\t\t,让光标向右移动两个制表位置。之后显示字符串soonest mended,其后是转义序列\",即显示另一个双引号。最后是另一个换行符\n,它把光标移动到下一行的开头,其后的转义序列\a表示发出一声鸣响。

字符串内部的双引号不会解释为字符串字面量的结束,这是因为每个双引号的前面都有一个反斜杠,表示这是一个转义序列。如果没有转义序列\",就无法输出双引号,因为它会被解释为字符串的结尾。

名称endl在<iostream>头文件中定义,在输出语句中使用它会输出一个换行符,因此可以使用endl代替\n。但\n和endl不完全相同,因为使用endl会使输出缓存溢出,并把仍在内存中的字符全部写到输出设备上。而\n不是这样。显然,不能在字符串字面量中包含endl,因为它会解释为四个字母e、n、d和l。

注意:

endl的最后一个字符是字母l,而不是数字1。这有时很难区分。

使用endl,上述代码中输出字符串的语句就应改写为:

cout << endl

<< "\" Least said"

<< endl

<< "\t\tsoonest mended.\ "\a"

<< endl;

这条语句给cout按顺序发送了5个字符串字面量:end、"\" Least said"、endl、"\t\tsoonest mended.\ "\a"和endl。其结果与前面的语句相同。当然,为了使该语句可以编译,需要在程序的开头添加另一个using指令:

using std::endl;

不必为换行符选择是使用endl还是转义序列。它们不是互斥的,可以根据自己的情况混合使用。例如,用下面的语句也可以生成相同的结果:

cout << endl

<< "\" Least said"\n\t\tsoonest mended.\ "\a"

<< endl;

这里只对第一个和最后一个换行符使用了endl。中间的那个换行符仍使用转义序列来生成。当然,输出中endl的每个实例都会在流中写入一个换行符,再使输出缓存溢出。

1.8.4 语句中的空白

如前所述,空白是在C++中描述空格、水平和垂直制表符、换行符及换页符的术语。在许多情况下,空白把语句的一部分与另一部分分隔开,允许编译器标识语句中的一个元素在哪里结束,下一个元素从哪里开始。例如下面的代码行:

int fruit;

该语句涉及到int和fruit,int是一个类型名称,而fruit是一个变量名称。在int和fruit之间至少要有一个空白字符(通常是一个空格),这样编译器才能区分它们。这是因为intfruit是一个可接受的变量名称或其他成员的名称,如果中间没有空格,编译器就会把它解释为变量或其他成员的名称。

再看下面的语句:

fruit = apples + oranges;

在fruit和=之间以及=和apples之间不需要空白字符,但如果愿意,也可以加入空白。这是因为=不是字母也不是数字,所以编译器会把它跟其周围的字符区分开来。同样,+号的两边也不需要插入空白。实际上,可以插入任意多个空白,例如,把上面的语句改写为:

fruit

=

apples

+

oranges;

这并不是什么好的编程风格,但编译器不会在意。

除了在语句的元素之间或引号中的字符串内用作分隔符之外,编译器会忽略空白。因此可以在代码中包含任意多个空白,使程序的可读性更高。在一些编程语言中,语句的结尾是代码行的末尾,但在C++中,语句的结尾用分号来表示。因此,可以把一个语句分散放在好几行代码行上,例如一个语句可以编写为:

std::cout << std::endl <<"\" Least ::said"<<std::endl

<<"\t\tsoonest mended.\ "\a"<<std::endl;

也可以编写为:

std::cout << std::endl

<< "\" Least said"

<< endl

<< "\t\tsoonest mended.\ "\a"

<< std::endl;

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论