C语言标准详解:从词法到类型转换
立即解锁
发布时间: 2025-08-22 00:24:53 阅读量: 11 订阅数: 16 


C语言编程基础与实践
# C语言标准详解:从词法到类型转换
## 1. 引言
本手册解读的是 1988 年 10 月 31 日提交给美国国家标准学会(ANSI)的草案所规定的 C 语言,该草案旨在批准成为 “信息系统 - 编程语言 C 的美国标准,X3.159 - 1989”。此手册是对拟议标准的阐释,虽尽力成为可靠的语言指南,但并非标准本身。
## 2. 词法约定
### 2.1 程序翻译阶段
程序由存储在文件中的一个或多个翻译单元组成,其翻译过程分为多个阶段。初始阶段进行低级词法转换,执行以 `#` 字符开头的行引入的指令,并进行宏定义和展开。预处理完成后,程序被简化为一系列标记。
### 2.2 标记
标记分为六类:标识符、关键字、常量、字符串字面量、运算符和其他分隔符。空白、水平和垂直制表符、换行符、换页符和注释(统称 “空白字符”)除用于分隔标记外,会被忽略。部分情况下,需要空白字符来分隔相邻的标识符、关键字和常量。若输入流已分隔到某个字符,下一个标记是能构成标记的最长字符串。
### 2.3 注释
注释以 `/*` 开头,以 `*/` 结尾,不允许嵌套,且不会出现在字符串或字符字面量中。
### 2.4 标识符
标识符是字母和数字的序列,首字符必须是字母,下划线 `_` 视为字母,大小写字母不同。标识符长度不限,对于内部标识符,至少前 31 个字符有意义,某些实现可能会考虑更多字符。具有外部链接的标识符限制更多,实现可能仅使前六个字符有意义,且可能忽略大小写区别。
### 2.5 关键字
以下标识符被保留用作关键字,不能另作他用:
```plaintext
auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while
```
部分实现还会保留 `fortran` 和 `asm` 这两个词。`const`、`signed` 和 `volatile` 是 ANSI 标准新增的关键字;`enum` 和 `void` 自第一版起新增,但已广泛使用;`entry` 以前被保留但从未使用,现在不再保留。
### 2.6 常量
常量有多种类型,每种都有数据类型,主要包括:
- 整数常量
- 字符常量
- 浮点常量
- 枚举常量
#### 2.6.1 整数常量
由数字序列组成的整数常量,若以 `0` 开头则为八进制,否则为十进制。八进制常量不包含数字 `8` 或 `9`。以 `0x` 或 `0X` 开头的数字序列为十六进制整数。整数常量可后缀 `u` 或 `U` 表示无符号,后缀 `l` 或 `L` 表示长整型。其类型取决于形式、值和后缀,具体规则如下表所示:
| 后缀情况 | 类型 |
| ---- | ---- |
| 无后缀且为十进制 | int, long int, unsigned long int(按顺序能表示其值的第一个类型) |
| 无后缀,八进制或十六进制 | int, unsigned int, long int, unsigned long int(按顺序能表示其值的第一个类型) |
| 后缀为 u 或 U | unsigned int, unsigned long int |
| 后缀为 l 或 L | long int, unsigned long int |
| 后缀为 UL | unsigned long |
#### 2.6.2 字符常量
字符常量是用单引号括起来的一个或多个字符序列,如 `'x'`。单字符常量的值是该字符在机器字符集中执行时的数值。多字符常量的值由实现定义。字符常量不包含 `'` 字符或换行符,可使用以下转义序列来表示它们及其他特定字符:
| 含义 | 转义序列 |
| ---- | ---- |
| 换行符 | `\n` |
| 反斜杠 | `\\` |
| 水平制表符 | `\t` |
| 问号 | `\?` |
| 垂直制表符 | `\v` |
| 单引号 | `\'` |
| 退格符 | `\b` |
| 双引号 | `\"` |
| 回车符 | `\r` |
| 八进制数 | `\ooo` |
| 换页符 | `\f` |
| 十六进制数 | `\xhh` |
| 响铃符 | `\a` |
部分实现中,存在无法用 `char` 类型表示的扩展字符集,此类常量以 `L` 开头,如 `L'x'`,称为宽字符常量,类型为 `wchar_t`。
#### 2.6.3 浮点常量
浮点常量由整数部分、小数部分、分数部分、`e` 或 `E`、可选带符号的整数指数和可选类型后缀(`f`、`F`、`l` 或 `L`)组成。整数和分数部分均为数字序列,整数部分或分数部分(不能两者都)可缺失,小数点或 `e` 及指数(不能两者都)可缺失。类型由后缀决定,`F` 或 `f` 表示 `float`,`L` 或 `l` 表示 `long double`,否则为 `double`。
#### 2.6.4 枚举常量
声明为枚举器的标识符是 `int` 类型的常量。
### 2.7 字符串字面量
字符串字面量,也称为字符串常量,是用双引号括起来的字符序列,如 ` "..."`。字符串类型为 “字符数组”,存储类为静态,用给定字符初始化。相同字符串字面量是否不同由实现定义,尝试修改字符串字面量的程序行为未定义。相邻字符串字面量会连接成一个字符串,连接后会在字符串末尾追加空字节 `\0`。字符串字面量不包含换行符或双引号字符,可使用与字符常量相同的转义序列来表示它们。扩展字符集中的字符串字面量以 `L` 开头,如 `L "..."`,宽字符字符串字面量类型为 “`wchar_t` 数组”,普通和宽字符字符串字面量的连接未定义。
## 3. 语法表示法
本手册使用的语法表示法中,语法类别用斜体表示,字面单词和字符用打字机字体表示。替代类别通常分行列出,少数情况下,一组较窄的替代项会在一行列出,用 “one of” 标记。可选的终结符或非终结符符号带有下标 “opt”,例如 `{ expressionopt }` 表示一个用花括号括起来的可选表达式。
## 4. 标识符的含义
标识符或名称可指代多种事物,如函数、结构体、联合体和枚举的标签、结构体或联合体的成员、枚举常量、`typedef` 名称和对象。对象(有时称为变量)是存储位置,其解释取决于两个主要属性:存储类和类型。存储类决定与该对象关联的存储的生命周期,类型决定该对象中值的含义。名称还有作用域和链接性,作用域是程序中该名称已知的区域,链接性决定不同作用域中相同名称是否指代同一对象或函数。
### 4.1 存储类
存储类分为两种:自动和静态。多个关键字结合对象声明的上下文来指定其存储类。
- **自动对象**:局部于一个块,块退出时会被丢弃。块内声明的对象,若未指定存储类或使用 `auto` 说明符,则为自动对象。声明为 `register` 的对象也是自动对象,若可能,会存储在机器的快速寄存器中。
- **静态对象**:可以局部于一个块或在所有块外部,但无论哪种情况,在函数和块退出和重新进入时都会保留其值。在块内(包括提供函数代码的块),使用 `static` 关键字声明静态对象。在所有块外部、与函数定义处于同一级别的对象始终是静态的。使用 `static` 关键字可使其局部于特定翻译单元,具有内部链接;省略显式存储类或使用 `extern` 关键字可使其在整个程序中全局可用,具有外部链接。
### 4.2 基本类型
存在几种基本类型,标准头文件 `<limits.h>` 定义了每种类型在本地实现中的最大和最小值。
- **字符类型**:声明为字符(`char`)的对象足以存储执行字符集中的任何成员。若将该集中的真实字符存储在 `char` 对象中,其值等同于该字符的整数代码,且为非负。其他量也可存储在 `char` 变量中,但可用的值范围,尤其是值是否有符号,由实现决定。无符号字符(`unsigned char`)占用与普通字符相同的空间,但始终为非负;显式有符号字符(`signed char`)同样占用与普通字符相同的空间。
- **整数类型**:除字符类型外,还有短整型(`short int`)、整型(`int`)和长整型(`long int`)三种整数大小可选。普通 `int` 对象具有主机机器架构建议的自然大小,其他大小用于满足特殊需求。较长的整数至少提供与较短整数相同的存储空间,但实现可能使普通整数等同于短整数或长整数。除非另有指定,`int` 类型表示有符号值。使用 `unsigned
0
0
复制全文
相关推荐










