常量指针和指针常量
在C++学习使用过程中,每个人都不可避免地使用指针,而且都或多或少的接触过常量指针或指针常量,但是对这两个概念还是很容易搞糊涂的。
本文即是简单描述指针常量和常量指针的区别。
常量指针
定义:又叫常指针,可以理解为常量的指针,也即这个是指针,但指向的是个常量,这个常量是指针的值(地址),而不是地址指向的值。
通俗理解:指向常量(定语)的指针(主语)。
- 指向常量:代表不能通过该指针来修改对应对象的值
- 但是可以通过原来的声明修改相应的值
- 指针是一个变量
关键点:
- 常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;
- 常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值;
- 指针还可以指向别处,因为指针本身只是个变量,可以指向任意地址;
代码形式:int const* p; const int* p;
指针常量
** 定义:
~~本质是一个常量,而用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值。 ~~
通俗理解:是一个指针(定语)的常量(主语)。根据定语表示性质可知,该常量是一个指针,而常量代表着值无法改变,也就是说指针的值无法改变,也就是指针指向的地址不能变化。但是指向的地址所对应的内容可以变化。**
关键点:
- 它是个常量
- 指针本身是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化;
代码形式:
int* const p;
指向常量的常指针
定义:
指向常量的指针常量就是一个常量,且它指向的对象也是一个常量。
关键点:
1.一个指针常量,指向的是一个指针对象;
2.它指向的指针对象且是一个常量,即它指向的对象不能变化;
代码形式:const int* const p;
区分
那如何区分这几类呢? 带两个const的肯定是指向常量的常指针,很容易理解,主要是如何区分常量指针和指针常量:
一种方式是看** * 和 const 的排列顺序,比如
int const p; //const * 即常量指针
const int p; //const * 即常量指针
int* const p; //* const 即指针常量
还一种方式是看const离谁近,即从右往左看,比如
int const* p; //const修饰的是p,即p的内容不可通过p改变,但p不是const,p可以修改,p不可修改;
const int p; //同上
int* const p; //const修饰的是p,p是指针,p指向的地址不能修改,p不能修改,但*p可以修改;
1 | //-------常量指针------- |
常量指针中的值不可以通过指针修改,但是可以通过原来的声明修改
1 | const int x = 8; |
**const**
本身也是一个类型,因此必须要用**const int ***
常量指针来指向,而不能用普通的指针
在实际应用中,常量指针要比指针常量用的多,比如常量指针经常用在函数传参中,以避免函数内部修改内容。
size_t strlen(const char* src); //常量指针,src的值不可改变;
char a[] = “hello”;
char b[] = “world”;
size_t a1 = strlen(a);
size_t b1 = strlen(b);
虽然a、b是可以修改的,但是可以保证在strlen函数内部不会修改a、b的内容。
指针问题
既然讲到了指针,那顺便说一下空指针、野指针的问题。
空指针就是保存地址为空的指针,使用指针时必须先判断是否空指针,很多问题都是这一步导致的。
野指针是在delete掉指针之后,没有置0,导致指针随意指向了一个内存地址,如果继续使用,会造成不可预知的内存错误。
另外指针的误用很容易造成BUG或者内存泄漏。
看代码:
1 | //-------空指针-------// |