加油鸭
头文件
- 如果文件名包含在尖括号中,则C++编译器将在存储标准头文件的主机系统的文件系统的中查找。如果文件名包含在双引号中,则编译器将在当前目录下查找。
- 使用条件编译防止多次包含头文件。
1
2
3
4
...
存储持续性,作用域和链接性
C++存储方式是通过存储连续性、作用域和链接性来描述的
存储描述 | 持续性 | 作用域 | 链接性 | 如何声明 | 存储位置 |
---|---|---|---|---|---|
自动 | 自动 | 代码块 | 无 | 在代码块中 | 栈中 |
寄存器 | 自动 | 代码块 | 无 | 在代码块中,使用关键字register | 寄存器中 |
静态,无链接性 | 静态 | 代码块 | 无 | 在代码块中,使用关键字static | 内存块 |
静态,外部链接性 | 静态 | 所有文件 | 外部 | 不在任何函数中 | 内存块 |
静态,内部链接性 | 静态 | 本文件 | 内部 | 不在任何函数内,使用关键字static | 内存块 |
- 如果定义一个静态外部链接性的变量,其他文件在使用时,需要引用声明使用关键字extern,且不进行初始化。
链接性(linkage)描述了名称如何在不同单元间共享。
- 链接性如果为外部,则名称可在文件间共享。
- 链接性如果为内部,则名称只能由一个文件中的函数共享。
- 自动变量的名称没有链接性,因为他们不能共享。
作用域解析运算符::
作用::就是当局部变量和全局变量名字重叠的时候,指定某变量一定是来自全局变量。1
2
3
4
5
6
7int a=5;
int main()
{
int a=3;
cout<<a<<endl;
cout<<::a<<endl;//作用域解析运算符,此时的a为全局变量的a
}
说明符
- register 用于在声明中指示寄存器存储,而在C++11中,它只是显式地指出变量是自动的。
- static 表示内部链接性。
- extern 表面是引用声明,即声明引用在其他文件定义的变量。
- thread_local(C++11新增) 指出变量的持续性与其所属的线程的持续性相同。thread_local变量之于线程,犹如常规静态变量之于整个程序。
- mutable 用来指出,即使结构(或类)变量为const,其某个成员也可以被修改。
1
2
3
4
5
6
7
8
9
10
11struct student
{
char name[30];
mutable int score;
};
int main()
{
const student a={"guo shen",100};
a.score++;
cout<<a.name<<' '<<a.score<<endl;
}
cv-限定符之volatile
- 即使程序代码没有对内存单元进行修改,其值也可能发生变化(可能受硬件影响)。
- 如果不使用volatile变量,在再次访问之前编译器可能会认为值没有变化,从而进行优化(如将值放在寄存器中缓存起来)。
- 使用volatile变量相当于告诉编译器,不要进行这种优化。
cv-限定符之const(不能修改的内存)
- const 对全局变量的链接性有影响 – const全局变量的链接性为内部的。
- 也是const变量能写在头文件而没有多重定义的原因。
- 若想使用链接性为外部的const变量,则可以再在前面加extern进行定义,但其他文件使用此变量必须也要用extern关键字进行声明。
1
extern const int maxn = 100;
函数的链接性
- 函数默认为外部静态的 即默认是extern的。
- 可使用 static 关键字将其链接性设置为内部的。
- 必须同时在原型和定义中使用static。
- 内部静态函数将覆盖外部函数。
名称空间
名称空间特性
为解决名称冲突的问题使用名称空间工具。
1
2
3
4
5
6
7
8
9
10
11
12namespace Tom{
double pail;
void fetch();
int pal;
struct Well {..};
}
namespace Jerry{
char other;
void fetch();
int pal;
struct Hill {..};
}名称空间可以是全局的,也可以位于另一个名称空间中,但不可以位于代码块中。
- 默认情况下,名称空间中声明的名称的链接性为外部的。
- 访问某一名称空间中的名称要使用作用域解析符::
1
2
3namespace Tom{
char *name;
}
using 编译指令和 using 声明
- using 声明使特定的标识符可用 :using Tom::pal=1;
- usng编译指令使整个名称空间所有的名称都可用。
- 使用using 声明和using编译指令可能会增加名称冲突的可能性,使用作用域解析运算符就不会存在二义性。
- 如果某个名称已经在函数声明了,则不能用using声明导入相同的名称。
- 如果使用using编译指令,名称空间相当于全局的,那么局部名称将隐藏名称空间名,就像隐藏同名的全局变量一样。不过仍可以使用作用域解析运算符。
关键字new 和 delete
1 | // 初始值 |