C++的存储持续性(自动、静态、动态),作用域,链接性

1.c++使用三种不同的方案进行数据的存储,这些方案的区别就在于数据保留在内存中的

   时间

●自动存储持续性:

在函数定义中声明的变量(包括函数参数)的存储持续性为自动类型。

     ☉作用域:局部,在包含定义它的函数内部有效。

     ☉链接性:没有链接性,只能在定义它的函数内部使用,不能在其他函数中使用。

     ☉内存对自动类型变量的管理:常用的方法是留出一段内存,并将其视为栈,以管理             变量的增减。

●静态存储持续性:

在函数定义外定义的变量和使用static关键字定义的变量为静态类型。

     ☉链接性:

         ▼外部链接性:变量定义在函数定义之外,并且没有用static修饰。

             作用域:整个程序,可以在各个文件中使用该变量。

         ▼内部链接性:变量定义在函数定义之外,但是用static修饰。

             作用域:在包含这个变量定义的文件的函数中可用。但在其他文件的函数中不可                               用

         ▼无链接性:变量定义在函数定义之内,用static休息,与auto的差别在于static修                 饰的变量一直存在在内存中,而auto类型的变量使用完后就在内存中销毁了。

             作用域:只在变量定义的函数体内有效。

     ☉内存对静态存储类型变量的管理:由于静态变量的数目在程序运行期间是不变的,            因此编译器将分配固定的内存单元来存储所有的静态变量,这些变量在整个程序执            行期间一直存在。

●动态存储持续性:

使用new分配的内存将一直存在,直到使用delete将其释放或函数结束。


2.auto变量,静态变量举例:

文件结构:


file1.cpp源代码:

#include <iostream>
using namespace std;

int error = 3;   //外部变量,在file1.cpp和file2.cpp中都可以使用
static int count = 9;  //静态变量,在file1中可以使用,在file2中不能使用

int myFun();
int Fun();

int main()
{
    int num = 5;   //auto类型变量,仅在main函数中能够使用,无链接性
    cout << count << endl; //可以使用
    cout << num << endl;
    return 0;
}

int Fun()
{
    cout << count << endl;  //可以使用count,因为count有内部链接性
    cout << error << endl;  //可以使用
    //cout << num << endl;  //不能使用,因为num是在main中定义,无链接性
    return 0;
}
file2.cpp源代码:

#include <iostream>
using namespace std;

extern int error;
//extern static int count;   //不能用,因为count是file1.cpp中定义的只具有内部链接性的变量,只能在file1.cpp中使用,不具有外部链接性

int myFun()
{
    cout << error << endl;
    return 0;
}

3.mutable的使用

作用:可以用它来指出,即使结构体(或类)变量为const,用mutable关键字修饰的变量的              值也是可以改变的。

举例:

struct data
{
    char name[30];
    mutable int level;
};

const data veep = {"zhangfei", 1};
veep.level++;  //这句是有效的,虽然veep被定义为const,但是level成员前有mutable修饰,所以可以修改

4.在c++中,被const修饰的全局变量的链接性为内部链接

如:

const int fingers = 10;
int main()
{
   ...
}
fingers这个变量只能在该文件中使用,不能在该项目的其他文件中使用。


5.函数和链接性:

    ●所有函数都是静态的,即整个程序的执行期间一直存在

    ●在默认情况下,函数的链接性为外部链接,即可以在文件间共享

    ●可以使用关键字static将函数的链接性设置为内部链接,即只能在一个文件中使用,在        函数声明和函数定以前都要加上static

static int private(double x);
...
static int private(double x)
{
  ...
}

   ●单定义规则也适用于非内联函数,内联函数不接受这条规则的约束,这允许程序员能        够将内联函数的定义放在头文件中

6.定位new运算符

  通常,new运算符负责在堆中找到一个足以能够满足要求的内存块。new运算符还有另外一种变体,能够指定要使用的位置,被称为定位new运算符。要使用定位new运算符,需要包含头文件new。需要注意的是,delete只能用于删除指向常规new运算符分配的堆内存。

常规new运算符和定位new运算符举例:

#include <iostream>
#include <new>          //要使用定位new运算符,需要包含头文件new
using namespace std;

const int N = 5;
const int BUF = 512;
int buffer[BUF];

int main()
{
    int *pi1, *pi2, *pi3, *pi4;
    pi1 = new int[BUF];           //pi1在内存中找一块能使用的内存,位置不定
    pi2 = new (buffer) int[BUF];  //pi2使用定位new,所分的内存是从buffer开始
    cout << "Calling new and placement new:\n";
    cout << "Memory addresses:\n";
    cout << "  heap: " << pi1 << "  static: " << pi2 << endl;
    cout << "Memory contents:\n";
    for(int i = 0; i < N; i++)
        pi1[i] = pi2[i] = 1000 + 20 * i;
    for(int i = 0; i < N; i++)
    {
        cout << pi1[i] << " at " << &pi1[i] << "  ";
        cout << pi2[i] << " at " << &pi2[i] << endl;
    }

    cout << endl;
    cout << "Calling new and placement new a second time:\n";
    cout << "Memory contents:\n";
    pi3 = new int[BUF];           //pi3在内存中找一块能使用的内存,位置不定
    pi4 = new (buffer) int[BUF]; //pi4使用定位new,所分的内存是从buffer开始,所以pi4显示的地址跟pi2一致
    for(int i = 0; i < N; i++)
        pi3[i] = pi4[i] = 1000+ 40 * i;
    for(int i = 0; i < N; i++)
    {
        cout << pi3[i] << " at " << &pi3[i] << "  ";
        cout << pi4[i] << " at " << &pi4[i] << endl;
    }

    delete [] pi1;
    delete [] pi3;         //释放常规new分配的内存,定位new分配的内存不能使用delete
    return 0;
}
运行结果:







  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值