5 语法词汇
为了开始全面描述C语言,我们解释了C代码的语法词汇和词汇单元。编程语言的词汇单元称为标记。本章涵盖了C的所有标记,但常量除外,这将在后面的章节中介绍。一种重要的标记是标识符,它用于任何类型的名称。
5.1 用英语编写程序!
原则上,您可以用任何人类语言编写程序中的函数名和变量名,以及注释。C允许在注释中使用任何类型的字符,您可以将非ASCII字符放入带有特殊前缀的标识符中。然而,为了使所有国家的程序员都能理解和开发该程序,在当今的情况下,最好用英语编写标识符和注释。
英语是所有国家的程序员普遍学习的语言。如果一个程序的名称是英文的,孟加拉国、比利时、玻利维亚、巴西和保加利亚的大多数程序员都能理解。这些国家的大多数程序员都会说英语,或者至少能阅读,但他们根本不会对方的语言。在印度,语言如此之多,两个程序员可能除了英语之外没有共同语言。
如果你对用英语写作没有信心,那么尽力吧。
5.2 字符
GNU C源文件通常以ASCII字符集编写,该字符集在20世纪60年代为英语定义。但是,它们也可以包括以UTF-8多字节编码表示的Unicode字符。
在C源代码中,非ASCII字符在注释、宽字符常量和字符串常量中都是有效的。
在常量(字符或字符串)和标识符中指定非ASCII字符的另一种方法是使用以反斜杠开始的转义序列指定期望的Unicode字符。
对于某些字符,C接受称为二合字母的双字符别名。
5.3 空白
空白是指存在于文件中但在文件的打印列表中显示为空白的字符(或久远年代前,传统上显示为空白的字符)。C语言需要空白来分隔两个连续的标识符,或者将标识符与数值常量分隔开。除此之外,在后面描述的一些特殊情况下,空格是可选的;您可以在需要时将其放入,以使代码更易于阅读。
C代码中的空格和制表符被视为空白字符。换行也是如此。您可以使用newline(也称为linefeed 或 LF)、CR(回车符)或CRLF序列(两个字符:回车符后跟换行符)表示换行。
formfeed字符,即Control-L,传统上用于将文件分页。在源代码中它仍然以这种方式使用,并且用于生成源代码的漂亮打印件的工具仍然在每个“formfeed”字符之后开始一个新页。将代码分成由formfeed字符分隔的代码页是一种很好的方法,可以将代码分解为可理解的片段,并向其他程序员表明它们的起点和终点。
传统上,垂直制表符Control-K用于使打印前进到页面的下一部分。我们不知道在源代码中使用它的具体原因,但它在C中仍然被接受为空白。
注释在语法上也等同于空白。
5.4 注释
注释是存在于源代码中对代码的逻辑没有影响的文本。
注释的目的是向阅读代码的人解释代码。为您的代码编写好的注释非常重要。它们应该提供背景信息,帮助程序员理解代码以这种方式编写的原因。六个月后返回代码时,您将需要这些注释的帮助,以记住您为什么以这种方式写代码。
过时的注释变得不正确会适得其反,因此软件开发人员的部分责任是根据需要更新注释,以适应程序代码的更改。
C允许两种注释语法,传统样式和C++样式。传统的C注释以“/”开头,以“/”结尾。例如,
/* This is a comment in traditional C syntax. */
传统注释可以包含“/”,但这些定界符不成对嵌套。第一个出现的“/”结束注释,不管它是否包含“/*”序列。
/* This /* is a comment */ But this is not! */
行注释以“//”开头,以行结尾。例如,
// This is a comment in C++ style.
行注释确实存在嵌套,只不过,行注释内的“//”实际上是它的一部分,如下,
// this whole line is // one comment This is code, not comment.
将行注释放在块注释中是安全的,反之亦然。
/* traditional comment // contains line comment more traditional comment */ text here is not a comment// line comment /* contains traditional comment */
但是要小心用行注释注释掉传统注释的一端。如果定界符“/*”出现在另一个注释的内部,它不会启动新的注释。
// line comment /* That would ordinarily begin a block comment. Oops! The line comment has ended; this isn't a comment any more. */
字符串常量中无法识别注释。 “/blah/”是字符串常量,不是空字符串。
在本手册中,为了可读性,我们以可变宽度字体显示注释中的文本,但源文件中不存在这种字体区别。
注释在语法上等同于空白,因此它总是分隔标记。因此
int/* comment */foo;is equivalent to int foo;
但是干净的代码总是使用真正的空白来将注释与周围的代码在视觉上分隔开。
5.5 标识符
C中的标识符(名称)是字母和数字,以及“_”的序列,但不能以数字开头。大多数编译器也允许“$” 。标识符可以是任意长度;例如
int anti_dis_establishment_arian_ism;
标识符中的字母区分大小写;因此,a和a是两个不同的标识符。
C中的标识符用作变量名、函数名、类型定义名、枚举常量、类型标记、字段名和标签。C中的某些标识符是关键字,这意味着它们具有特定的语法含义。C中的关键字是保留词,这意味着不能以任何其他方式使用它们。例如,不能定义名为return或if的变量或函数。
您还可以在标识符中包含其他字符,甚至非ASCII字符,方法是在标识符名称中写入以“\u”或“\u”开头的Unicode字符名。然而,在标识符中使用非ASCII字符通常是一个坏主意,当它们用英语书写时,它们永远不需要非ASCII字符。
空白用来分隔两个连续标识符,或将标识符与前一个或后一个数字常量分隔。
5.6 运算符和标点符号
在这里,我们描述了C语言中运算符和标点符号的词汇语法。具体的运算符及其含义将在后续章节中介绍。
C中的大多数运算符由一个或两个字符组成,这些字符不能用于标识符。C中用于运算符的字符是“!~ ^&|*/%+-=<>,.?:” 。
有些运算符是两个字符。例如, “++”是增量运算符。多字符运算符的识别是通过将尽可能多的连续字符组合在一起构成一个运算符来实现的。
例如,字符序列“++”总是被解释为增量运算符;因此,如果我们想写入运算符“+”的两个连续实例,我们必须用空格分隔它们,以便它们不会合并为一个标记。应用相同的规则,a+++++b总是标记为a++ ++ +b,而不是a++ + ++b,即使后者可以是有效C程序的一部分,而前者不能(因为a++不是左值,因此不能是++的操作数)。
一些C运算符是关键字而不是特殊字符。它们包括sizeof和_Alignof 。
字符“;{}[]()”用于标点和分组。分号( “ ;” )结束一条语句。大括号(“{”和“}”)在语句级开始和结束一个块,或者用于包围一个变量(如数组或结构)的初始值列表。
方括号(“[”和“])用于数组索引,如数组[5]。
括号用于表达式中表达式的显式嵌套、围绕函数声明或定义中的参数声明以及函数调用中的参数列表,如printf(“Foo%d\n”,i)。有几种语句也使用括号作为其语法的一部分,例如if语句、for语句、while语句和switch语句。
括号还被用于围绕运算符关键字sizeof和_Alignof的操作数,当操作数是数据类型而不是值时。
5.7 续行
反斜杠和换行的序列在C程序中的任何位置都被完全忽略。这使得可以在源文件中将单个源行拆分为多行。GNUC容忍并忽略反斜杠和换行之间的其他空白。特别是,如果某些文本编辑器决定以CRLF序列结束行,它总是忽略其中的CR(回车)字符。
在C语言中,行连续的主要用途是用于一行过长的宏定义中。
可以使用反斜杠换行符在另一行上继续行注释。您可以将反斜杠换行放在标识符、甚至关键字或运算符的中间。您甚至可以使用反斜杠换行符将“/”、“/”和“//”拆分为多行。下面是一个丑怪的例子:
/\**/ fo\o +\= 1\0;
这相当于“/**/foo+=10;”。
在实际的程序中不要做这些事情,因为它们使代码难以阅读。
注意:因为要在源代码中使用某些工具的缘故,明智的做法是在每个源文件末尾使用一个前面没有反斜杠的换行符,这样它就真正结束了最后一行。
版权声明:内容来源于互联网和用户投稿 如有侵权请联系删除