指针

来源:互联网 发布:node.js 构建工具 编辑:程序博客网 时间:2024/06/07 05:27

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

    运行阶段决策提供了灵活性,可以根据当时的情况进行调整。例如,考虑为数值分配内存的情况。传统的方法是声明一个数组。要在C++中声明数值,必须指定数值的长度。因此,数值长度在程序编译时就设定好了;这就是编译阶段决策。OOP通过将这样的决策推迟到运行阶段进行,使程序更灵活。在程序运行后,可以这次告诉它需要多少元素。

    总之,使用OOP时,您可能在运行阶段确定数组的长度。为使用这种方法,语言必须允许在程序运行时创建数组。C++采用的方法是,使用关键字new请求正确数量的内存以及使用指针来跟踪新分配的内存的位置。

    

1 声明和初始化指针

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

例如,int *p_updates;

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

2 指针的危险

及其重要的一点是:在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。

注意:一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。

3 指针和数字

指针不是整型,虽然计算机通常把地址当做整数来处理。从概念上看,指针和整数是截然不同的类型。整数可以执行加减乘除运算的数字,而指针描述的是位置,将两个地址相乘没有意义。从可以操作上看,它们是彼此不同的。因此,不能简单地将整数赋给指针:

int *ptr;

ptr=oxB80000000 (错误的)

要将数字值作为地址来使用,应通过强制类型转换将数字转换为适当的地址类型:

int *ptr;

pt=(int*)oxB80000000

4 使用new类分配内存

在前面我们将指针初始化为变量的地址;变量是在编译时分配的有名称的内存,而指针只是为可以通过名称直接访问的内存提供了一个别名。指针正在的用武之地在于,在运行阶段分配未命名的内存以存储值。在这种情况下,只能通过指针来访问内存。在C语言中,可以用库函数malloc()来分配内存;在C++中仍然可以这样做,但C++还有更好的办法——new运算符。

为一个数据对象(可以是结构,也可以是基本类型)获得并指定分配内存的通用格式如下:

typename *pointer_name=new typename;

需要在两个地方指定数据类型;用来指定需要什么样的内存和用来声明合适的指针。

对于指针,需要指出另外一点是,new分配的内存块通常与常规变量声明分配的内存块不同。变量都存储在被称为栈的内存区域中,而new从被称为堆或自由存储区的内存区域分配内存。


5 使用delete释放内存

当需要内存时,可以使用new来请求,这只是C++内存管理数据包中有魅力的一个方面。另一个方面是delete运算符,它使得在使用内存后,能够将其归还给内存池,这是通向最有效地使用内存的关键一步。归还或释放的内存可供程序的其他部分使用。

int *ps=new int;

delete ps;

这将释放ps指向的内存,但是不会删除指针ps本身,例如,可以讲ps重新指向另一个新分配的内存块。一定要配对地使用new和delete;否则将发生内存泄漏。

不要尝试释放已经释放的内存块,C++标志指出,这样做的结果将是不确定的,这意味着什么情况都可能发生。另外,不能使用delete来释放声明变量所获得的内存:

注意:只能使用delete来释放使用new分配的内存,然而,对空指针使用delete是安全的。

注意,使用delete的关键在于,将它用于new分配的内存,这并不意味着要使用用于new的指针,而是用于new的地址。

int *ps=new int;

int *pq=ps;

delete pq;

一般来说,不要创建两个指向同一个内存块的指针,因为这将增加错误地删除同一内存块两次的可能性。

6 使用new来创建动态数组

在编译时给数组分配内存被称为静态联编,意味着数组是在编译时加入到程序中。但使用new时,如果在运行阶段需要数组,则创建它;如果不需要,则不创建它。还可以在程序运行时选择数组的长度。这被称为动态联编,意味着数组是在程序运行时创建的。这种数组叫做动态数组。

使用new创建动态数组

int * psome=new int[10];

new返回第一个元素的地址。

delete释放

delete [] psome;


使用new和delete时,应遵循以下规则

    1 不要使用delete释放不是new分配的内存

2 不要使用delete释放同一个内存块两次

3 如果使用new[]为数组分配内存,则应使用delete[]来释放

  4 如果使用new[]为一个实体分配内存,则应使用delete(没有方括号)来释放

5 对空指针应用delete是安全的。



对于指针和数组名有以下两点区别:

1 可以修改指针的值,而数组名是常量;

2另一个区别是,对数组应用sizeof运算符得到的是数组的长度,而对指针应用sizeof得到的是指针的长度,即使指针指向的事一个数组。


一般来说,如果给cout提供一个指针,它将打印地址。但如果指针的类型为char*,则cout将显示指向字符串。如果要显示的是字符串的地址,则必须将这种指针强制转换为另一种指针类型,如int*。因此,如果ps是指向char*类型的指针,则ps显示的为里面所存放的字符串,而(int*)ps显示为该字符串的地址。

0 0
原创粉丝点击