c语言中的词法范围是什么?

问题描述

我正在阅读 K&R 的书,发现了一段我无法理解的段落。

有两种作用域需要考虑:第一,词法作用域 一个标识符,它是程序文本的区域,其中 标识符的特征被理解;其次,范围 与具有外部链接的对象和功能相关联, 确定单独编译的标识符之间的连接 翻译单元。

有人可以详细说明段落以及词法范围吗??

解决方法

严格来说,C 标准中没有“词法范围”这样的规范术语。

这本书的作者似乎指的是标识符的范围(词法范围)及其链接。

来自 C 标准(6.2.2 标识符的链接)

1 一个标识符声明在不同作用域或同一个作用域中 more 可以多次引用同一个对象或函数 过程称为联动。共有三种联动方式:外部、 内部,没有。

,

C 标准使用不同且更精确的语言。 Kernighan 和 Ritchen 所说的“词法范围”在 C 标准中简称为“范围”。 C 2018 在 6.2.1 条款中定义了范围,在 6.2.2 中定义了链接。简而言之,范围是在源代码中标识符在一个源文件编译期间“可见”的位置,而链接是一种在不同编译之间连接相同标识符的方法。更详细,但仍然总结:

  • 标识符(源代码中的名称,如 x3 中的 int x3;)可以表示各种事物:
    • 一个对象1;
    • 一个函数;
    • 一个标签(MyStructure 中的 struct MyStructure);
    • 结构、联合或枚举的成员;一个 typedef 名称;或
    • 标签(用于 goto 语句,如 goto Error; … Error: exit(EXIT_FAILURE);)。2
  • 标识符有多种作用域,我不会详细讨论:
    • 函数作用域:标签在它出现的整个函数中都是可见的。
    • 文件范围:在任何函数之外声明的标识符从其声明到文件末尾都是可见的(除了隐藏3) .
    • 块作用域:在内声明的标识符(每个{ … }语句都是一个块,但还有其他的,这里没有讨论)对其封闭块的结尾。
    • 函数原型作用域:函数声明的参数声明中的标识符(不是定义)在函数声明符的末尾可见。
  • 每次编译源文件时,标识符都会在声明它们的位置(或者,对于标签,它们出现在带标签的语句中的位置)上是已知的。其他源文件中的标识符未知或不可见;它们不在范围内。
  • 即使相同的标识符出现在两个不同的源文件中,编译器也不知道它们指的是同一个东西。
  • 将源文件编译为目标文件后,将链接目标文件以生成程序。在此过程中,一些标识符被解析为指向同一事物。
  • Linkage 是一个属性,描述了如何使同一标识符的不同实例指向同一事物。
  • 没有链接的标识符永远不会与同一标识符的另一个实例指代相同的事物;没有链接的标识符的每个声明都指向一个独特的事物。
  • 一个带有内部链接的标识符在被编译的源文件中被解析;所有引用都在单个编译内部解析。
  • 具有外部链接的标识符被解析为与其他具有外部链接的源文件中使用的标识符相同的事物。

我们可以将作用域视为一个单一的事物:编译器在其整个作用域中识别标识符并在内部对其进行处理。相比之下,在外部链接中,编译器将有关标识符及其引用的事物的信息放在目标文件中,链接器从不同的目标文件中读取信息并将它们联合起来。只要在目标文件中使用带有外部链接的标识符,链接器都会稍微更改代码,以便标识符的不同用途指代同一事物。

脚注

1 学生可能会将 x 创建的 int x = 3; 视为一个变量。 C 标准对此进行了更技术性的处理:有标识符 x,它是源代码中的文本,还有存储值的内存。 C标准把这个内存称为对象,把一个变量看成两部分,一个标识符表示一个对象,让我们讨论和分析概念更好。

2 标识符也可以表示宏或宏参数,但我不会在本答案中介绍它们。

3 可以在嵌套作用域中声明相同的标识符,如 int x = 3; … { float x = 4.5; … } }。外部标识符的作用域包括内部区域,但外部标识符隐藏在内部作用域中。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...