变量“作用域类型”提供的哪些信息尚未由变量“链接类型”描述?

问题描述

在“ C编程:一种现代方法”一书中,第18章介绍了一些声明的更多技术特性。在页面459上,作者指出C程序中的变量具有三个属性

  1. 存储时间-(自动静态
  2. 范围-( block file
  3. 链接-(外部内部

我在几个不同的网站和几个不同的S.O上闲逛。帖子,但是我仍然很难理解 范围 链接 间的区别。

我遇到的主要概念困难之一是确定唯一信息,该信息是通过指定链接类型尚未给出的变量 的范围来提供的 strong> 。我似乎完全缺少一些细微差别。

请考虑以下变量声明示例:


情况1:

void foo(void)
{
  static int j;  /* block scope + no linkage */
}

情况2:

int i; /* file scope + external linkage */

int main(void)
{
  .
  .
  .
}

情况3:

static int i; /* file scope + internal linkage */

int main(void)
{
  .
  .
  .
}

如果查看这3种情况,则会发现没有链接的块作用域对和具有内部或外部链接文件作用域对

因此,我看不到通过指定范围添加的信息。就是说:

  1. 如果我知道变量具有链接功能,则我知道范围类型必须为 block
  2. 如果我知道变量具有内部链接外部链接功能,那么我知道范围类型必须为 file 。 / li>

我不熟悉使用块作用域内部链接代码。我不熟悉使用 block范围外部链接代码。最后,我不熟悉使用文件范围且没有没有链接代码

因此,看来链接类型提供了所需的所有相关信息 ...那么,范围的确切含义是什么?

谢谢!

编辑:

用不同的方式讲,这些术语不是不独立的(有某些组合根本不存在,至少看起来是这样)。

这是一张我认为正确地抓住了主意的照片:

Linkage Hierarchy

解决方法

虽然范围和链接之间存在关系,但它们代表两个独立的概念。

此外,C标准为标识符定义了四个不同的范围:

  • 文件
  • 阻止
  • 功能
  • 功能原型

这在C standard的6.2.1p2节中指定:

对于标识符指定的每个不同实体, 标识符可见(即可以使用)仅在 程序文本称为 scope 。不同实体指定dby 同一标识符具有不同的范围或名称不同 空格。范围有四种:功能,文件,块, 和功能原型。 (功能原型是一个声明 声明其参数类型的函数。)

具有功能范围的唯一标识符是标签。标签可以在函数中任何地方被引用。

具有函数原型

标识符是出现在函数声明中的函数参数。例如:

void foo(int x);   //  x has function prototype scope

对于具有函数作用域或函数原型作用域的标识符,它们不表示对象。然后,在那些情况下,标识符没有链接。第6.2.2p6节规定:

以下标识符没有链接:声明为 除了对象或函数之外,还可以是其他任何东西;标识符 声明为函数参数;块范围标识符 对于声明的没有存储类说明符extern

的对象

因此要回答您的问题,标识符的链接并不表示其范围。没有链接的标识符可以具有块作用域,功能作用域或功能原型作用域。