C++程序文件链接
1.什么是转换单元
程序中的每个.cpp文件和它包含的所有头文件称为一个转换单元。
编译器处理每个转换单元,生成二进制对象文件,用扩展名.obj来标识。
链接器将对象文件组合起来,生成一个可执行文件,用扩展名.exe来标识。
2.作用域
使用{}来限定变量的作用域
内部作用域可以定义一个和外部作用域相同的名称,此时,内部作用域中定义的名称,将隐藏外部作用域中的名称,
若要访问外层作用域中的名称,可使用解析运算符::,解析运算符的介绍,可参考 C++范围解析运算符::的使用
int main()
{
const int limit =;
std::cout<<"limit 1 is "<<limit<<std::endl;
{
const int limit = ;
std::cout<<"limit 2 is "<<limit<<std::endl;
std::cout<<"limit 3 is "<<::limit<<std::endl;
}
std::cout<<"limit 4 is "<<limit<std::endl;
}
输出结果:
limit 1 is 10
limit 2 is 5
limit 3 is 10
limit 4 is 10
3.转换单元的全局名称属性linkage
每个转换单元中的全局名称,都有一个属性linkage,该属性指明该全局名称可以在程序代码的什么地方使用。
内部链接属性:该名称只能在同一转换单元的任何地方访问。比如全局const变量。
外部链接属性:该名称除了在同一转换单元访问外,还可在其他的转换单元中访问。除了全局const变量,其他的全局名称都是外部链接属性的。
局部名称没有链接属性。
4.什么是“一个定义”规则
在所有的转换单元中,外部链接属性的全局名称,如变量、函数、类类型、枚举类型、模板都只能定义一次。
内联函数除外,内联函数的定义必须出现在调用该函数的每个转换单元中。
内部链接属性的名称可以在多个转换单元中同时定义。
5.如何访问另一转换单元中定义的变量
对于函数来说,如果函数的调用和定义不在同一个转换单元,编译器会把这个函数调用标记为外部的,让链接程序去处理它。
对于变量来说,是不同的。必须使用extern关键字来声明该变量。表示该变量的定义在另一个转换单元中。
示例代码如下:
myextern.cpp
int limit = ; mymain.cpp
int main()
{
extern int limit;
std::cout<<"Extern limit is "<<limit<<std::endl;
return ;
}
由链接属性linkage的介绍,我们知道const变量是内部链接属性的,只能在转换单元内部访问。
而定义一个const变量,希望其他的转换单元都可以使用的情况是常见的,如圆周率PI,const double pi=3.14159265,
那么,怎么才能让const变量也具有外部链接属性呢。
我们只需要在定义const变量时,也加上extern关键字就可以了。
示例代码如下:
myextern.cpp
extern const double pi=3.14159265; mymain.cpp
int main()
{
extern const double pi;
std::cout<<"Extern pi is "<<pi<<std::endl;
return ;
}
另外需要说明的是,extern变量声明的位置,决定了该外部变量的作用域。
参考资料:《C++入门经典 第三版》 pp.309-318
C++程序文件链接的更多相关文章
- 小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号
小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号 https://blog.csdn.net/hotqin888/article/details/84111389 小程序中打开网页和pdf h ...
- linux下c程序的链接、装载和库(3)
9. 目标文件放在一起-->静态库. 你的同事给出的目标文件太多了,从 one.o two.o …… …… 一直到 xxx.o. 好的,你如果真正想用,你的同事提供的这些现有的目标文件,你得做三 ...
- linux下c程序的链接、装载和库(1)
读完<程序员的自我修养--链接.装载和库>相关章节,想来总结一下,若有错误,请指正,多谢. 1. 什么叫目标文件? 你的工程里有很多xxx.c这样的源文件,这些文件是文本文件,只有人能够认 ...
- 解决qt程序的链接阶段出现 undefined reference 错误
错误的原因是我使用到了 QT Widgets 模块中的东西,但是makefile的链接的参数中没有 widgets.其实官网上提到了这个: http://doc.qt.io/qt-5/qtwidget ...
- 程序的链接和装入及Linux下动态链接的实现
http://www.ibm.com/developerworks/cn/linux/l-dynlink/ 程序的链接和装入及Linux下动态链接的实现 程序的链接和装入存在着多种方法,而如今最为流行 ...
- Linux链接库四(多个库文件链接顺序问题)
最近在Linux下编程发现一个诡异的现象,就是在链接一个静态库的时候总是报错,类似下面这样的错误: (.text+0x13): undefined reference to `func' 关于unde ...
- discuz X2.0教程]教你快速了解Discuz!程序文件功能,修改文件从此不用再求人
x3.x数据字典 http://faq.comsenz.com/library/database/x3/x3_index.htm 先从根目录开始,根目录文件一般都是入口,即执行具体功能的代码一般不在这 ...
- c++应用程序文件的编译过程
这里讲下C++文件的编译过程及其中模板的编译过程: 一:一般的C++应用程序的编译过程. 一般说来,C++应用程序的编译过程分为三个阶段.模板也是一样的. 在cpp文件中展开include文件 ...
- [转]c++应用程序文件的编译过程
原文地址 这里讲下C++文件的编译过程及其中模板的编译过程: 一:一般的C++应用程序的编译过程. 一般说来,C++应用程序的编译过程分为三个阶段.模板也是一样的. 在cpp文件中展开inclu ...
随机推荐
- Docker 安装使用
1:安装 在Linux上安装Docker,要求64位操作系统,并且内核版本需求为3.10以上,查看本机Linux内核版本: [root@localhost ~]# uname -r -.el7.x86 ...
- java 设计模式大全
在线学习网址: http://www.runoob.com/design-pattern/
- eclipse手动指定启动的jdk版本
在eclipse.ini中添加 -vm D:/wwjDocument/JDK6/jre/bin/client/jvm.dll -vmargs -Dosgi.requiredJavaVersion=1. ...
- spring启动方式
spring有三种启动方式,使用ContextLoaderServlet,ContextLoaderListener和ContextLoaderPlugIn.看一下ContextLoaderListe ...
- 关于DES加密中的 DESede/CBC/PKCS5Padding
今天看到一段3DES加密算法的代码,用的参数是DESede/CBC/PKCS5Padding,感觉比较陌生,于是学习了一下. 遇到的java代码如下: Cipher cipher=Cipher.get ...
- sublime text3及插件安装过程
本人安装的是sublime text3 1.安装 这个过程下一步下一步即可 2.激活 在help菜单中选择输入验证码,例如以下整个都是: ----- BEGIN LICENSE ----- Andre ...
- python之函数用法file()
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法file() #file() #说明:file()内建函数它的功能等于open(),但 ...
- Linux下umask的缺省默认权限
Linux有缺省默认文件.文件夹权限umask.默认 777 -xxx(文件夹) 666 - xxx(文件) 11.查看当前用户umask R(4)--W(2)--X(1) [root@mvpban ...
- gVim中重新载入当前文件
http://club.topsage.com/thread-2251455-1-1.html有些时候当前打开的文件可能被外部程序不知不觉改变了,这个时候我们就需要重新打开这个文件,或是重读/重载一个 ...
- 浅析若干Java序列化工具【转】
在Java中socket传输数据时,数据类型往往比较难选择.可能要考虑带宽.跨语言.版本的兼容等问题.比较常见的做法有: 采用java对象的序列化和反序列化 把对象包装成JSON字符串传输 Googl ...