①单独编译
1.介绍
C++鼓励大家将组建函数放在独立的文件里。编译器可以单独编译这些文件,然后将它们链接成可执行的程序。如果只修改了一个文件,则可以只重新编译该文件,然后将它与其他文件的编译版本链接,这使得大程序的管理更便捷。
我们可以将原来的程序分成三部分:1)头文件 2)源代码文件 3)源代码文件。
1.头文件:
我们可以将 函数原型,#define 或const定义的符号常量,结构声明,类声明,模板声明和内联函数放在头文件中,在每一个源代码文件中包含该头文件,并且,在需要修改的时候,只需要修改头文件一处即可。
不要把函数定义或变量声明放到头文件中,因为如果将函数定义放到头文件,同一程序的其他文件中包含该头文件,则同一个程序中包含同一个函数的两个定义,除非函数是内联的,否则这将出错。
在包含头文件时,我们用的双引号而不是尖括号,这是因为如果文件名包含在尖括号内,C++编译器将在存储标准头文件的主机系统的文件系统寻找,文件名包含在双引号中,编译器首先查找当前的工作目录或源代码目录,如果没有找到头文件,将在标准位置查找。所以在包含自己的头文件时,应使用双引号。
#ifndef COORDIN_H_ //和后边的endif像是个选择语句(if not defined)
#define COORDIN_H_
struct polar
{
double distance;
double angel;
};
struct rect
{
double x;
double y;
};
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);
#endif
在同一个头文件中只能将同一个头文件包含一次,但是在不知情的情况下,我们可能使用了包含另一个头文件的文件,因此采用#ifndef 和 endif来进行选择,本质上头文件还是包含多次,只是包含多次被选择性忽略掉。
2.源代码文件——函数定义
#include<iostream>
#include<cmath>
#include"cooedin.h"
using namespace std;
polar rect_to_polar(rect xypos)
{
polar answer;
answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
answer.angel = atan2(xypos.y, xypos.x);
return answer;
}
void show_polar(polar dapos)
{
const double Rad_to_deg = 57.29577;
cout << "distance = " << dapos.distance;
cout << "angel = " << dapos.angel * Rad_to_deg
<< "degrees\n";
}
3.源代码文件——主函数
#include<iostream>
#include"cooedin.h"
using namespace std;
int main()
{
rect rplace;
polar pplace;
cout << "Enter the x and y values:";
while (cin >> rplace.x >> rplace.y)
{
pplace = rect_to_polar(rplace);
show_polar(pplace);
cout << "Next two numbers:(q to quit):";
}
cout << "Bye!\n";
return 0;
}
将这两个源代码文件和新的文件头一起进行编译和链接,将生成一个可执行程序。
注意:C++标准允许编译器设计人员以他认为合适的方式实现名称修饰,因此由不同的编译器创建的对象代码文件很可能无法正确的链接。在链接编译模块时,请确保所有对象文件或库都是由同一个编译器生成的。如有源代码,通常可以用自己的编译器重新编辑源代码来消除链接错误。
②存储持续性、作用域和链接性
1.介绍
存储持续性:数据保留在内存中的时间。可以分为4种:
1)自动存储持续性 2)静态存储持续性
3)线程存储持续性 (生命周期和所处线程一样长)
4)动态存储持续性 (new来分配,delete删除,有时被称为自由存储或堆)
作用域:作用域描述了名称在文件(翻译单元)的多大范围可见,可以分为:
1)作用域为局部 2)作用域为全局
3)函数原型作用域 (函数原型中所使用的名称只在函数参数列表括号内可用)
4)作用域为整个类(类中声明的成员)
5)作用域为整个名称空间(名称空间声明的变量)
6)函数作用域 (可以是整个类或整个名称空间,但不能是局部的,局部函数将无法被调用&#x