广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++存储链接性原理示例详解
  • 879
分享到

C++存储链接性原理示例详解

C++存储链接性原理C++存储链接性 2023-01-03 18:01:56 879人浏览 八月长安
摘要

目录链接性外部链接性单定义规则内部链接性无链接性总结链接性 链接性是指名称在不同文件之间能否共享,而作用域是指名称在文件内部哪些范围可见。 这里的文件并非开发时创建的文件,而是将文

链接性

链接性是指名称在不同文件之间能否共享,而作用域是指名称在文件内部哪些范围可见。

这里的文件并非开发时创建的文件,而是将文件的 include 内容全部递归包含进来之后,形成的大文件。

这一点也是与Go等一些语言不同。在Go语言中,文件是按包(package)组织,所有依赖的包都需要直接或间接import进来。也就是从main开始递归import得到的就是我们依赖的所有文件。

c++不同。C++源文件主要分.h 和 .cpp两种,一般我们都只会include .h文件,而不会include .cpp文件。因此,.cpp文件之间其实没有直接关联,需要通过cmakelist等方式告诉编译器,我们的程序涉及到哪些源文件。

而C++在编译时,会首先将include的文件内容全部递归包含进来,形成一个大的文件,这个大文件是一个编译单元,也就是上面链接性所说的文件。其实,C++的宏定义的可使用范围,也是在这个大文件内。

链接性有三种:

  • 外部链接性:一个文件声明的名称可以在另一个文件中使用
  • 内部链接性:声明的名称只能在文件内使用
  • 无链接性:意味着只能在函数或代码块内使用

自动类型变量都没有链接性,而静态类型变量可以有三种链接性。那么如何定义这三种链接性的静态变量呢?

外部链接性

链接性为外部的变量也叫外部变量,也称全局变量。外部变量在函数外声明,不加static关键字。外部变量可以在所有文件使用。

对于函数来说,没有加inline和static关键字的函数,都具有外部链接性。

说到外部,可能会想到一个关键字:extern。这个关键字有什么用?实际上它是用来做引用声明。因为如果想使用其他文件中定义的外部变量,不能直接使用,而是要先进行引用声明,表示要引用这个外部变量,这里就需要用到关键字extern。例如:

// file1.cpp
int foo = 1;

// file2.cpp
extern int foo;
// extern int foo = 1; WRONG
cout << foo;

file1.cpp 在函数之外定义了全局变量foo,在file2.cpp中,用extern关键字声明之后,即可使用foo了。注意,extern语句中不能初始化foo,否则这里就变成定义而不是引用声明,导致重复定义全局变量foo,编译错误。

单定义规则

对于外部变量,每个使用它的文件都必须声明它。而C++又有“单定义规则”,即链接性为外部的函数和变量可以有多个声明,但只能有一个定义。这里再明确下这两个术语:“定义声明”,简称“定义”;“引用声明”,简称“声明”。

为了实现单定义规则,编译器要知道这一行代码是在声明还是在定义,那怎么区分声明还是定义呢?

对于函数来说,区分声明和定义很简单,有函数体则是定义,否则为声明。而变量则不同,前面所谓的变量声明,对于编译器来说都是定义,都分配了存储空间。如何声明一个变量而不分配存储空间呢?关键字extern就派上用场了,使用extern关键字且没有进行初始化,则为声明,不会分配存储空间,否则为定义。

C++初学者可能还不太明白为什么C++中都要把函数声明放在.h文件,把函数定义放在.cpp文件中。其实用单定义规则就很好解释了。函数如果没有加inline和static,即具有外部链接性,如果把定义放在.h文件中,这个.h文件会被多个.cpp文件引用,编译时会形成多个副本,相当于被定义了多次。

总之,.h文件中只能放声明,或者没有外部链接性的定义。

可能有小伙伴发现,有些定义在函数外的静态变量没有加static,也会放在.h文件中,为什么可以呢?其实const变量默认会添加static,链接性变为内部。而如果想要声明为外部变量,则需要加上external:

const int foo = 10;  // 链接性为内部
extern const int bar = 10; // 链接性为外部

内部链接性

前面说了,定义在函数外部的变量默认是全局变量,具有外部链接性。但如果加上static说明符,则变成内部链接性。对于函数也一样,加上static则变为内部链接性。

在函数外定义的变量,static的含义与局部变量中static的含义不同。前者表示链接性为内部,后者表示存储持续性为静态。这也可以称为关键字重载,即关键字在不同上下文中有不同含义。

具有内部链接性的变量或函数,可以在不同文件中有多个定义。内部链接性的变量也可以与同名外部变量同时存在,这时内部变量将隐藏外部变量。对函数来说也一样。

无链接性

定义在函数或代码块内的局部变量没有链接性,只能在局部使用。如果加上static修饰则为静态变量,虽然在程序运行期间会一直存在,但只有在代码块内才能使用。

总结

下面总结一下前面提到的不同存储持续性与链接性的变量。

  • 自动存储持续性,无链接性

在代码块内定义

  • 静态存储持续性,无链接性

在代码块内定义,用static关键字

  • 静态存储持续性,内部链接性

在代码块外定义,用static关键字 或const修饰

  • 静态存储持续性,外部链接性

在代码块外定义。引用声明则需要用extern

以上就是C++存储链接性原理示例详解的详细内容,更多关于C++存储链接性原理的资料请关注编程网其它相关文章!

--结束END--

本文标题: C++存储链接性原理示例详解

本文链接: https://www.lsjlt.com/news/176553.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作