码迷,mamicode.com
首页 > 其他好文 > 详细

指针和自由存储空间

时间:2015-05-17 10:44:25      阅读:544      评论:0      收藏:0      [点我收藏+]

标签:

  指针是一个变量,其存储的是值的地址,而不是值本身。

  对变量应用地址运算符(&),就可以获得它的位置。

  使用常规变量时,值是指定的量,而地址为派生量。下面来看看指针策略,它是C++内存管理编程理念的核心。


 

  指针与C++基本原理

  面向对象编程与传统的过程性编程的区别在于,OPP强调的是在运行阶段(而不是编译阶段)进行决策。运行阶段指的是程序正在运行时,编译阶段指的是编译器将程序组合起来时。

  运行阶段决策提供了灵活性,可以根据当时的情况进行调整。在运行阶段做决策并非OPP独有的,但使用C++编写这样的代码比使用C语言简单。


 

  处理存储数据的新策略刚好相反,将地址视为指定的量,而将值视为派生量。一种特殊类型的变量——指针用于存储值得地址。因此,指针名表示的是地址。*运算符被称为间接值或解除引用运算符,将其应用于指针,可以得到该地址处存储的值(这和乘法使用的符号相同;C++根据上下文来确定所指的是乘法还是解除引用)。例如,假设manly是一个指针,则manly表示的是一个地址,而*manly表示存储在该地址处的值。*manly与常规int变量等效。

 

声明和初始化指针

  指针声明必须指定指针指向的数据的类型。

int*P_updates

  这表示,*p_updates的类型为int。由于*运算符被用于指针,因此p_updates变量本身必须是指针。我们说p_updates指向int类型,我们还说p_updates的类型是指向int的指针,或int*。可以这样说,p_updates是指针(地址),而*p_updates是int,而不是指针。

int *ptr;//传统上,C程序员使用这种格式。这强调*ptr是一个int类型的值。
int* ptr;//很多C++程序员使用这种格式。这强调的是:int*是一种类型——指向int的指针。
/*下面的声明创建一个指针(p1)和一个int变量(p2)*/
int* p1,p2;
/*对每个指针变量名,都需要使用一个*
在C++中,int*是一种复合类型,是指向int的指针。
*/

   可以在声明语句中初始化指针。在这种情况下,被初始化的是指针,而不是它指向的值。也就是说,下面的语句将pt(而不是*pt)的值设置为&higgens:

int higgens=5;
int* pt=&higgens;

指针的危险

  极其重要的一点是:在C++创建指针时,计算机将反派用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。为数据提供空间是一个独立的步骤,忽略这一步无疑是自找麻烦,如下所示:

long* fellow;
*fellow=223323;

  fellow确实是一个指针,但它指向哪里呢?上述代码没有将地址赋给fellow。由于fellow没有被初始化,它可能有任何值。不管值是什么,程序都将它解释为存储223323的地址。如果fellow的值碰巧是1200,计算机将把数据放在地址,计算机将把数据放在地址1200上,即使这恰巧是程序代码的地址。fellow指向的地方很可能并不是所要存储223323的地方。这种错误可能会导致一些最隐匿、最难以跟踪的bug。

  一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。这是关于使用指针的金科玉律。

指针和数字

  不能简单地将整数赋给指针:

int* pt;
pt=0xB8000000;

  在这里,左边是指向int的指针,因此可以把它赋给地址,但右边是一个整数。您可能知道,0xB8000000是老式计算机系统中视频内存的组合段偏移地址,但这条语句并没有告诉程序,这个数字就是一个地址。在C99标准发布之前,C语言允许这样赋值。但C++在类型一致方面的要求更严格,编译器将显示一条错误信息,通告类型不匹配。要将数字值作为地址来使用,应通过强制类型转换将数字转换为适当的地址类型:

int* pt;
pt=(int*)0xB8000000;

  使用new来分配内存

 

/*use_new.cpp*/
#include<iostream>
int main()
{
    using namespace std;
    int nights = 1001;
    /*使用new为int类型的数据对象分配内存。这是在程序运行时进行的。
    有了指针,就可以像使用变量那样使用*pt。将值赋给*pt,从而将这些值赋给新的数据对象。
    new分配的内存块通常与常规变量声明分配的内存块不同。变量nights和pd的值都储存在被称为栈(stack)的内存区域中,而new从被称为堆(heap)或自由存储区(free store)的内存区域分配内存*/
    int* pt = new int;
    *pt = 1001;

    cout << "nights 的值=";
    cout << nights << ":地址" << &nights << endl;
    cout << "整型";
    cout << "值=" << *pt << ":地址=" << pt << endl;
    double*pd = new double;
    *pd = 10000001.1;

    cout << "浮点型";
    cout << "值=" << *pd << ":地址=" << pd << endl;
    cout << "指针pd的地址:" << &pd << endl;
    cout << "pt的大小=" << sizeof(pt);
    cout << "*pt的大小=" << sizeof(*pt) << endl;
    cout << "pd的大小=" << sizeof pd;
    cout << ":*pd的大小=" << sizeof(*pd) << endl;
    cin.get();
    cin.get();
    return 0;
}

 

使用new来创建动态数组

/*arranew.cpp*/
#include<iostream>
int main()
{
    using namespace std;
    /*为数组分配内存的通用格式:type_name* pointer_name=new name[num_elements];*/
    double* p3 = new double[3];
    p3[0] = 0.2;
    p3[1] = 0.5;
    p3[2] = 0.8;
    cout << "p3[1] is" << p3[1] << ".\n";
    /*不能修改数组名的值。但指针是变量,因此可以修改它的值。
    p3加1导致它指向第2个元素而不是第1个*/
    p3 = p3 + 1;
    cout << "Now p3[0] is" << p3[0] << "and";
    cout << "p3[1] is" << p3[1] << ".\n";
    /*p3减1后,指针将指向原来的值,这样程序便可以给delete[]提供正确的地址。*/
    p3 = p3 - 1;
    /*方括号告诉程序,应释放整个数组,而不仅仅是指针指向的元素*/
    delete[]p3;

    cin.get();
    cin.get();
    return 0;
}

输出

p3[1] is 0.5.
Now p3[0] is 0.5 and p3[1] is 0.8.

 

指针和自由存储空间

标签:

原文地址:http://www.cnblogs.com/cuiyuan1996/p/4496799.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!