1.1 单独编译
程序可以分为三部分:
➢ 头文件:包含数据类型的声明和函数的原
型声明;
➢ 源代码文件:包含函数的实现或数据类型
的实现;
➢ 源代码文件:包含主调函数(main()函数或
其他客户程序)或相关函数实现
//coordin.h -- struct templates and function prototypes
//struct templates
#ifndef COORDIN_H_
#define COORDIN_H_
struct polar
{
double distance;
double angle;
};
struct rect
{
double x;
double y;
};
//prototypes
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);
#endif //COORDIN_H_
//file1.cpp
#include <iostream>
#include <cmath>
#include "coordin.h"
polar rect_to_polar(rect xypos)
{
using namespace std;
polar answer;
answer.distance =
sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
answer.angle = atan2(xypos.y, xypos.x);
return answer;
}
void show_polar(polar dapos)
{
using namespace std;
const double Rad_to_deg = 57.29577951;
cout << "distance = " << dapos.distance;
cout << ",angle = " << dapos.angle * Rad_to_deg;
cout << " degress." << endl;
}
//file2.cpp
#include <iostream>
#include "coordin.h"
using namespace std;
int main()
{
rect rplace;
polar pplace;
cout << "Enter the x and y value: ";
while(cin >> rplace.x >> rplace.y)
{
pplace = rect_to_polar(rplace);
show_polar(pplace);
cout << "Next two numbers (q to quit): ";
}
cout << "BYE!" << endl;
}
1.2 存储持续性、作用域和链接性
➢ 自动存储持续性:在函数定义中声明的变量,其生命周期与函数执行周期相同;
➢ 静态存储持续性:在函数定义外定义的变量和使用关键字static定义的变量,声明周期与程序运行周期相同;
➢ 线程存储持续性(C++11):多核处理器已经成为常态,程序能将计算放在并行计算的不同线程中。如果变量使用thread_local声明,则生命周期与所属的线程一样。
➢ 动态存储持续性:用new分配的变量,直到delete删除为止;或程序结束为止。
1.2.1 作用域和链接
➢ 作用域和链接
作用域: 描述了名称(变量或对象)在文件中多大的范围是可见的。如函数内定义的变量只能在该函数中使用等。
连接性: 描述了名称如何在不同的单元中共享。
➢ 作用域为局部的变量只能在定义它的代码块中使用;
➢ 代码块是由花括号括起来的系列语句集合;
➢ 作用域为全局的变量在定义位置到文件结尾都可用;
1.2.2 自动存储持续性
在默认情况下,在函数中声明的函数参数和变量是自动存储的,作用域是局部,没有链
接性。
例如: main()函数中声明了texas变量, oil()函数中也声明了texas变量,则创建了两个独立的变量,只有在自己的函数内部才能使用,也不相互冲突。函数结束时,变量自动消失。
自动变量与存储(栈):
自动变量的数目随着函数的调用和结束进行增减,因此程序必须对其进行管理。即使用一段内存,称为“栈”来管理自动变量的增减。
1.2.3 静态持续变量
C++为静态存储持续性变量提供了3种链接性:外部链接性,内部链接性和无链接性。分别是:
➢ 外部:在代码块外面声明;
➢ 内部:在代码块外面声明,且使用static限定;
➢ 无链接:在代码块内部声明。
1.2.3.1 静态持续性、外部链接性
由于外部链接性的功能使得变量可以在多个文件中共享使用,但C++提供了一些规则来防范一些逻辑问题:
➢ 单定义规则:变量只能定义一次。因此,在其他文件使用时,需要使用到“引用声明”,该声明并不将变量再定义一次。
1.2.3.2 静态持续性、内部链接性
将static限定符用于作用域为整个文件的变量时,该变量的链接性将为内部的。
1.2.4 存储方案和动态分配
使用new运算符分配的内存,这种称为“动态内存”。和自动内存不同,动态内存释放不是“后进先出”(栈方式),而是取决于new和delete何时以何种方式被使用
1.3 名称空间实例
//namesp.h
#include <string>
namespace pers
{
struct Person
{
std::string fname;
std::string lname;
};
void getPerson(Person &);
void showPerson(const Person &);
}
namespace debts
{
using namespace pers;
struct Debt
{
Person name;
double amount;
};
void getDebt(Debt &);
void showDebt(const Debt &);
double sumDebt(const Debt ar[],int n);
}
//namesp.cpp -- namespace
#include <iostream>
#include "namesp.h"
namespace pers
{
using std::cout;
using std::cin;
void getPerson(Person & rp)
{
cout << "Enter first name: ";
cin >> rp.fname;
cout << "Enter last name: ";
cin >> rp.lname;
}
void showPerson(const Person & rp)
{
std::cout << rp.lname << ", " << rp.fname;
}
}
namespace debts
{
void getDebt(Debt & rd)
{
getPerson(rd.name);
std::cout << "Enter debt: ";
std::cin >> rd.amount;
}
void showDebt(const Debt & rd)
{
showPerson(rd.name);
std::cout << ": $" << rd.amount << std::endl;
}
double sumDebt(const Debt ar[], int n)
{
double total = 0;
for(int i = 0; i < n; i++)
total += ar[i].amount;
return total;
}
}
//usenmsp.cpp -- using namespace
#include <iostream>
#include "namesp.h"
void other(void);
void another(void);
int main(void)
{
using debts::Debt;
using debts::showDebt;
Debt golf = {{"Benny","Goatsniff"},120.0};
showDebt(golf);
other();
another();
return 0;
}
void other(void)
{
using std::cout;
using std::endl;
using namespace debts;
Person dg = {"Doodles","Glister"};
showPerson(dg);
cout << endl;
Debt zippy[3];
int i;
for(int i = 0; i < 3; i++)
getDebt(zippy[i]);
for(int i = 0; i < 3; i++)
showDebt(zippy[i]);
cout << "The total debt: $" << sumDebt(zippy,3) << endl;
return;
}
void another(void)
{
using pers::Person;
Person collector = {"Milo","Rightshift"};
pers::showPerson(collector);
std::cout << std::endl;
}
1.4 总结
➢ C++鼓励程序员使用多个文件,不同文件定义或实例化不同的程序部分。
➢ C++存储方案决定了变量保留在内存中的持续时间。
➢ 静态变量在整个程序执行过程中都存在。
➢ 默认情况下, C++函数的链接性是外部的。
➢ 动态内存使用new和delete来控制,定位new可以设定内存分配的具体起始地址。
➢ 名称空间允许定义一个可在其中声明标识符的命名区域,有效防止各种命名冲突。
资料参考 C++ Primer Plus (第六版)中文版,仅学习使用