内存模型

本文详细介绍了C++中存储持续性、作用域和链接性的概念,涵盖了自动、静态及动态存储的区别,以及如何通过关键字控制变量的行为。同时,文章探讨了函数的存储特性,并解释了语言链接性对函数调用的影响。

1.存储持续性:描述数据在内存中的保留时间

   自动存储持续性:

   静态存储持续性:

   动态存储持续性:

2.作用域:描述名称在翻译单元(文件)的可见范围

    声明区域 declaration region:可以在其中进行声明的区域。

    潜在作用域 potential scope:从声明点开始,到其声明区域的结尾。变量对程序而言可见的范围被称为作用域scope。

3.链接性:描述名称如何在不同翻译单元(文件)间共享。有3种值:文件外部,文件内部,无。

4..自动存储持续性变量:在函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性

   可以使用关键字auto来显示指出存储类别,它极少被使用,比如它可以表明程序中特意创建了一个自动变量,它将暂时覆盖全局定义。

   寄存器变量是另一种形式的自动变量。使用关键字register提醒编译器,用户希望它通过cpu寄存器,而不是堆栈来处理特定的变量,从而提供对变量的快速访问。

   如果变量被存储中寄存器中,则没有内存地址,不能将地址操作符用于寄存器变量。

   在编写for循环时,编译器可能自动使用寄存器来存储循环计数。

5.静态存储持续性变量

   由于静态变量的数目在运行期间是不变的,程序不需要使用特殊装置如堆栈来管理它们,将分配固定的内存块来所有静态变量。

   默认情况下,静态数组和结构每个元素或成员的所有位都设置为0。

   只能使用常量表达式来初始化静态变量,常量表达式包括:字面值常量,const常量,enum常量,sizeof操作符。

   传统的K&R C不允许初始化自动数组和结构,但允许初始化静态数组和结构

   在代码块外声明的变量链接性为外部;

   在代码块外声明的static变量链接性为内部;

   在代码块内声明的static变量没有链接性;

5.1.外部链接性变量,在函数外部定义,也称为全局变量,链接性为外部,持续性为静态,作用域为其所属的文件内外。

      自动变量将隐藏同名的外部变量。

     只能有一个文件中定义声明某个外部变量,其它文件中可以使用extern来引用声明其它文件中定义声明过的外部变量;在同一个文件中extern是可选的;不能在引用声明中初始化变量,初始化指的是在分配内存单元时给它赋值。

      例如:extern double warming;

      在c++中,使用作用域操作解析符(::)来显示指出操作的是全局变量。

5.2.内部链接性变量,若要常规外部变量前加了static限定符,则其变成内部变量,链接性为内部,持续性为静态,作用域为文件内。

      内部变量将隐藏同名的外部变量。

      c++标准指出:使用static来创建内部链接性的方法将逐步被淘汰,提供了另一种由名称空间来使用共享数据的方法。

      const全局变量链接性为内部的

      内部链接性还意味着,每个文件都有自己的一组常量,这就是能够将常量定义放在头文件中的原因。

      如果希望const全局变量链接性为外部,可以再加上extern关键字。如extern const int state=1;这与常规的定义声明不同多加了使用了extern,其它引用声明形式不变。

5.3.无链接性静态变量,作用域在代码块中的静态持续性变量,使用static限定符。

6.cv-限定符(cv-qualifier),cv表示const和volatile(不稳定的)

   volatile表明即使程序没有对内存单元修改,其值 也可能发生变化。

   mutable表明即使变量声明为const,其值也可以被修改。较少使用。

7.函数的存储持续性都是静态的,链接性为外部,即可以在文件间共享。

  可以在函数原型中用extern指出函数是在另一个文件中定义的,这是可选的。

   可以使用static将函数的链接性设置为内部的,要同时在函数原型和定义前使用static。

   单定义规则:对于非内联函数,程序中只能包含一个定义。同一个内联函数名的内联定义必须相同。

8.语言链接性:language linking。

   在c语言中,一个名称只对应一个函数,这是c语言链接性。

   在c++中,有同名函数的不同重载版本,c++编译器执行名称修饰,将这些重载函数翻译成不同的符号名称,这是c++语言链接性。

   链接程序寻找函数时,c++函数和c函数有不同的方式。可能c仅根据函数名,而c++要根据函数名和参数名。为解决这个问题,在函数原型前加上extern “C”,或extern “C++”

,来指出要使用的约定。例如 extern void spoff(int); 这样默认使用的是c++语言链接约定。

9.动态内存由操作符new和delete控制,不是由作用域和链接性控件。

   虽然存储方案并不适用于动态内存,但适用于用来跟踪动态内存的自动静态指针变量。

   使用new语句设置静态存储变量的代码必须在函数中,因为只能使用常量表达式来初始化静态存储变量。

   在程序结束时,由new分配的内存通常都将被释放,但在不很健壮的操作系统中,请求的大型内存块时可能不会被自动释放,最佳的做法时使用delete释放。

10.布局new操作符

11.名称空间 namespace

     名称空间可以嵌套,但不能位于代码块中,默认情况下,名称空间中声明的变量是外部链接性的,除非它引用了常量。

     全局名称空间:它对应于文件级声明区域。

     通过作用域 解析操作符::使用名称空间限定名称。名称空间结尾的大括号后面无分号

    

  

  

 

 

 

  

  

 

 

 

内存的分配方式:

 一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。 
 二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 
 三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值