我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

链接性

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

这里的文件并非开发时创建的文件,而是将文件的 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++存储链接性原理的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

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

下载Word文档

猜你喜欢

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

这篇文章主要为大家介绍了C++存储链接性原理示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-03

C/C++函数原理传参示例详解

这篇文章主要为大家介绍了C/C++函数原理传参示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-08

通过手写instanceof理解原型链示例详解

这篇文章主要为大家介绍了通过手写instanceof理解原型链示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-19

React Fiber 链表操作及原理示例详解

这篇文章主要为大家介绍了React Fiber 链表操作原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

C++存储持续性生命周期原理解析

这篇文章主要为大家介绍了C++存储持续性生命周期原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-03

C++预处理连接的示例详解

C++预处理连接(Preprocessor Concatenation)是一种宏定义技巧,用于将两个或多个符号(如变量、字符串等)连接成一个符号。这篇文章主要通过一些示例为大家讲解一下预处理连接,需要的可以参考一下
2023-03-13

C语言动态内存管理malloc柔性数组示例详解

这篇文章主要为大家介绍了C语言动态内存管理malloc柔性数组示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

如何理解C语言数据结构中线性表的链式存储结构

如何理解C语言数据结构中线性表的链式存储结构,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1.什么是线性表的链式存储结构 —链表存储结点:包括元素本身的信息,还有元素之间的关系
2023-06-21

C#使用Task实现执行并行任务的原理的示例详解

Task是一个表示异步操作的类,它提供了一种简单、轻量级的方式来创建多线程应用程序。本文就来和大家聊聊在C#中如何使用Task执行并行任务吧
2023-05-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录