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

来源:互联网 发布:运行python 批处理 编辑:程序博客网 时间:2024/03/29 14:41

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运算符,需要包含头文件newusing 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;}
运行结果:







0 0
原创粉丝点击