内存模型和名称空间
一、单独编译
将组件函数放在单独的文件中,然后将它们连接成可执行的程序。将结构声明放到头文件中,使用#include包含(“”),例如:
- 头文件:包含结构声明和结构中的函数原型
- 源代码文件:包含与结构有关的函数的代码
- 源代码文件:包含调用与结构线管的函数的代码
头文件中包含的内容有:
- 结构声明
- 类声明
- 函数原型
- 内联函数
- 模板声明
- 使用#define或const定义的符号常量
在同一个文件中只能包含同一个头文件1次,为了防止包含多次,使用#ifndef来预处理
#ifndef COORDIN_H_
#define COORDIN_H_
#endif
注1:define语句的使用
#define MAXIMUN 4096 //创建符号常量
二、存储持续性、作用域和链接性
- 自动存储持续性:在函数中定义的变量
- 静态存储持续性:static,在程序运行整个过程中都存在
- 线程存储持续性(C++11):thread_local声明
- 动态存储持续性:new分配的内存,直到delete将其释放掉
1. 作用域和链接
- 作用域描述名称在文件中多大范围可见,类中成员作用域为整个类
- 链接性分为外部和内部,内部只能在该文件中使用
2.自动存储连续性
默认情况下,函数中声明的函数参数和变量的存储连续性为自动,作用域为局部,没有链接性。
自动变量只在包含它们的函数或代码块中可见
自动变量和栈:
栈是LIFO,最后加入栈中的变量先被弹出,按函数调用顺序进站出站
寄存器变量:
register int count_fast;//建议编译器使用寄存器来存储自动变量
3.静态持续变量
所有经他变量在整个程序执行期间都存在
- 外部链接性:代码块外
- 内部链接性:代码块外、static
- 无链接性:代码块内、static
int global = 1000; // 静态变量,外部链接性,可以在程序的其他文件中使用
static int one_file =50; //静态变量,内部链接性,只能在该文件中使用
int main()
{
}
void funct1(int n)
{
static int count = 0;
//静态变量,无链接性,只能在funct1()中使用它,
int llama = 0;
}
4.静态持续性、外部链接性
外部变量也成全局变量,在每个使用外部变量的文件中,都应该声明它,单变量只能定义一次,因此C++提供两种声明
- 定义声明(定义):给变量分配存储空间
- 引用声明(声明):引用已有的变量,不分配内存空间,使用extern族谱为关键字
double up; // up = 0
extern int blem; //blem defined elsewhere
extern char gr = 'z'; //定义
如果要在多个文件中使用,那么在一个文件中包含定义,其他文件中使用关键字extern
//file1.cpp
extern int cats = 20;//extern不是必需的
int dogs = 22;
int fleas;
···
//file2.cpp
extern int cats;
extern int dogs;
在函数中使用extern声明外部变量,就可以在该函数中使用
::作用域解析运算符放在变量名前时表示该变量的全局版本
5. 静态持续性、内部链接性
相同变量名的static类型(静态外部变量)可以隐藏另一文件中的常规外部变量,链接性为内部的静态变量可以在同一文件的多个函数之间共享数据
6. 静态存储持续性、无链接性
该变量只在该代码块中可用,但它在该代码块不处于活动和状态时仍然存在。
处理行数如可能长于目标数组的方法:
cin.get(unput,Arsize);
while(cin)
{
cin.get(next);
while(next ! = '\n')//后面还有字符没读完
cin.get(next);//读取后面的字符
strcount(input);
cout << ""<<endl;
cin.get(input,Arsize);
}
7.说明符和限定符
说明符:同一声明中不能使用多个说明符(除thread local)
- register
- static
- extern
- thread local
- mutable
限定符:
- const
- volatile:该变量随时可能发生变化
(1)mutable:即使结构、类变量为const类型,其某个成员也可可以被修改。
struct data{
chat name[30];
mutable int accesses;
};
const data veep={"Claybourge Clodde", 0,};
strcpy(veep.name, "Joye Joux"};// not allowed
veep.accesses++; //allowed
(2)const:const全局变量链接为内部的,与使用了static一样,这样放在头文件中就不违反单定义规则,不需要使用extern
8.函数和链接性
不允许在一个函数中定义另一个函数,默认情况下,函数的链接性是外部的,可以在文件中共享,可以使用static使之成为内部的。
9.存储方案和动态分配
(1) 使用new运算符初始化
//()包含初始值
int *pi = new int(6); //*pu set to 6
//[]初始化数组,{}包含初始值
int *ar = new int[4] {2,4,6,7};
//{}初始化结构
struct where{double x;double y;double z;};
where *one = new where{2.5,5.3,7.2};
//其他
int *pi = new int;
(2)定位new运算符:不能用delete删除
#include<new>
char buffer1[50];
p1 = new (buffer1) chaff;
三、名称空间
1.传统C++名称空间
- 声明区域:可以在其中进行声明的区域
- 潜在作用域:从声明点开始,到声明区域的结尾,但作用域要从定义开始。
2.新的C++名称空间
通过定义一种新的声明区域来创建命名的名称空间,一个名称空间中的名称不会与另外一个名称空间中的名称发生冲突。
名称空间可以嵌套。
- 用户定义的名称空间
namespace Jill{
double bucket(double n){...}
double fetch;
int pal;
struct Hill(...};
}
Jill::Hill mole;
- 全局名称空间:对应于文件级声明区域
3.using声明和using编译指令
- using声明:使一个名称可用
using Jill::fetch;//以后可直接使用fetch
- using编译指令:是所有名称都可用,如果与局部名称发生冲突,局部名称将覆盖掉它
using namespace Jack;