c++中有一种特殊的变量,他叫指针,他存储着地址。说指针之前我们说说常规变量的地址怎么获得呢?我们可以用&运算符获得例如
int a=0;
int *p=&a;
注意两点一般常规变量存储的地址随系统而异,且地址一般都是十六进制表示的
定义指针
一般有两种写法定义指针
int *p
int* p
第一种写法表示*p(在定义之外用*是对指针的解析, *p是指 指针p中存储的地址指向的那个变量)指向的是int;
第二种是指p是一种 int*类型的变量(c++程序员一般喜欢这种,我也听别人说的)
其实上述两种表达都一样 ,只是你怎么理解罢了。不过有一点要说明就是
对每个指针变量名都需要一个*
int *p1,p2;//p1是一个指针,但是p2是int的变量
注意 指针是危险的
int *p;
*p=123;
上述代码中没有对p初始化,就直接给*p赋值,这样的后果是我们不知道123这个值被赋值到哪里了,如果是计算机系统的核心内存,一般都禁止写入,这样程序就崩溃了
初始化指针
有两种
int *p=(int*)0xB8000000//为什么要强制转换呢?因为不强制转换的话就是把数字赋值个指针,这样是错误的
int *=new int
第一种方法不安全 除非你知道 给予的地址在计算机中是干什么的,第二种是推荐做法,让计算机替我们找一个合理的地址
用delete释放内存
如果new出来的地址不会释放的话 ,他就一直存在在哪里,而一般的操作系统会在程序退出时释放程序申请的所有内存,那怎么自己释放呢?使用delete,delete后面加上new出来的那个指针例如
int *p=new int;
char *p1=new char[20];//new 初始化数组返回的是数组第一个元素地址所以赋值给char*
delete p;
delete []p1;
如上所述 删除不同的变量用 delete 而数组用delete []
注意亮点点 我们不能删除声明变量所属的内存,也不能重复删除,
int a=0;
int *p=&a;
delete p;//错误,不鞥删除不是通过new返回的指针,不能的原因是因为普通变量在栈中,但是是delete只能删除堆中的
delete p;;//错误,如果上一步是正确的话 这一步也是错误的,因为不能重复delete,c++标准说明了这样的结果是不确定的,没人知道会怎么样
还有删除时的类型不匹配,导致的后果是不确定的没人知道会怎么样,所以不要这样使用
int* p1=new int;
int*p2=new iint[10];
delete p2;
delete []p1;
指针,数组,指针运算
c++的数组是通过指针管理的,数组名解释为地址,是这个数组第一个元素的地址,而对数组名取地址是这个数组的地址
int a[]={0,1,2}
int *p1=a;
int *p2=&a;
cout<<p1<<p2;//p1,p2地址值是一样的 但是p1,p2是不一样的地址,p1是int* ,而p2是int(*)[]的
指针的运算符
只能加 上和减上一个者整数例如
int a[]={1,2,3};
int *p=a;
cout<<*(p++)<,endl;//输出是a[1].
指针的+1和-1,不是地址加+1和-1,而是加上1个 这个指针指向的数据类型的字节,说的有的拗口,简单说就是如果这个指针指向的数据是int的,又如果int 是4字节,那么指针加一的话地址就会加上4。(内存中1个字节是1个地址)
指针访问
和指针有关的访问就三个 一个是 * 一个 . 是.一个是 -> 这三个符号其实很简单
第一个 就是普通的的取地址 *p就是取p指向的那个值
第二个 就是如果有一个结构体或者类A 有一个成员a , 就A.a
第三个就是如果有一个结构体或者类但是你不知名字值知道指针p, 有一个成员a 这是你就可以p->a
最后告诉你们就是p->a等于(*P).a
const和指针
const的修饰的指针表示不可以通过指针修改变量 而变量本身在非const的情况下是可以修改的
上图简单总结了一下 其实非const的指针在强制转换下时刻以指向const 的变量的(const_cast来强制转换)
还有一种很有趣的事
const int const *p;//这修饰了一个指针 这个指针是const的 它指向的是一个int 这个int也不可以通过这个指针来修改
函数指针
函数名就是函数的地址
a1(b);//a1函数形参是b函数的地址
a2(b());//a2的形参是b函数的返回值
声明函数指针
int a(int);
int (*p)(int);一定要加括号不然就int *(p(int)),意味着pf()是一个返回指针的函数
使用指针调用函数
p()//一种学派认为指向函数的指针应该和函数名相似,
(*p)();//另一种学派认为因为p是函数指针所以*p是函数
c++这种了这两种方法都可以