c++ Primer Plus 第九章

头文件(内容)

  • 函数原型
  • 结构声明
  • 类声明
  • 模板声明
  • 符号常量定义
  • 内联函数

头文件搜索:

  • #include<>在存储标准头文件的计算机的文件系统中查找
  • #include"" 首先在工作目录或者编译器规定的目录中查找,然后再查找标准头文件。

头文件管理:不允许在一个文件中两次调用头文件。解决方法如下:

#ifndef name
// 名称定义
#define name
// 内容
#endif

定义一个名称,如果名称被定义过,则不执行#ifndef 和#endif 之间的数据 。

4种存储方法:自动存储,静态存储,线程存储,动态存储(内存分配)

三个属性:

  • 连续性:
  • 作用域:局部作用域,全局作用域(文件作用域),类作用域,函数原型作用域,名称空间作用域
  • 链接性:外部链接性,内部链接性,无链接性

自动存储

变量:自动变量,局部代码块变量(在代码块中的代码块定义的变量)

持续性:在代码块被执行开始到代码块结束。

作用域:从代码声明开始到代码块结束。

链接性:没有

初始化:一般的初始化

存储位置:放在栈中

静态变量(常规外部变量(全局变量,有时也称外部变量),静态外部变量,静态局部变量)

存储位置:在计算机中开辟一个区域。

初始化:静态初始化和动态初始化

  • 静态初始化包括:零初始化,常量表达式初始化。sizeof(int)属于常量
  • 常量表达式:只由常量组成的表达式
  • constexpr和const:const既表达常量,也表达只读的属性。constexpr只表达常量的属性。

常规外部变量:定义在函数之外,且链接性是外部。单定义准则:在所有的文件中只可以定义一次。

file1中:
int a = 1;
file2中:
extern int a;
// 此处不能初始化,否则就是定义变量和int a = 1;一样

静态外部变量:使用static修饰的外部变量,意味着链接性为内部。

静态局部变量:使用static修饰的局部变量,其中static意味着持续性是整个文件。

int a = 1;    // 外部变量
static int a = 1;   // 静态外部变量
void function(void)
{
    static int a;   // 静态局部变量
}

存储说明符和cv限定符:

存储说明符:

  • auto:自动判别类型。后置返回类型。
  • register:自动变量的标识
  • static:静态变量声明
  • extern:引用声明
  • mutable:对于结构中的值,即是结构声明了const,但是其内部变量仍然可变。
struct name{
    int a;
    mutable double b;
};
const name bob = {1, 2.0}
其中bob.a内容不能变化,但是bob.b内容可以变化
  • thread_local 类似于static,static是在程序执行期间的持续性,而thread_loacl是在线程执行期间的持续性。

cv限定符:

  • const:表示只读属性。const定义的符号全局符号常量的链接性是内部的,所以不会违反单一变量原则。
  • volatile:表示存储的数据即是没有程序代码对内存进行修改,其值仍然会发生变化。

当指向硬件的指针,其内部包含硬件的时间信息,则硬件会修改。或者网络共享的文件,也会被其他人修改。

volatile解决的问题是:对于在很多的代码块内多次使用的参数,编译器会将其放在寄存器当中,从而达到加快运行的目的,而这时如果发生非程序代码更改,则信息无法同步。使用volatile则可避免以上的优化。

函数

函数的持续性:静态。链接性:外部。

静态函数:在原型和定义中加入static,其链接性是内部的。

内联函数可以多次定义:但是c++要求不同文件的相同内联函数定义必须相同。

c++找函数:

  1. 判断函数是否是静态函数,如果是则在文件中寻找。
  2. 在项目中寻找(项目中定义的函数最好不要和标准库中的函数相同)
  3. 在标准库文件中寻找

c++语言链接性:

名称修饰:c++当中的函数为了应对函数重载,所以将函数名和特征标组合并进行修改,形成一个独特的名字,用于函数搜索。对于不同的编译器,得到的名字不同。

C语言库函数和C++的名称修饰不同:所以C++允许对名称修饰方式进行转换:

extern "C" void spiff(int);  // C语言的方式
extern void spaff(int);  // C++方式
extern "C++" void spaff(int);  // C++

动态存储:

new实现动态存储:其返回的指针可以使用静态存储或者自动存储。

new初始化:

new int (4);
new int [4] {1,2,3,4};

new 失败时:使用std::bad_alloc标识

new声明分配函数和释放函数:

// 分配函数
void * operator new(std::size_t);

void * operator new[](std::size_t);

// std::size_t是整形的大小

// 释放函数
void operator delete(void *);

void operator delete[](void *);

// new和delete的函数用法

void * ps = new(sizeof(int));
void * ps = new(n*sizeof(int));

delete (ps);

定位new运算符:

new (buffer) int ;

new (buffer) int [4];

特点:

  • 不和delete连用
  • new分配的空间类型和buffer定义的类型可以不同
  • 可以放在不同的地址
  • 定位new运算符可以重载。

名称空间:不同名称空间同名变量不冲突,且允许程序的其他部分使用该名称空间。全局名称空间包含用户定义的名称空间。

限定名称:即有装饰的名称。非限定名称:就是没有装饰的名称。

using声明,using编译:去除原来名称空间的特性,变成非限定名称。

using声明可以代替变量声明。

using编译和using声明本质区别:

namespace jill
{
    double a;
}
void function()
{
    using namespace jill;
    double a; // 不冲突
}
void function1()
{
    using jill:a;
    double a; // 冲突
}

未命名的名称空间:类似于静态全局变量。

名称空间函数:(对于函数的原型和定义要放在同一个名称空间中)

using name::function_name; // 可以引用所有的重载函数

拥有名称空间之后的一些习惯:

  1.  使用名称空间去替代外部变量和静态外部变量。
  2.  对于标准库文件c++11要求都放在std名称空间中
  3.  尽量使用using声明和作用域解析运算符。

你可能感兴趣的:(c++,c语言,开发语言)