C++学习笔记(七)

内存模型和名称空间(单独编译、存储持续性、作用域、链接性、说明符、限定符、布局new操作符、名称空间)

1.模板声明由于不是将被编译的代码,只是指示编译器如何生成与源代码中的函数调用相匹配的函数定义,因此放在头文件中是可以的

2.在链接编译模块时,要确保所有的对象文件或库都是由同一个编译器生成的。如果有源代码可以用自己的编译器重新编译源代码来消除链接错误。

3.C++采用三种方案来存储数据,区别在于数据在内存中保留的时间,分别是:自动存储持续性、静态存储持续性和动态存储持续性。

自动存储持续性:函数定义中声明的变量,程序执行这部分函数或代码块时被创建,执行完这部分时释放

静态存储持续性:函数定义外定义的变量和使用static定义的变量,在程序整个运行中存在。

动态存储持续性:使用new分配的内存,知道被delete时释放内存。

4.链接性:名称在不同单元之间的共享。链接性为外部的名称可在文件间共享,为内部的名称只能由一个文件中的函数共享。自动变量没有链接性,因为它们不能共享。

5.在类中声明的成员作用域为整个类。名称空间中声明的变量作用域为整个名称空间。函数的作用域不能是局部的,可以是整个类或整个名称空间(包括全局的)。

6.堆栈:LIFO后进先出。一段用于管理变量的内存。新的数据被放在原有数据的相邻内存单元中,程序使用完变量后从堆栈中删除它。堆栈的默认长度取决于实现,但编译器通常提供改变堆栈长度的选项。使用指向栈底(堆栈开始)和指向变量后的下一个可用内存单元的指针来管理。

 

7.自动存储持续性

(1)自动变量:可以用关键字auto指出,不过多数是默认给定,因此可以省略auto。

   自动变量可以使用任何已知值的表达式进行初始化。

   自动变量用堆栈进行管理,当函数被调用时,自动变量被加入到堆栈,指向栈顶的指针向后移动,函数结束栈顶指针重置为调用函数前的值,从而释放新变量使用的内存。

  (2)寄存器变量:使用register关键字指出  形如: register int count_fast;

    寄存器变量与自动变量类似,存储持续性为自动、作用域为局部、无链接性,但区别在于不用堆栈管理,而是用寄存器管理,因此访问速度比放在堆栈内存块中的变量速度要快。

   注意:寄存器变量由于没有被放置在内存中,因此没有内存地址,因此不能对它进行取地址操作。

9.静态持续变量:静态持续变量有三种链接性——外部链接性、内部链接性、无链接性

  (1)静态变量在程序运行期间不变,因此可以直接放在内存中,不需要用堆栈进行管理。

  (2)如果静态变量没有初始化,则默认它值为0,若为数组则每个元素为0。

  (3)三种声明: 

         int global = 1000;            //外部链接性         在代码块外声明    (也称全局变量)

                                                                             作用域为整个文件,从声明到文件结尾,可以在程序的其他文件中使用

         static   int onefile=50;     //内部链接性         代码块外声明,用static标识 

                                                                             作用域为整个文件,从声明到文件结尾,只能在包含它声明的代码文件中使用

         int main()

         {

                ...

         }

         void fun1(int  n)

         {

                  static int count =0;              //无链接      代码块内声明,用static限定   

                                                                                作用域为代码块内,函数不被执行时也存在于内存中

                  int linma=0;

          }

    

    (4)初始化: (一)未被初始化,则默认初始化为0;(二)只能用常量表达式来初始化静态变量(字面常量、const、enum 或sizeof)

   (5)外部存储时为防止数据被修改,可以使用常量数据,用const进行修饰,如:

            const char * const month[12]=       //第一个const防止字符串被修改,

                                                                   //第二个const确保数组中的每个指针始终指向它最初指向的字符串

           {

                         "January","February",.....

           }

 

    (6)对于外部链接性变量,如果只有一个文件中包含了该变量,其他文件中要引用时需要在引用声明中加extern。

    (7)如果两个文件中,A文件的静态外部变量和当前常规外部变量(static声明的)重名,则隐藏A中声明的静态变量。

 

   10.cv限定符: const 与 volatile

   const:内存被初始化后,程序将不能对内存单元进行修改(链接性为内部)

   volatile:即使程序代码没有对内存进行修改,其值也可能发生改变(如硬件修改或两个程序相互影响)。作用是改善编译器的                    优化性能。将变量声明为volatile相当于告诉编译器不要进行优化

   mutable:即使结构或类变量为const,某个成员也可以被修改,如:

     

             struct data

             {

                           char name[30];                    //不可以被修改

                            mutable int accesses;            //可以被修改

                            ...  

           };

              const data veep = {"ddddd",0,...};

             

11.函数存储持续性为静态,链接性为外部的。但如果在函数的声明和定义前加上static关键字,则函数变为内部链接函数,只能在当前文件中使用。且这个静态函数会覆盖外部定义。

12.C++中引用C库文件中的函数spiff可以利用extern :

   extern "C" void spiff(int);  

   同理有用法extern void spoff(int); 和 extern "C++" void spaff(int); 

13.编译器中使用三块独立的内存用于存放静态变量、自动变量和动态存储。

     其中,动态存储的内存分配和指向内存指针分配方式不同。指向该地址的指针可以是自动或静态指针变量。如:

   float *p_fees = new float[20];  //new的空间将一直在内存中,直到被delete。指针p_fees会包含在该声明的函数结束时消失。

14.new在堆(heap)中为被定义的变量分配内存 ,如果要指定new出的内存分配的地址(如在一个自定义的buffer中)可以使用布局new,使用时需要包含头文件<new>,除需要指定参数外,其他与new的使用相同。具体如下:

   double *pd1,*pd2;

   char buffer[512];

    pd1=new double[5];     //常规new,在堆中分配内存

    pd2= new (buffer)double[5];  //布局new,在buffer中分配内存

 

15.名称空间:可以是全局的或位于另一个名称空间中,但不能位于代码块中。如果没有引用的常量,则链接性是外部的。

    全局名称空间是文件级声明区域。

    作用域解析符:: 可以限定名称。如pail为未限定名称,Jack::pail为限定名称。

 16.未命名的名称空间由于作用域仅在该文件中,因此链接性为内部,可以用来替代static,如下:

     static int counts;   //合法,但C++不建议、

     namespace 

    {

         int counts;   //合法,作用形同于上,C++建议

     }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值