C++指针

来源:互联网 发布:淘宝well运动怎么样 编辑:程序博客网 时间:2024/06/11 15:53

1、什么是指针: 

指针就是用来保存内存地址的变量。


2、指针的地址和指针保存的地址

指针的地址是指针本身在内存中的位置,该地址中可以保存另一个变量的地址,即指针保存的地址。
int main(){int a = 100;int *p = &a;//&a和p拥有相同地址,p保存的变量地址即是&acout<<"a的地址:"<<&a<<endl;cout<<"p所保存的地址:"<<p<<endl;//指针p自身的地址cout<<"p自身的地址:"<<&p<<endl;//指针p中保存的地址的值,在p前面加“*”进行解引用操作,即可获得它所指针地址的值cout<<"p保存的地址的值:"<<*p<<endl;//通过对指针p自身地址解引用,获得它所保存的地址cout<<"p保存的地址的值:"<<*&p<<endl;//同上,得到 保存的地址后,再解引用,就可以获得保存地址里面的实际数据cout<<"p保存的地址的值:"<<**&p<<endl;return 0;}


3、指针修改它所指向的内存中的数据
指针通过解引用*运算符访问并读取内存地址中的数据,并可以对数据进行修改。

int main(){int a = 100;int *p = &a;//a的值也会随之而变,因为*p和a占用引用的是同一块物理地址*p = 200;cout<<a<<endl;//--->200cout<<*p<<endl;//--->200//*p的值也会随之而变,理由同上a = 300;cout<<a<<endl;//--->300cout<<*p<<endl;//--->300return 0;}


4、修改指针保存的地址
允许将一个变量的地址赋给一个已经保存了其它地址的指针变量
int main(){int a = 100;int b = 200;//现在指针p中保存的是变量a的地址int *p = &a;cout<<"a的地址:"<<&a<<endl;//---> a = 100cout<<"p所保存的地址:"<<p<<endl;//---> *p = 100//现在指针p中保存的是变量b的地址p = &b;cout<<"b的地址:"<<&b<<endl;//---> b = 200cout<<"p所保存的地址:"<<p<<endl;//---> *p = 200return 0;}


5、对象在堆与栈中的不同
(1)堆中的对象:通过new关键字动态开辟的存储空间,生命周期和整个程序运行周期相同,需要手动delete释放
class MyClass{public:MyClass(){cout<<"执行构造函数"<<endl;}~MyClass(){cout<<"执行析构函数"<<endl;}};int main(){MyClass *p = new MyClass();delete p;//手动释放,否则p声明周期会一直持续到程序结束return 0;}
(2)栈上的对象:程序执行到对象所以有效区域的右大括号时被销毁,栈的生命周期随着它所在函数的执行完毕而结束

class MyClass{public:MyClass(){cout<<"执行构造函数"<<endl;}~MyClass(){cout<<"执行析构函数"<<endl;}};int main(){MyClass m;return 0;}//在这里销毁了对象m

6、delete指针后,为其赋一个NULL值,以免发生难以调试的错误
int main(){int *p = new int;*p = 100;//虽然delete了,但也只是说明这块空间现在谁都可以用了,不再被p独占,但是并没有对上面保存的地址进行任何修改delete p;//对p上的空间置空,否则p会变成野指针//p = NULL;//紧接着分配另一块内存空间,这块空间有可能就是编译器刚刚收回的p指针所保存的地址int *p1 = new int;*p1 = 200;//因为p没有被置空,所以还可以继续使用,上面还存在以前分配的空间地址//且p1也指向这块空间,所以对p的操作,会影响p1的结果*p = 300;//p1现在将会是p修改的值cout<<*p1<<endl;return 0;}

7、指针的运算
(1)自加自减:将当前的内存地址前后偏移N个字节(字节大小由指针指向的数据类型的大小决定)
int main(){int *p = new int;//sizeof(int) = 4bit++p;//向后移动4个字节--p;//向前移动4个字节p += 2;//向后移8个字节p -= 2;//向前移8个字节return 0;}
(2)指针的赋值运算
int main(){int *p = new int;int *p1 = new int;p = p1;//p现在保存的是p1所存储的内存地址,但是p本身的地址并不会改变return 0;}
(3)指针相减:计算出地址差(结果×数据类型大小=字节数)
注:两个指针不能做相加操作
int main(){int *p1 = new int;int *p2 = new int;cout<<p2<<endl;int a = p1 -p2;//计算两块内存之间的地址差p1 += a;//将p1的内存单元地址加上地址差a,就等于p2的内存地址了cout<<p1<<endl;return 0;}
(4)指针的比较运算
int main(){int *p1 = new int;int *p2 = new int;if (p1 > p2){cout<<"p1 bigger"<<endl;}else{cout<<"p2 bigger"<<endl;}return 0;}

8、带const修饰符的指针
(1)常量指针:指针是常量,不能修改;它所指向的内容是非常量,可以修改
class MyClass{public:MyClass(){cout<<this<<endl;}~MyClass(){}public:void set(int n){m_nVal = n;}private:int m_nVal;};int main(){//常量指针:指向的地址不能修改,指向的内容可以修改MyClass *const p = new MyClass;//指针存储的地址不能修改//p++;//指针指向的内容可以修改p->set(1);return 0;}
(2)指向常量的指针:指针指向的内容是常量,不能修改;指针所存储的内存地址可以修改
int main(){//指向常量的指针:指向的地址可以修改,指向的内容不能修改MyClass const* p = new MyClass;//const MyClass * p = new MyClass;//指针存储的地址可以修改p++;//指向的内容不可以修改//p->set(1);return 0;}
(3)指向常量的常指针:指针存储的地址和所指向的内容都不能修改
int main(){//指向常量的指针:指向的地址可以修改,指向的内容不能修改//const MyClass *const p = new MyClass; MyClass const*const p = new MyClass;//指针存储的地址可以修改//p++;//指向的内容不可以修改//p->set(1);return 0;}

原创粉丝点击