指针的用法概述
1.什么是指针
简单地说,指针就是指向内存中某个位置的地址。
2.指针的定义
定义格式:数据类型 *指针名;//指针名=&变量名
示例1:int *p; //指向整型数据的指针
char *pchar;//指向字符型数据的指针
3.指针的优点
①可以提高程序的编译效率和执行速度,使程序更加简洁。
②指针可以作为函数的参数进行值传递,返回更多的数据。
③利用指针可以实现C和C++动态内存分配。
④利用指针可以直接操纵内存地址。
⑤表示和实现各种复杂的数据结构。
4.赋值与转换
①同类型直接赋值,异类型需要转换。
②强制转换可以把表达式类型直接转换为指定类型(大转小时可能会有数据丢失,如int型转为double型)。
③void型指针可赋值给任何类型的指针。
5.指针与数组
不带下标的数组名返回数组的起始地址,即数组首元素的地址,因此可以通过指针访问数组元素。
示例2:
int *p1=new int;
int *p2;
int a;
p2=&a;
cout<<p1<<" "<<*p1<<endl;
cout<<p2<<" "<<*p2<<endl;
6.指针与引用
①引用是一个变量的另一个名字。
②只能对已经存在的对象和变量实现引用。
③引用直接访问变量,不用分配自己的内存空间。
7.指针使用常见错误
1)指针未初始化
指针的初始化,不是指指针的定义,而是指针变量存储的数值是个无效数值。
比如定义float a;这个a会分配一个地址,但初始值是一个乱七八糟的数据。 同样,float *a;也会为a分配一个地址,初始值也是乱七八糟的数据。
初始化可以将a = NULL,这样在以后的程序中可以增加if(a = = NULL)来判断指针是否有效,否则不行。
或者为指针分配或者指定空间:float *a = new float;或者float b; float *a = &b;都可以为指针指向一块内存以实现初始化。
2)指针越界
数组(指针)越界访问,是指使用了超过有效范围的偏移量。
如只分配了10个元素的空间,但是访问了第11个元素,就属于越界。当出现越界时,由于无法得知被访问空间存储的内容及功能,所以会出现不可预知后果。可能程序崩溃,可能运算结果非预期,也可能完全没有影响。
在编程时要避免指针越界访问,对于用变量作为参数访问元素时,需要控制好变量范围。如果变量值由外部因素决定,那么访问前先对合法性做判断,防止越界。
3)指向局部变量指针
数组指针是记录某块内存起始地址的变量,要使指针有效,则必须确保这块内存有效。
用new分配的内存空间,只要不delete,则一直有效。但是对于指向某个变量地址的指针,程序员必须清楚该变量的作用域。如果离开了变量的作用域,该变量的内存空间就会被系统自动回收,再使用指针时,将会发生错误。这是程序中最容易出现的错误。
4)指针指向的转移(野指针)
示例4:
char *pChar = new char;
char *pChar;
char chs;
pChar = &chs;
delete pChar;
程序目的是将chs内容传递给pChar指针指向的内存。但这样写将会使pChar先前指向的空间变成垃圾地址(因为先前的地址无法再获取),从而导致内存泄漏。另外,在调用delete pChar时也会出现异常错误(不是new的空间不能使用delete删除!),因为pChar已经转到指向chs这个变量的地址了。