coordin.h头文件
#ifndef COORDIN_H_ //#ifndef #endif可以避免多次包含同一个头文件多次
#define COORDIN_H_
struct polar //头文件常包含的内容:1、函数原型 2、结构声明 3、类声明
{ //4、使用#define或const定义的符号常量 5、模板声明 6、内联函数
double distance;
double angle;
};
struct rect
{
double x;
double y;
};
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);
#endif
内存模块和名称空间.cpp
#include<iostream>
#include<new>//要使用
#include"coordin.h" //注意引用创建的头文件应使用双引号“”,因为编译器会根据不同的引用方式,来进行查找
//<>号会先在存储标准头文件的主机系统的文件中查找,“”则会先在工作目录和源代码目录下查找
namespace jack
{
double pail;
void fetch();//名称空间既可以定义变量,还可以定义函数,结构,类
int pal;
struct well
{
int mark;
int age;
};
}
namespace elements
{
namespace fire//名称空间的嵌套
{
int flame;
}
float water;
}
namespace myth
{
using jack::pal;//在名称空间中可以使用using声明和编译指令
using namespace elements;
}
namespace
{
int ice;
}
using namespace std;//每个头文件只能包含一次————
struct date
{
int year;
int month;
mutable int day;//mutable说明符表明可以修改此成员值
};
struct where
{
double x;
double y;
double z;
};
int global;//外部链接性
static int one_file;//内部链接性
int sum(int, int);
extern "C" void spiff(int);//引用c语言链接性指定的符号名称
extern int warming;
static int error = 798;//不会影响file1中的error变量,不会违反单定义规则————链接性为内部
int main()
{
rect rplace;
polar pplace;
cout << "enter:";
while (cin >> rplace.x >> rplace.y)//正因如此我们现在是根据文件进行单独编译————利用多个文件整合成一个程序
{
pplace = rect_to_polar(rplace);
show_polar(pplace);
cout << "next:";
}
cout << "bye!!";
//存储持续性、作用域和链接性
//存储方式有4种:1、自动存储持续性 2、静态存储持续性 3、动态存储持续性 4、线程存储持续性(了解)
//作用域有3种:1、局部作用域:只能在代码块中使用 2、文件作用域:定义位置到结束都可以使用 3、函数原型作用域:只在函数定义中使用
//链接性:描述了名称如何在不同单元(文件)间共享
//自动变量初始化可以使用任何在声明时其值为已知的表达式来初始化自动变量
//自动变量和栈:变量随着函数的开始和结束消失————按顺序存放在栈中,先进后出——对变量进行标记
//寄存器变量————使用register关键字————将变量存在寄存器中————这皆在提高访问变量的速度
register int count_fast;
//静态存储持续性变量提供了3种链接性:外部链接性(可在其它文件中访问),内部链接性(只能在当前文件),无链接性(只能在当前函数和代码块)
//注意内部和无都要使用static关键字
static int count;//无链接性————如果没有显示初始化静态变量,将自动初始化为0;数组和结构一样
// ———————— —————————— ——————————— ——————————— ———————————— —————————— ——————————
//c++单定义规则:变量只能有一次定义,给变量分配内存地址。1、定义声明——分配内存 2、引用声明——不会分配内存——引用已有变量
extern int process_status;//使用关键字extern引用变量————该变量在file.cpp文件中
//如果函数中声明了一个与外部变量同名的变量,将被视为自动变量的定义
//静态外部(链接内部)会隐藏常规外部——————同名的情况下
//静态存储(无链接性)链接性为内代码不处于活动状态时仍然存在
//存储说明符和限定符(const、volatile)-- 同个声明中不能使用多个存储符————thead_local不同,可以结合static和extern使用
//存储说明符:auto、register、static、extern、thead_local、mutable
//thead_local指出变量的持续性与其所属线程的持续性相同———之于线程———犹如常规静态变量之于整个程序
//volatile限定符表明即使程序代码没有对内存单元进行修改,其值也有可能变化——————相当于做标记
//回到mutable,可以用它来指出,即使结构或类变量为const,某个成员的值也可以修改
//注意const全局变量的链接性为内部的————就像使用了static说明符一样
//语言链接性,链接程序要求每个函数都有不同的符号名,对于c++重载函数来说,要生成不同的符号名称---14行
//存储方案和动态内存————new运算符
//动态内存由new和delete控制,而不是由作用域和链接性规则控制
int* pi = new int(6);
double* pd = new double(99.99);//使用new运算符初始化
int* one = new int [4] {2, 4, 6, 7};
where* onw = new where{ 2.5,5.3,7.2 };//也可以使用c++11的列表初始化边分配内存边赋值!
//当new失败的时,c++会返回空指针
//new和new[]被称为分配函数————会将一些形式自动转化
int* pu = new int;
int* pu = new int (sizeof(int));//上一行将自动转化为这一行
int* pa = new int[40];
int* pa = new int(sizeof(int) * 40);//上一行将自动转化为这一行
//这就是c++函数可替换
//定位new运算符————能够指定要是用的位置——分配内存(可以有方括号,也可以没有)
char buffer1[512];
char buffer2[50];
where* p;
int* p_;
p = new (buffer1) where;//使用buffer1数组的位置来提供内存空间
p_ = new(buffer2) int[20];//使用buffer2数组的位置来提供内存空间
//其实按道理来说,如果要释放p和p_的内存,delete是不行的,因为buffer1和2并不是由new分配出来的——————P265页
//名称空间
//声明区域是可以在其中进行声明的区域。潜在作用域是变量从声明起点开始到声明区域的结尾。————得出潜在作用域小于声明区域
//变量对于程序而言可见的范围称为作用域
//c++通过一种新声明区域创建命名的名称空间————namespace关键字————第5行
//一个名称空间中的名称不会与另一个名称空间中的名称相互冲突
//名称空间可以是全局的,也可以位于另一个名称空间中,但就是不能位于代码块中
//除了用户定义的名称空间外,还存在一个自带的名称空间————全局名称空间——其实就是文件作用域
//访问给定名称空间中的名称,通过作用域解析运算符::
jack::pal = 1314;//未限定名称————pal
jack::pail = 1.314;//通过限定进行访问的名称叫限定的名称————jack::pail
//using声明和using编译指令--using声明使特定的标识符可用,using编译指令使整个名称空间可用
using jack::pal;//使用using指令,将名称添加到局部空间中,会覆盖掉已有同名变量和同名的全局变量
cin >> pal;
cout << pal;
//在全局声明区域使用using编译指令,将使得名称空间中的名称全局可用
//一般来说using声明比using编译指令更安全,可以一个一个的导入名称————但就是要多次使用作用域解析运算符
//名称空间的嵌套————复合的使用作用域编译运算符--16行
using elements::fire::flame;//复合使用using声明
//另外也可以在名称空间中使用using编译指令和using声明--24行
//使用未命名的名称空间————提供了链接性未内部的静态变量的替代品--29行
cin >> ice;
cout << ice;
}
namespace jack
{
char* goose(const char*);//名称空间是开放的,可以将名称加入到已有的名称空间中
}
int sum(int a, int b)
{
a *= 2;//a和b都是局部作用域————具有自动存储的特性————使用完之后自动销毁释放内存
static int total = 0;//静态存储,链接性为内部————只在程序运行时,被定义为0
return a + b;
}
void print()
{
extern int warming;
cout << warming;
cout << ::warming;//只有在引用变量为全局时,才能用作用域解析运算符 ::
//放变量名在::前面时,该运算符表示使用变量的全局版本
}
void see()
{
using namespace jack;//使用using编译指令使得空间中的所有名称都可用
cout << pal;
cin >> pail;
}
//这里补充一点名称空间的理念
//1、使用已在名称空间中声明的变量,而不是使用外部全局变量或全局变量
//2、不要在头文件中使用using编译指令
//3、导入名称优先使用作用域解析运算符或using声明
//4、对于using声明,首先将其作用域设置未局部
file1.cpp
#include<iostream>
#include<math.h>
#include"coordin.h"//包含进coordin头文件,可对里面原型函数进行定义#1、#2
int process_status = 0;//静态外部链接性变量
int warming = 45;
int error = 798;
polar rect_to_polar(rect xypos)//#1
{
using namespace std;
polar answer;
answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
answer.angle = atan(xypos.y, xypos.x);
return answer;
}
void show_polar(polar dapos)//#2
{
using namespace std;
const double red_to_deg = 57.29577951;
cout << dapos.distance;
cout << dapos.angle * red_to_deg;
cout << "degress\n";
}