指针可以为空,可以改变指向的对象,可以在任何时候被初始化
指针可能传空值,需要进行NULL判断
地址
变量的地址用&获取:
int var1;
cout << &var1 << endl; //0xbfebd5c0
指针
指针是一种变量,这个变量的值是另外一个变量的地址。
int a = 2;
int *p; //p是指针,*p表示int类型的变量
p = &a; //p的值为变量a的地址。
NULL指针
- 声明指针时没有合适的地址可以赋值,就先 *p = NULL;
- NULL的地址为0;
- NULL也为0;
int *p4 = NULL;
printf("%d",*p4); //运行Error,使用指针时必须先判断是否空指针
数组和指针
数组a[n]的变量名a是此数组第一个元素a[0]的指针:
int a[3] = {100, 200, 300};
cout << *a << endl; //100
int height[10]; //int型的数组(short int 每个数据2字节)
cout << "height "<< height << endl
<< "height+1 "<< height + 1 << endl
<< "&height[0] " << &height[0] << endl
<< "&height+1 "<< &height + 1<< endl
<< "height+9 "<< height+9 << endl
<< "height+10 " << height + 10 << endl;
输出:
height 0x72fdd0 //第一个元素地址
height+1 0x72fdd4
&height[0] 0x72fdd0
&height+1 0x72fdf8 //数组结束之后第一个地址,等价于height+10
height+9 0x72fdf4 //数组最后一个元素地址
height+10 0x72fdf8 //数组结束之后第一个地址
指针的算术运算
- 既然指针表示地址,那么指针就可以++、--、+、-。
- int型指针++,实际地址+4;
- char型指针--,实际地址-1;
我们喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,因为数组是一个常量指针。
int a[3] = {100, 200, 300};
cout << *(a+1) << endl; //200, 不能直接 *(a++),因为a是一个指针常量,不能变化
int *b;b = a;b++;
cout << *b << endl; //200
注意1!!!!:
不能简单认为*p代表p所指地址代表的对象,*只是声明p是个指针,没有任何作用的。下面三个指针完全等价:
int height = 1;
int *p1;p1 = &height;
int *p2 = &height; //int *p2 = height是非法的,因为*p2代表声明p2是指针;
//*p2 = &height也是非法的,此时*p2代表p2所指的变量,不能赋值为地址。
int *p3 = p2; // p1 == p2 == p3
注意2!!!!!:常量指针与指针常量
- 常量指针【int const *p】,指向的值是常量,不能改变指针指向的内容,但是指针可以改变
(就是*p不能再赋值,但是p可以再赋值)
- 指针常量【int *const p】:指针自己是常量,可以改变指针指向的内容,但是指针不能改变
(就是*p可以再赋值,但是p不能再赋值)
int const *p1 = &b; //定义为常量指针,p1可以变,但是*p1不能变(或const int*p1)
int *const p2 = &c; //定义为指针常量,p2不能变,但是*p2可以变
//当然也可以p和*p都不能变:
int const* const p = &a; //或 const int* const p = &a;
注意3!!!!!!:野指针
delete掉指针后,没有置0,导致指针随意指向了一个内存地址,如果继续使用,会造成不可预知的内存错误。
//-------野指针(悬浮、迷途指针)-------//
int *p5 = new int(5);
delete p5;
p5 = NULL; //一定要有这一步,或者p5 = 0;
注意4:指针的内存泄漏
int *p6 = new int(6);
p6 = new int(7); //p6原本指向的那块内存尚未释放,结果p6又指向了别处,
//原来new的内存无法访问,也无法delete了,造成memory leak