C++指针汇总

来源:互联网 发布:枪林弹雨刷枪软件视频 编辑:程序博客网 时间:2024/06/06 20:09

首先非常感谢ggjucheng的指针概念解读。

很多人接触C++的指针,第一感觉就是头大,感觉很容易被这玩意儿绕晕了,C++相比较其他语言,指针确实是一大难点,其涉及到的动态内存分配与手动释放等常常带来很大的困扰,尽管后来智能指针的出现有效缓解了这个问题。今天小编这里给大家详细讲一下有关指针的内容,更多详细的内容请参考指针的概念解读。首先,必须明确的是指针的概念:指针是一个特殊的变量,所以它同样需要内存中开辟一定的空间,指针作为变量辣么必须要有值的,指针的值是内存里的一个地址。要搞懂指针必须要弄清楚指针的类型、指针所指向的类型、指针所指向的内存以及指针本身所占的内存,更多的关于指针使用方面的注意事项也需要留意:如指针的初始化、指针的释放以及野指针错误等。

一、指针举例

先看一些常见的指针:
int * p;               <span style="color:#006600;">//整形指针</span>int ** p;              <span style="color:#006600;">//指针的指针</span>char * p;             <span style="color:#006600;"> //字符指针</span>int (*p) [5];          <span style="color:#006600;">//数组指针</span>int* (*p)[5];         <span style="color:#009900;"> </span><span style="color:#006600;">//指针数组</span>const char * p;        <span style="color:#006600;">//常量指针</span>char * const p;       <span style="color:#006600;"> //指针常量</span>const char* const p;   <span style="color:#006600;">//常量指针常量</span>
不知道上面的指针大家都认识否?或许没有注释一眼看上去肯定蒙了?那么我们就把各个指针进行分解,请看下面的内容。

二、指针的类型

怎么获取指针的类型呢?最简单的辨认方法:把指针声明语句里面指针变量名去掉,剩下的那一部分就是指针的类型
int * p;               //指针的类型是int*int ** p;              //指针的类型是int**char * p;              //指针的类型是char*int (*p) [5];          //指针的类型是int(*)[]int* (*p)[5];          //指针的类型是int*(*)[]const char * p;        //常量指针的指针类型是const char *char * const p;        //指针常量的指针类型是char* const char* const p;   

三、指针所指向的类型

得到指针的类型就是辣么简单,想知道指针所指向的类型也很简单,只需要把指针声明语句里的指针名称以及前面的*去掉就可以了,剩下的内容就是指针所指向的类型。
int * p;               //指向intint ** p;              //指向int*char * p;              //指向charint (*p) [5];          //指向int[]int* (*p)[5];          //指向int*[]const char * p;        //指向const char;char * const p;        //指向charconst char* const p;   //指向const char;

四、指针所占的内存

指针所占的内存区与指针本身 类型密切相关,sizeof(指针的类型)就可以知道指针所占的内存了。

五、指针所指向的内存

指针所指向的内存与指针所指向的类型密切相关,sizeof(指针所指向的类型)就可以知道目标占用的内存了

六、指针的值

指针的值表示一段内存的地址,用来指向存在那片内存区域的数据,在32位的程序里,所有类型的指针的值都是一个32位的整数。还需要注意一点,指针的值表示的是内存的首地址,而具体的内存大小则是指针所指向的类型来确定的。
指针所指向的内存区域和指针所指向的类型是不一样的,这是声明和初始化的区别,初始化意味着内存区域的分配。

七、指针运算

关于指针的运算,可以先看一个例子:
int a[20] ;int* p = a;p++;(*p)++;
在声明数组的时候,int类型的数组被默认初始化为0,当我们声明一个指向int类型的指针p时,由于a是数组名,代表内存中分配数组存储单元的其实地址,所以可以赋给p,当p指向数组起始地址之后,指向p++会发生什么呢?
p++实际上在p原指向的地址的基础上,根据所指向的数据类型,加上一个sizeof(指针所指向的数据类型),导致地址移动了一个单位的长度,指向下一个地址单位。如果p+=5,表示每次移动5个单位的地址长度,记住指针的操作与内存地址密切相关。

八、指针与函数的关系

我们可以把一个指针声明成指向函数的指针。请看下面:
int fun(int x,int y);int(*p)(int x,int y);p = fun;

声明指向函数的指针的时候需要符合函数的参数以及返回值,这样我们就可以通过指针来调用该地址上的函数了。

九、野指针错误

野指针错误指的就是指针指向了不可以的内存地址或一段区域。所以当我们队野指针进行操作的时候会发生不可预期的错误,会导致程序崩溃,这是我们在编程中需要谨慎注意的,请看下面的案例:
int main(){        int * p;       if(p!=NULL)                 free(p);       else{        p =(int*) malloc(sizeof(int)*4);        }        return 0;}
上面的代码通过编译是不会报错的,但是一旦运行,就会发生错误导致程序崩溃。原因在于p指针在声明的时候并没有进行初始化,未初始化的指针在使用的时候系统会自动随机的赋值给指针,是指针指向一段不明内存区域的起始地址,所以当p!=NULL的时候,执行free方法,由于free和malloc都是c++库函数在堆上分配与回收内存的工具,既然p不是在堆上分配的,就无法使用free去让p释放这段内存,这就导致野指针错误。
解决野指针错误主要在于声明指针的时候及时初始化以及指针不再使用的时候需要被及时释放,free也好,delete也行,我们必须在使用指针的过程中意识到这两点,不然还会有内存泄露发生。

十、指针的其他注意事项

1、指针置空不等于释放。
     当声明了一个指针int* p = xxx;之后,把p置为空,p=NULL,此时只是p不再指向任何地址,而p本身所占的内存依然保留,所以需要执行free或delete方法;
2、new
     new关键字使用在堆上分配内存,new比malloc的好处在于,避免了分配长度的显示计算,提高了类型安全性的检查,自动的初始化,有效避免在使用库函数malloc分配内存时的繁琐以及错误的发生率。
0 0
原创粉丝点击