【基础】指针常量与常量指针

【基础】指针常量与常量指针

  • 指针常量
  • 常量指针
  • 指向常量的指针常量
  • 编码时的记忆方法

指针常量与常量指针是非常常见但又很容易搞混的概念,并且这里面也有一些涉及到C程序运行布局的知识,所以就趁热一起温习一遍。指针常量与常量指针本身的名字就够绕的了,还好看了很多文章发现一个比较好记忆的方法。

指针常量

看到这个名词的时候首先想一下它的主语和修饰,首先它一定是一个常量,使用指针修饰所以是一个指针类型的常量。常量意味着是只读的,也就是说这个指针的值是不可以修改的。指针的值是什么?是一个地址!这个地址是不可以修改的!也就是说这个指针永远只能指向一个地址。但是!这个地址上存放的数值,就不一定了。
根据通常的常量定义的注意点:只能在定义的时候初始化,所以可以知道的是,如果是定义了一个指针常量,就一定会在定义的同时赋值。换言之如果定义的时候没有赋值,它怎么也不会是个指针常量。

int a=10;
int * const b = &a;	//定义一个指针常量,const在*的右边。可以看到定义的时候就进行了赋值*b)++//正确:*b实际上就是a,a就是一个普通的int型变量,++后a的值是11
b++//错误:b++改变的是b指向的地址,然而b是常量不可以修改

根据之前写的C程序布局的博客,可以知道这种指针常量是存放在只读数据段中的。

常量指针

同样的方法看,它首先是一个指针,但却是一个指向常量的指针。这意味着指针指向的变量是常量?不准确。最恰当的说法应该是:无法通过该指针修改指向的变量的数值,至于被指向的数值是不是常量,这是不确定的。此外,该指针只是一个普通的指针,所以指针是可以修改它的数值去指向其他地址的,这也是两个概念之间比较直观的区别之一,这个指针也因此不会存放在只读数据段。

int a=10;
const int * b = &a;	//定义一个指针常量,const在*的右边。可以看到定义的时候就进行了赋值
int const * b;	//两个都可以,意义完全一样,同时,该变量定义的时候可以不进行赋值*b)++//错误:*b实际上就是a,然而是无法通过b去修改a的数值的
a++//正确:a就是一个普通的int变量并不是常量,所以可以进行修改
b++//正确:b++改变的是b指向的地址

从上述代码中可以看到,常量指针不是说指向的是一个常量,而是说仅仅对于这个指针而言,指向的变量是一个常量,无法通过指针去修改他。但是实际上可以通过直接访问这个变量去修改。

常量指针最大的一个用途就是在参数传递中:
通常而言,如果调用一个函数传递的不是指针,那么局部变量的修改是不会影响到实参本体的。但是如果要传递的参数是一个很大的数组,那么传递数组指针一定是一个最高效的方式,但这也意味着函数内部可以直接访问到数组本体,如果发生了意外的修改就GG了。所以这时就要使用常量指针的方法,将函数的入口参数限定为常量指针,这样的话,函数内部还是可以访问数组但是却不可以修改数组的值,这样不就可以保证数组的安全了么?例子如下:


void strCmp(const char *a,const char *b)
{
	//函数内部可以通过指针a和b访问实际的数组但是却不能修改它们
}

指向常量的指针常量

很绕人,不过意思就是首先这个指针是一个常量,它指向的地址不可以修改。同时,在这个地址上的,被该指针指向的数据元素对于该指针来说是一个常量,也就是说不可以通过指针修改它。

const int * const a;

编码时的记忆方法

通过分析主语,已经能够理解指针常量和常量指针的含义了。但是总是记不住const和*的位置关系,写完这篇博客的时候才发现,其实同样可以使用分析主语的方式来做,const是常量关键字,*是指针关键字,所以:
指针常量是指针类型的常量,指针在左常量在右:type* const var;
常量指针是指向常量(不一定是真常量)的指针,常量在左指针在右:const type/type const * var;

搞定!

你可能感兴趣的:(C/C++)