第15章:source files and programs

原创 2016年06月01日 21:24:54

一:源文件要变成计算机可执行文件,需要经过编译和链接两个步骤。编译时,编译器一次只能处理一个源文件,当源文件经过编译变成目标文件后,链接器一次处理多个目标文件,对这些目标文件进行组织,使其变成计算机可执行文件。

二:当链接器链接多个目标文件时,如果一个名字在一个目标文件中被定义,但是可以在其它目标文件中使用,那么就称其有外部链接(external linkage);如果这个名字只能被其定义所在的目标文件使用,那么就称其有内部链接(internal linkage);当然有些名字,链接器不会去查看,比如局部变量的名字,那么就称其为没有链接(no linkage)。虽然具有内部链接的名字和没有链接的名字都只能被其定义所在的文件使用,但是链接器会去查看具有内部链接的名字,而不会去查看没有链接的名字。

三:1:在下面的一些情况下,名字具有外部链接。比如 在全局域,命名空间作用域定义的变量名字,如int x, string s中的名字x 和s;定义的普通函数,模板函数的名字(constexpr函数除外);定义的普通类,模板类的名字。

同时一定要注意的是,在全局域和命名空间作用域中如果一个变量被定义但是没有初始化,这个变量会被默认初始化,比如在全局域或命名空间作用域中的int x语句,或许我们是想声明x,但是事实上这个变量会被赋予初值0,变量x被定义了而不是如我们想的,只是声明而已,要想在全局域或命名空间域中声明,要加上关键字extern,比如extern int x这时候就只是声明x,不是定义。

2:在下面的一些情况下,名字具有内部链接,比如在命名空间作用域或全局域中用static声明的变量,比如static int x1=1;还有就是const,constexpr对象名字,以及 type alias,这些都只有内部链接。但是如果我们想要使const对象名字具有外部链接,那么当我们定义const对象时要在其前面加上extern关键字,比如extern const char c=’a’,这个名字c具有外部链接。

四:我们都听说过”一个定义规则”,说的是一个对象只能被定义一次,但是可以被声明多次。因此对于那些具有外部链接的名字来说,如果他们在两个将要被链接在一起的源文件中都被相同的定义了,那么链接器会报错,比如我们在两个源文件中都定义了一个一模一样的普通函数或者是变量,这时候链接器会报错。

但是我们经常会在头文件中定义一个类,然后被多个将要链接到一起的源文件#include,还有就是内联函数的使用要求其在不同的源文件要被相同的定义, 这两种情况明显违反了上述所说的”只能被定义一次”的规则。那么这该如何解释呢?可以如下来解释:

* 当我们对变量和普通函数应用”一个定义”规则时,我们要求它们只能定义一次,不能在多个源文件中被相同定义。当我们对类,模板类,内联(inline)函数,模板函数等应用”一个定义”规则时,它们可以在多个源文件中被相同定义,但是此时链接器会把这些定义看成是一个定义,这刚好也符合”一个定义”规则(one-definition rule),当然如果他们在同一个源文件中被定义了多次,那么这时候就违反了一个定义规则。*

有了上述的解释,我们就能明白以下一些情况:
1):内联函数可以在多个源文件中被相同定义,通常情况我们会把内联函数的使用放在一个头文件中。
2):我们可以把非模板类的定义放在一个头文件中,同时可以被多个源文件#include。并且由于普通函数不能在两个源文件中被相同定义,因此如果非模板类的成员函数在类体中给出了定义,那么我们就认为这个成员函数是内联函数。但是一般情况下我们会在类体中给出成员函数声明,在另外一个.cc文件中给出成员函数定义。
3):我们也可以把模板类的定义放在一个头文件中,同时可以被多个源文件#include。我们在模板类体中声明模板类成员函数,在另外一个.cc文件中给出该模板成员的定义,但是然后我们会在定义模板类的头文件末尾include该.cc文件。之所以可以这样做是因为模板函数可以在多个源文件中被相同定义,所以当定义模板类的头文件被多个源文件include的时候,不会出现链接错误。

五:我们会经常在头文件中写一些声明或者定义,比如类的定义,函数的声明等等,这时候我们一定要注意当我们在定义(不是声明)一个具有外部链接的名字的时候,一定要确保它不能违反”一个定义”规则,因为我们不知道这个头文件是否会被多个将要被链接在一起的源文件include,比如我们不能在头文件中给出普通函数定义,或变量的定义(像 int a这种)。我们可以在头文件中给出类,模板类,内联(inline)函数,模板函数的定义,正如上面说的,虽然它们的名字具有外部链接,但是并不违反”一个定义”规则。当然我们可以在头文件给出具有内部链接名字的定义,比如const float pi=3.1415,因为这些名字不会被其它源文件访问。一个头文件该包含什么,不该包含什么可以参看15.2.2那一小节。

六:在开发大型程序时,我么应该把逻辑功能相同的接口(interface)放在一个头文件中,同时在对应的.cc文件中给出这些接口的定义,不提倡把不具有相同逻辑功能的接口放在一个头文件中。并且在开发大型项目时,多个头文件被#include是不可避免的,事实上几百个头文件(不包括标准库头文件)被#include是正常的,但是如果几千个头文件被#include,那么这些头文件的管理就变得很麻烦了。因此只在必要的时候才#include头文件这种做法是被提倡的,这不仅可以减少头文件被#include的数目从而缩短编译时间,这也可以避免带来不必要的声明或者定义,而过多的声明或定义或许会造成想象不到的麻烦。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Python核心编程第15章正则表达式练习答案

#15-1 识别下列字符串:“bat,” “bit,” “but,” “hat,” “hit,” 或 “hut” pattern =  r'[bh][aiu]t,?' #15-2  匹配用...
  • iamzhaiwei
  • iamzhaiwei
  • 2012年10月09日 10:54
  • 3492

第15章 动态规划 算法导论

动态规划常用来解决最优化问题,在这类问题中,我们通过做出一组选择来达到最优解。在做出每个选择的同时,通常会生成与原问题形式相同的子问题。 当多于一个选择子集都生成相同的子问题时,动态规划技术通常会很...
  • Xiejunyi12
  • Xiejunyi12
  • 2016年02月11日 22:22
  • 451

算法导论第15章习题答案

Permalink: 2013-05-07 09:51:00 by hyhx2008in clrs tags: clrs algorithm 15.2-2 Q:请给出一个递归算法MATRIX-...
  • sushauai
  • sushauai
  • 2015年11月28日 10:21
  • 3047

《C++primer(第五版)》学习之路-第十五章:面向对象程序设计

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:libin493073668@sina.com】 15.1 OOP:概述 1.面向对象程序设计的核心思想是数据抽象,继承和动...
  • libin1105
  • libin1105
  • 2015年10月02日 23:12
  • 1629

算法导论第15章练习题 15.4-5

15.4-5设计一个O(n²)时间的算法,求一个n个数的序列的最长单调递增子序列。 第一种:对序列进行排序,排序之后得到序列b与原来的序列a,求最长公共子串。(排序之前先将原来序列中的重复元素删掉(保...
  • u013264046
  • u013264046
  • 2017年07月04日 17:19
  • 334

C++ Primer Plus第六版 第十五章 编程练习答案

//第一题 //main.cpp #include "TV.h" int main() { Tv s42; std::cout
  • zhaoshu01234
  • zhaoshu01234
  • 2015年12月10日 15:31
  • 1140

算法导论第十五章--霍夫曼编码

这道题纠结了一天,本想用简单点的方法实现,可是反而弄巧成拙。不过通过写该代码学会了如何使用优先级队列,对优先级队列有了进一步的了解。代码如下: 其中难度较大的是优先级队列的使用,详细的使用方法请参考...
  • liuzhanchen1987
  • liuzhanchen1987
  • 2012年08月12日 18:54
  • 1522

Python核心编程(第十五章)--正则表达式

正则表达式为高级文本模式匹配 [A-Za-z]\w+:第一个字符是字母,由大写字母A~Z或是a~z组成,它后面至少跟有一个(或更多)由字母或数字组成的字符(\w) 搜索和匹配的区别: ...
  • u014380159
  • u014380159
  • 2016年06月22日 14:43
  • 374

C#第15章

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst...
  • qq_36074062
  • qq_36074062
  • 2016年10月20日 14:47
  • 77

DonMin-2017-6-1-day06

9:00-9:45 10:00-10:45 11:00-11:45 学习jeeSite第14章 jeesite在线办公activiti代码流程简介 ---------------------...
  • adfree2
  • adfree2
  • 2017年06月02日 09:04
  • 113
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:第15章:source files and programs
举报原因:
原因补充:

(最多只允许输入30个字)