指针复习

来源:互联网 发布:java js跨域请求 编辑:程序博客网 时间:2024/06/05 21:10

1.指针和自由存储空间

计算机程序存储数据时必须跟踪3种基本属性:
1. 信息存储在何处
2. 存储的值是多少
3. 存储的信息是什么类型

另一种策略是:以指针为基础,指针是一个变量,其存储的是值的地址,而不是值本身。

指针与C++基本原理
面向对象编程与传统的过程性编程的区别在于,OOP强调的是在运行阶段(而不是编译阶段)进行决策。运行阶段决策就好比度假时,选择参观哪些景点取决于天气和当时的心情;而编译阶段决策更像不管什么条件下,都坚持预先设定的日程安排。

例如对于数组,编译阶段决策就需要在编译阶段就确定数组的长度,所以我们需要为数组创建尽可能长的长度,而大多数时候,这个长度都是用不完的,会造成内存的浪费。而运行阶段决策就会解决这一问题,在运行阶段根据此时数组需要的长度来决定内存的大小。

关于如何在运行阶段决定数组的长度,C++采用的方法是,使用关键字new来请求正确数量的内存以及使用指针来跟踪新分配的内存的位置。

#include <iostream>int main(){    using namespace std;    int updates = 6;    int *p_updates;    p_updates = &updates;    cout << "Values: updates = " << updates;    cout << ", *p_updates = " << *p_updates << endl;    cout << "Addresses : &updates = " << &updates;    cout << ", p_updates = " << p_updates << endl;    //use pointer to change value    *p_updates = *p_updates + 1;    cout << "Now updates = " << updates << endl;    return 0;}

输出为:

Values: updates = 6, *p_updates = 6Addresses : &updates = 0x28ff08, p_updates = 0x28ff08Now updates = 7Process returned 0 (0x0)   execution time : 0.343 sPress any key to continue.

1.1声明和初始化指针

声明

指针声明必须指定指针指向的数据的类型。因为不同的数据类型所占用的存储空间不一样。

例如下面的两种声明方式:
int *ptr;
将*放在了ptr的前面,强调的是*ptr是一个int类型的值

int* ptr;
将*放在了int的后面,强调的是int*是一种类型,是指向int的指针

但是:
int* p1, p2;
将创建一个指针(p1)和一个常规int变量(p2)。对每个指针变量名,都需要使用一个*

对于指向不同数据类型的指针,他们的长度是一样的,一般为2个或者4个字节,取决于计算机系统。

初始化

可以在声明语句中初始化指针。在这种情况下,被初始化的是指针,而不是它指向的值。即:

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

将pt(而不是*pt)的值设置为&higgens

也就是说上面的代码和下面的是等效的:

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

看下面这个例子:

#include <iostream>int main(){    using namespace std;    int i = 6;    int *p_i = &i;    cout << i << endl;    cout << &i << endl;    cout << p_i << endl;    cout << *p_i << endl;    int j = 9;    *p_i = j;    cout << i << endl;    cout << &i << endl;    cout << p_i << endl;    cout << *p_i << endl;    cout << &p_i << endl;    int k = 12;    p_i = &k;    cout << i << endl;    cout << &i << endl;    cout << p_i << endl;    cout << *p_i << endl;    cout << &p_i << endl;    return 0;}

运行结果是:

60x28ff080x28ff0860x28ff0490x28ff080x28ff0890x28ff0490x28ff080x28ff00120x28ff04Process returned 0 (0x0)   execution time : 0.201 sPress any key to continue.

1.2 指针的危险

在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。
一定要在对指针应用解除引用操作符(*)之前,将指针初始化为一个确定的,适当的地址,这是关于使用指针的金科玉律。

例如:

long *fellow;*fellow = 223333;

这里,fellow是一个指针,但是计算机只为它分配了存储fellow值的内存,没有分配存储fellow所指向的数据即(*fellow)的内存。那么*fellow = 223333将被存储在哪里呢?我们不知道。由于fellow没有初始化,它可能有任何值。不管只是什么,程序都将它解释为存储223333的地址,如果fellow的值恰巧为1200,计算机将把数据存放在223333地址上,即使这恰巧是程序代码的地址。没有初始化的指针所指向的地址很可能并不是所要存储值的地方,这种错误可能会导致一些最隐匿,最难以跟踪的bug。

1.3 指针和数字

指针不是整数。
整数可以执行加减乘除的运算,而指针描述的是位置,将两个地址相乘没有任何意义。因此,不能简单地将整数赋值给指针。

例如:

int *pt;pt = 0xB8000000;

这是错误的,正确方法是先将整数进行强制类型转换,然后再赋值给指针。如下:

int *pt;pt = (int*)0xB8000000; //将0XB8000000强制类型转换为指向int的指针

1.4 使用new来分配内存

接下来分析指针如何实现重要的OOP技术——在程序运行时分配内存。

1.5 使用delete来释放内存

原创粉丝点击