【阅读笔记】c++ Primer Plus——第九章

内存模型和命名空间

单独编译

  • c++程序分成三部分
    • 第一部分:包含结构声明和使用这些结构的函数原型(头文件)
    • 第二部分:包含与结构有关的函数代码(源代码文件)
    • 第三部分:包含调用与结构相关的函数代码(源代码文件)
    • 头文件包含了用户定义类型的定义;源代码文件包含操纵用户定义类型的函数代码
  • 头文件中包含的内容:
    • 函数原型
    • #define 或 const 定义的符号常量
    • 结构声明
    • 类声明
    • 模板声明
    • 内联函数
  • 将这些内容放在头文件中,并不会创建变量,而会在源代码声明的时候,告诉编译器如何创建该变量
    头文件中,include使用""和<>的区别是:

    • 使用<>,c++编译器会在存储标准头文件的主机系统的文件系统中进行查找
    • 使用"",c++编译器会首先查找当前工作目录和源代码目录的文件时
  • 在调用头文件的时候,可能会出现头文件包含多次的情况,尤其是项目较为庞大的时候。可以通过使用#ifndef和#endif来避免该变量是否被定义。若COORDIN_H_被定义了,就会跳到endif后面

#ifndef COORDIN_H_
#define COORDIN_H_
struct polar
{
    double distance;
    double angle;
}
# endif

存储持续性、作用域和链接性

  • c++的4种存储方式:

    • 自动存储持续性(局部变量)
    • 静态存储持续性(static)
    • 线程存储持续性(thread_local,生命周期和所属线程一样长)
    • 动态存储持续性(new delete)
  • 作用域和链接

    • 作用域描述了名称在文件的多大范围可见
    • 链接性描述了名称如何在不同单元间共享。链接性为外部的名称可在文件间共享,链接性在内部的名称只能有一个文件中的函数共享

自动存储持续性

  • 默认情况下,函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性
int i = 5;
cout << &i << endl;
{
    cout << "测试" <<endl;
    int i = 2;
    cout << i << endl;
    cout << &i << endl;
    cout << "出来了" << endl;
}
cout << i <<endl;
cout << &i << endl;
cout << i <<endl;

*  这不得来个图

静态持续变量

  • 在c++中,为静态存储持续性变量提供了三种链接性 1. 外部链接性,可在其他文件中访问 2. 内部链接性,只能在当前文件中访问 3. 无连接性,只能在当前函数或代码块中访问
    与自动变量相比,寿命更长
int global = 100;       //第一种
static int test = 50;   //第二种
int main()
{
    ...
    retrn 0;
}
void func1(int n)
{
    static int count = 0 ;  //第三种
    ...
}

全局变量

  • 链接性为外部的变量简称为外部变量(全局变量),存储持续性为静态,作用域为整个文件。外部变量在函数外部定义,可以在main()前面或头文件中定义它们。定义了之后可以在后面的任何函数当中去使用
  • 每个使用外部变量的文件都必须声明它。服从"单定义规则"(变量只能有一次定义)
    • 定义声明,给变量分配存储空间
    • 引用声明,不分配存储空间,直接引用已有的变量(关键字extern)
    • "单定义规则"指的是每个变量只能定义一次,而不是不能有同名变量。若局部变量中存在和全局变量同名的变量,全局变量会被隐藏掉

staic变量

  • 将static限定符用于作用域为整个文件的变量时,该变量的链接性为内部。只能在所属文件中使用。使用static的静态变量,就不必担心其名称与其他文件中的全局变量发生冲突

静态存储性持续性、无链接性

将static限定符用于代码中定义的变量。在代码块中使用static,将导致局部变量的存储持续性为静态。意味着该变量只能在代码块中使用,但在代码块不处于活动状态是仍然存在

void test(int i);

int main()
{
    test(6);
    test(8);
}

void test(int i)
{
    static int result = 0;
    result = result + i;
    cout << result << endl;
}
  • 说明符和限定符
    • c++关键字分为存储说明符和cv-限定符
    • 存储说明符
      • auto
      • static
      • register
      • extern
      • thread_local
      • mutable
    • cv-限定符
      • const
      • volatile
  • 函数和链接性
    • c++不允许在一个函数中定义另外一个函数,因此所有的函数的存储性都默认为静态。同样可以使用static将函数的链接性设置为内部。必须同时在原型和函数定义中都加上static

名称空间

传统的c++名称空间

  • 声明区域是可以在其中进行声明的区域
  • 潜在作用域。变量的潜在作用域从声明点开始到其声明区域的结尾
  • c++对全部变量和局部变量的规则定义了一种名称空间层次,每个声明区域都可以声明名称,这些名称独立于其他声明区域中的声明名称。防止同名变量在不同函数中发生冲突的情况

新的名称空间特性

  • 通过定义一种新的声明区域来创建命名的声明空间(namespace)

  • 一个名称空间中的名称不会与另一个名称空降的同名变量发生冲突,同时允许程序的其他部分使用该名称空间中声明的东西
    using声明和using编译指令。using声明使特定的标识符可用,using编译指令使整个名称空间可用

    • using编译指令由名称空间名和它前面的关键字using namespace组成
      using编译指令和using声明比较

    • using声明,像是声明了相应的名称。如果某个名称已经在函数中声明了,则不能用using声明导入相同的名称

    • using编译指令,将进行名称解析,像是包含了using声明和名称空间本身的最小声明区域中声明了名称一样

    • 如果using编译指令导入一个已经在函数中声明的名称,则局部名称将隐藏名称空间名,就像隐藏同名全局变量一样

  • 一般情况下,使用using声明比使用using编译指令更安全。因为using声明只导入指定名称,如果该名称与局部名称发生冲突,编译器会发出指示。using编译指令导入所有名称,包括并不需要的名称,如果和局部名称发生冲突,会被局部名称覆盖掉名称空间版本,但编译器并不会发出警告
    可以将名称空间声明进行嵌套

namespace elements
{
    namespace fire
    {
        int flame;
        ...
    }
    float water;
}

namespace myth
{
    using Jill::fetch;
    using namespace elements;
    using std::cout;
    using std::cin;
}
  • 可以通过省略名称空间的名称来创建未命名的名称空间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值