什么是外部联动和内部联动?

我想了解外部连杆和内部连杆以及它们的区别。

我也想知道的意思

除非声明为extern,否则默认情况下const变量内部链接。

175827 次浏览

当你写一个实现文件(.cpp.cxx等)时,你的编译器会生成一个翻译单元。这是你的实现的源文件,加上你在其中#included的所有头文件。

内部链接只指向在翻译单元的范围内

外部链接指的是存在于特定翻译单元之外的东西。换句话说,可通过整个程序访问,它是所有翻译单元(或目标文件)的组合。

正如dudewat说一样,外部链接意味着符号(函数或全局变量)可以在整个程序中访问,而内部链接意味着它只能在一个翻译单元中访问。

可以通过使用externstatic关键字显式控制符号的链接。如果没有指定链接,则默认链接为extern(外部链接)用于非-const符号,static(内部链接)用于const符号。

// In namespace scope or global scope.
int i; // extern by default
const int ci; // static by default
extern const int eci; // explicitly extern
static int si; // explicitly static


// The same goes for functions (but there are no const functions).
int f(); // extern by default
static int sf(); // explicitly static

注意,与其使用static(内部链接),不如使用匿名< em > < / em >名称空间,你也可以在其中放入classes。尽管匿名名称空间允许extern链接,但匿名名称空间无法从其他翻译单元访问,因此链接有效地 static

namespace {
int i; // extern by default but unreachable from other translation units
class C; // extern by default but unreachable from other translation units
}
  • 全局变量默认具有外部链接。通过在另一个文件中给出匹配的extern声明,它的作用域可以扩展到包含它以外的文件。
  • 通过在声明前加上关键字static,可以将全局变量的作用域限制在包含其声明的文件中。这样的变量被称为内部链接

考虑下面的例子:

1. cpp

void f(int i);
extern const int max = 10;
int n = 0;
int main()
{
int a;
//...
f(a);
//...
f(a);
//...
}
  1. 函数f的签名将f声明为带有外部链接(默认值)的函数。它的定义必须在后面的文件或其他翻译单元中提供(如下所示)。
  2. max被定义为一个整数常量。常量的默认链接是内部。通过关键字extern将其链接更改为外部链接。所以现在max可以在其他文件中访问。
  3. n被定义为一个整型变量。函数体外定义的变量的默认链接是外部

2. cpp

#include <iostream>
using namespace std;


extern const int max;
extern int n;
static float z = 0.0;


void f(int i)
{
static int nCall = 0;
int a;
//...
nCall++;
n++;
//...
a = max * z;
//...
cout << "f() called " << nCall << " times." << endl;
}
  1. max被声明为具有外部链接max的匹配定义(带有外部链接)必须出现在某个文件中。(如1.cpp)
  2. n被声明为具有外部链接
  3. z是带有内部链接的全局变量定义
  4. nCall的定义指定nCall是一个变量,在调用f()函数时保持其值。与具有默认自动存储类的局部变量不同,nCall将只在第一次调用f()时初始化一次。存储类说明符static影响局部变量的生存期,而不是其作用域。

关键字static有双重作用。在全局变量定义中使用时,它指定内部链接。当在局部变量的定义中使用时,它指定变量的生存期将是程序的持续时间,而不是函数的持续时间。

希望有帮助!

在“C”方面(因为静态关键字在“C”和amp之间有不同的含义;“c++”)

我们来谈谈C中的不同作用域

范围:它基本上是指我能看东西多长时间和多远。

  1. 局部变量:作用域只在函数内部。它位于RAM的STACK区域。 这意味着每次函数被调用时所有的变量 这是函数的一部分,包括函数实参 控件刚创建,一旦控件离开 函数。(因为每次函数返回时堆栈都会刷新)

  2. 静态变量:用于文件的作用域。它可以在
    文件中的任何地方访问 它被宣布了。它驻留在RAM的DATA段中。自 这只能在文件内部访问,因此是INTERNAL链接。任何< br > 其他文件不能看到这个变量。实际上STATIC关键字是 只有这样我们才能引入一些级别的数据或函数
    隐藏在'C'

  3. 全局变量:该变量的作用域适用于整个应用程序。它可以从任何地方获得 申请的地点。全局变量也驻留在DATA段中 因为它可以在应用程序的任何地方访问,因此 李外部链接< / p > < / >

默认情况下,所有函数都是全局函数。以防万一,如果你需要 从外部隐藏一些函数在文件中,你可以前缀静态 函数的关键字。: -) < / p >

在讨论这个问题之前,最好准确地了解术语< em >翻译单元< / em >< em > < / em >程序和c++中的一些基本概念(实际上链接是其中之一)。你还必须知道什么是范围

我将强调一些重点,特别是之前回答中遗漏的部分。

链接的名字的属性,由宣言引入。不同的名字可以表示相同的实体(通常是一个对象或函数)。因此,谈论实体的链接通常是毫无意义的,除非你确定实体只会被某些特定声明(通常是一个声明)中的唯一名称引用。

注意对象是一个实体,而变量不是。在讨论变量的链接时,实际上关注的是所表示实体的名称(由特定声明引入)。名称的联动是在三种情况之一:不联动、内部联动或外部联动。

不同的翻译单元可以通过头文件/源文件(是的,这是标准的措辞)共享相同的声明。所以你可以在不同的翻译单元引用相同的名称。如果声明的名称具有外部链接,则该名称引用的实体的标识也将被共享。如果声明的名称具有内部链接,则不同翻译单元中的相同名称表示不同的实体,但您可以引用同一翻译单元的不同作用域中的实体。如果名称没有链接,则无法从其他作用域引用实体。

(哦…我发现我键入的内容只是在重复标准措辞…)

还有一些语言规范没有涵盖的令人困惑的地方。

  1. (名字的)可见性。它也是声明名称的属性,但是意思和连杆不同
  2. (副作用的)可见性。这与本主题无关。
  3. (符号的)可见性。这个概念可以是由实际实现使用。在这样的实现中,在对象(二进制)代码中具有特定可见性的符号通常是从实体定义映射的目标,其名称在源(c++)代码中具有相同的特定链接。然而,通常不能保证一对一。例如,动态库映像中的符号只能从源代码(涉及到一些扩展,通常是__attribute____declspec)或编译器选项中指定在该映像内部共享,并且映像不是整个程序或从翻译单元翻译的目标文件,因此没有标准概念可以准确地描述它。由于符号在c++中不是一个规范术语,它只是一个实现细节,即使方言的相关扩展可能已经被广泛采用。
  4. 可访问性。在c++中,这通常是关于类成员或基类的属性,这又是一个与主题无关的不同概念。
  5. 全球。后者在C语言中大致相当于文件范围。在C和c++中,链接都与作用域无关,尽管作用域(像链接一样)也与某个声明引入的标识符(在C中)或名称(在c++中)密切相关。

命名空间作用域const变量的链接规则是一些特殊的东西(尤其不同于C语言中在文件作用域中声明的const对象,后者也具有标识符链接的概念)。由于ODR是由c++强制执行的,因此除了inline函数外,在整个程序中保持同一个变量或函数的定义不超过一个是很重要的. C。如果const没有这样的特殊规则,那么在程序中由多个翻译单元(或由一个翻译单元包含不止一次,但很少)的头文件或源文件(通常是“头文件”)中使用初始化器(例如= xxx)对const变量进行最简单的声明将违反ODR,这使得使用const变量替换某些类对象宏是不可能的。

我认为c++中的内部和外部链接给出了一个清晰而简洁的解释:

翻译单元指的是一个实现(.c/.cpp)文件和所有 头文件(.h/.hpp)。如果一个对象或函数在里面 这样的翻译单元有内部的联动,则说明具体 符号仅对该翻译单元内的链接器可见。如果 对象或函数具有外部链接,链接器也可以看到它 当处理其他翻译单元时。当使用static关键字时 在全局名称空间中,强制符号具有内部链接。的 关键字Extern将导致具有外部链接的符号

编译器默认的符号链接如下:

非const全局变量默认具有外部链接
Const全局变量默认有内部链接
函数默认具有外部链接

基本上

  • extern linkage变量在所有文件中可见
  • internal linkage变量在单个文件中可见。

解释:默认情况下,const变量内部链接,除非声明为extern

  1. 默认情况下,全局变量为external linkage
  2. 但是,const全局变量是internal linkage
  3. 另外,extern const全局变量为external linkage

这是一本关于c++中的链接的很好的材料

http://www.goldsborough.me/c/c++/linker/2016/03/30/19-34-25-internal_and_external_linkage_in_c++/

联动确定具有相同名称的标识符是否引用相同的对象、函数或其他实体,即使这些标识符出现在不同的转换单元中。标识符的链接取决于它是如何声明的。 有三种类型的连杆:

  1. 内部链接:标识符只能在翻译单元中看到。
  2. 外部链接:标识符可以在其他翻译单元中看到(并引用)。
  3. 没有链接:标识符只能在定义它们的作用域中被看到。 链接不影响范围

c++只:你也可以在c++和非c++代码片段之间建立链接,这被称为语言的联系

来源:IBM程序联动

在c++中

任何不在类或函数内嵌套的文件范围内的变量,在程序的所有翻译单元中都是可见的。它被称为外部链接,因为在链接时,该名称在翻译单元之外的任何地方都对链接器可见。

全局变量与普通函数具有外部联系。

静态对象或函数在文件作用域的名称是翻译单元的本地名称。这是 内部链接

链接仅指在链接/加载时具有地址的元素;因此,类声明和局部变量没有关联。