C++入门(2)——指针和自由存储空间

地址

计算机程序在存储数据时必须跟踪以下3个属性

  • 信息存储在何处
  • 存储的值为多少
  • 存储的信息是什么类型
    之前我们使用过另一种策略来达到上述目的:定义一个简单变量,声明语句指出了值的类型和符号名,还让程序为值分配内存,并在内部跟踪该内存单元
    下面来看另一种策略,它在开发C++类时非常重要。这种策略以指针为基础,指针是一个变量,其存储的是值的地址,而不是值本身。在讨论指针之前,我们先看一看如何找到常规变量的地址。只需要对变量应用地址运算符&, 就可以获得它的位置
    #include <iostream>
    int main()
    {
        using namespace std;
        int a = 6;
        double b = 4.5;
        cout << "a value = " << a;
        cout << " and a address is " << &a << endl;
         cout << "b value = " << b;
        cout << " and b address is " << &b << endl;
        return 0;
    }

输出如下,显示地址时,该实现的cout使用十六进制法,因为这时常用于描述内存的表示法。

a value = 6 and a address is 0x7ffedf68996c
b value = 4.5 and b address is 0x7ffedf689970

指针与C++基本原理

面向对象(OOP)与传统过程性编程的区别在于,OOP强调的是在运行阶段决策,这样更灵活。如在C++中声明数组,必须指定数组长度,这就是编译阶段决策。而下文就就会提到,C++通过OOP使用关键字new请求正确数量正确的内存以及使用指针表来跟踪新分配的内存的位置。

    #include <iostream>
    int main()
    {
        using namespace std;
        int updates = 6;    // declare a variable
        int * p_updates;   // declare pointer to an int
        p_updates = &updates; // assign address of int to pointer
    //express values two ways
        cout << "Values: updates = " << updates;
        cout << ", *p_updates = " << *p_updates << endl;
    //express values two ways
        cout << "Addresses: &upadates = " << &updates;
        cout << ", p_updates = " << updates << endl;
    //use pointer to change value
        *p_updates = *p_updates + 1;
        cout << "Now updates = " << updates << endl;
        return 0;
    }

输出如下,从中可以知道int变量updates和指针变量p_updates 只不过是同一枚硬币的两面。变量updates表示值,并使用& 运算符来获得地址: 而变量p_updates表示地址,并使用*运算符来获得值。由于p_updates指向updates,因此*updates 和updates完全等价(译者注: 如果觉得这里有点绕,先把指针当作语法糖,后面的文章会详细介绍)。

Values: updates = 6, *p_updates = 6
Addresses: &upadates = 0x7fffa344041c, p_updates = 6
Now updates = 7

声明和初始化指针

计算机需要跟踪指针指向的值的类型,因此在指针声明时必须指定指针指向的数据的类型,例如

   int *p_updates

需要注意的是,对每个指针变量名,都需要使用一个*

   int *p1, p2;

如果这样声明,就创建一个指针p1和一个int变量p2。(译者注:p1前面的int,不代表p1是一个int。指针和数组一样,都是基于其他类型的)
可以在声明语句中初始化指针

    #include <iostream>
    int main()
    {
        using namespace std;
        int a = 5;
        int *pointer = &a;
        cout << a
            <<"; address = "<< &a << endl;
        cout << *pointer
            <<"; value of pointer = "<< pointer << endl;
        return 0;
    }

输出如下

    5; address = 0x7ffccfb23a2c
    5; value of pointer = 0x7ffccfb23a2c

可以看出,程序将pointer 初始化为变量a的地址。注意: 在不同的系统上,显示的地址可能不同,显示格式也可能不同,这里仅供参考。

指针的危险

在C++中创建指针时,计算即将分配用来存储地址的内存,但不会分配用来储存指针所指向的数据的内存。

   long * fellow;  // create a pointer to long
   *fellow = 233333;

fellow确实是一个指针,但上述代码没有将地址赋值给fellow,那么233333将被放在哪里呢?我们不知道,由于fellow没有被初始化,它可能有任何值。不管值是什么,程序都将它解释为存储233333的地址,如果fellow的值碰巧为1200,计算机将把数据放在地址1200上,即使这恰巧是程序代码的地址。这种错误可能导致一些最隐匿的错误

IT文库 » C++入门(2)——指针和自由存储空间
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址