1.4 C语言的“字母”和“单词”

1.4.1 C语言的“字母”

作为一种语言,必须要有自己“字母表”(或者说是类似于汉字的基本笔画一类的东西)、“单词”(或“汉字”)及“标点符号”。抽象地看,C语言源程序无非就是一系列字符。最基本的、构成C语言源程序的最基本的“字母”表(Basic Source Character Set)如下。

1.拉丁字母表中的26个大写字母(Uppercase Letters):

1.4 C语言的“字母”和“单词” - 图1

2.拉丁字母表中的26个小写字母(Lowercase Letters):

1.4 C语言的“字母”和“单词” - 图2

3.10个十进制数字(Digits):

1.4 C语言的“字母”和“单词” - 图3

4.29图形字符(Graphic Characters):

1.4 C语言的“字母”和“单词” - 图4

5.空白字符:

空格(Space Character)及三个分别表示水平制表(Horizontal Tab)、垂直制表(Vertical Tab)及换页(Form Feed)的控制字符。

这85个字符是构成C语言源程序的最基本元素,是必须的也是充分的。然而需要指出的是,C99并不排斥这个字符集以外的字符。理论上来说,源程序中也可以使用汉字这样的字符。但是C99标准对此只给出了一个宽松的政策,具体的实现还须仰仗未来编译器作者的努力(10)

此外要明确的是编写程序用的字符与程序所处理(输入、输出或其他)的字符是两个概念。也就是说,即使源程序使用的是前面所说的85个字符,但在程序所处理的文字(Execution character)中,比如字符串中,还是可以使用汉字等其他字符的。如前面的“printf("你好,C!\n");”中就出现了汉字,当然这同时还需要操作系统的支持。

在基本的85个字符中,有些明显是臃余的。所有的空白字符,加上作为一行的结束标志的字符(通常就是回车换行),对于编译器来说,作用只可能有一个——作为各个单词之间必要的间隔,甚至没有作用。但是从另一个角度来讲却又是必要的,因为源程序除了编译器以外还有另一个读者——那就是人。应该善于利用这些空白字符把源代码写得更美观、更具有可读性,使人读起来更加赏心悦目。

在有的语言中,大小写字母被认为是相同的字母,但在C语言中大小写字母是完全不同的字母,而且习惯上,C语言以小写字母为主——多数情况下用小写字母,大写字母通常用在较为特殊的场合。

1.4.2 C语言的“词”

所谓c语言的“词”是指源程序中若干连续的或成对的、具有独立语意的字符的组合。“词”是语意的基本单位,在语意这个意义上是不容割裂的“原子”。专业人士把这种东西统一称之为“记号”(Token: an individual instance of a type of symbol)。

在GB/T 15272-94中,“Token”被译成了“单词”,这是一个很漂亮的翻译。本书正式釆用这个术语。

在C语言中,有5种单词。它们正式的分类名称分别如下。

■ 关键字(Keyword)

■ 标识符(Identifier)

■ 常量(Constant)

■ 字符串文字量(String-Literal)

■ 标点符号(Punctuator)

下面简单地介绍一下各种单词大概的含义。

1.常量

在计算圆周长的数学公式C=2πr中,2和π都是所谓的常量。在程序计算中也有类似的情况,这时就需要在源程序中写出这些常量(Constant)。

在源程序中写常量时,需要按照C语言规定方式书写,特别需要注意的是不可以把日常的或其他学科的习惯带到源代码中,如把1234写成1,234,或用空格把数字分组,或者随意在数字前加0等。前两者违背了单词不可分割的原则,而后者的写法在源程序中有特定的含义:1234与01234在源程序中的含义是全然不同的。

常量不仅有数值常数,还有其他种类。常量的准确定义及各种具体写法将在稍后详细介绍。

2.字符串文字量

在书面自然语言中,实实在在原封不动地引用一段语言或文字时通常用双引号括起来。在C语言源程序中也是如此,甚至形式上也完全相同。它就是一段实实在在的字符序列,可以被源程序处理,但本身并不是用来描述程序执行步骤而是程序执行处理的一个对象,这和常量在程序中的作用基本一样(11)。为了有别于程序中描述程序思想的那些文字,字符串文字量必须在形式上与它们有所区别,这就是字符串文字量一定要披着双引号这种马甲的原因。

3.标识符

大体上,标识符(Identifier)相当于自然语言中的名词,或者数学公式中变量的表示符号,是编程者为程序中用到的各种对象——有时是实的,比如一块内存,有时是虚的,比如一种数据类型等所取的名字。

C99之前,为程序中的对象取名只可以使用大小写英文字母、下划线和数字字符(12),而且开头不可以是数字。

此外要注意的是同一英文字母的大小写在C语言中是不同的两个字符,换句话说C语言区分大小写,在源程序中abc和Abc是两个不同的标识符。

4.关键字

关键字(Keyword)是C语言所保留的、具有特定含义的一些标识符,不可以作为普通的标识符来为其他对象取名。

关键字有些类似自然语言中的“成语”,其含义不是一两句话能说清楚的。精确全面地理解关键字的含义并能够恰到好处地应用它们,至少占C语言学习内容的一半以上。

从使用方式的角度看,大体有两类关键字,一类是以固定格式构成某种“句型”的,这种句型一般是一套复杂计算动作的组合;另一类简单地相当于自然语言中的“副词”或“形容词”。

与其他语言相比,C语言的关键字很少,这从一个方面显示了C语言简洁的特点。并且,不同的编译器下的不同的C语言方言或不同的标准下的C语言关键字也不同。如表1-1所示,是C99新增的关键字。

表1-1 C语言的关键字

1.4 C语言的“字母”和“单词” - 图5

(2) C99新增加的关键字

5.标点

C语言中可以归类为标点(Punctuator)的单词有下面48(13)个:

1.4 C语言的“字母”和“单词” - 图6

1.4 C语言的“字母”和“单词” - 图7

这些标点有些类似于自然语言中的标点符号(如{}),有些相当于数学运算式中的运算符号(如+),被称为“运算符”(Operator)。特别需要注意的是有些标点在不同的场合下含义是不同的。C语言的词汇有一词多意的特点。一个C语言单词的语意经常需要根据单词所在的上下文才能确定,这是一个C语言的一个特点,也是一个难点。

作为一个整体,标点是不容分割的(所有单词都这样),如“<<”不可以写做“< <”,两个“<”之间不可以加入任何字符(包括空格)。此外“[”、“]”、“(”、“)”、“{”、“}”、““”、“‘”也一定是成对使用的,且大部分情况下其中间部分不能是空的。

6.空白

在英语中,单词与单词之间是用空格或标点符号分隔开的;在源程序中也是如此。在单词之间可以自由地添加任意个空白字符(White-space Character):空格(Space)、换行(New-line)、水平制表(Horizontal Tab)、垂直制表(Vertical Tab)和换页(Form-feed)。对于编译器来说,这种空白有时是必要的,有时是可有可无的。但从代码的可读性以及可欣赏性来考虑,单词之间的空白是完全必要的。那些C语言大师们无一例外地都是“留白”的高手。

所以,编写代码的总的原则是:单词原则上应该是一个整体,不容许割裂;常量、标识符、关键字这样的单词之间必须有空白符或符合语法要求的标点符号。在写代码时,应该在遵循这个原则的条件下把代码写的清晰、自然、易读。

7.例外

有一些情况,在前面的讨论中没有涉及,比如程序代码1-2中的:

1.4 C语言的“字母”和“单词” - 图8

由于<stdio.h>中的“<”、“>”和“.”作为独立的个体并不具C语言的语法意义,因此“<stdio.h>”也是不可分割的独立单词,这是不同于前面所提到的单词的另一类单词,叫做“预处理命令记号”(Preprocessing-token)。这些内容将在介绍相应的预处理命令时一并介绍。

练习

识别并找出下面代码中的单词:

程序代码1-5

1.4 C语言的“字母”和“单词” - 图9

1.4 C语言的“字母”和“单词” - 图10