C语言 :指针常量和常量指针的区别

标题列出了5个概念,以指针为一组,常量为一组的两组概念内部是非常容易混淆的。希望以本文来清晰区分它们。

一. const限定符

将const理解为一个修饰词似乎更容易理解一些。一旦出现const,一定要看清楚它究竟修饰的是什么。虽然这句话比较抽象且模糊,但接下来所述的所有内容将举出例子,理解下面的内容就会理解这句话的含义。

如下面所看到的,所有涉及指针的概念为一组(即常指针和指针常量为一组),涉及引用的概念为一组(引用、常引用、引用常量)。

非常清楚这些内容的人可能会说:没有引用常量这个说法。这里我们暂且先这样说,后文将会阐述清楚这个说法不存在的事实。

二. 常指针和指针常量

首先能看到这篇文章的读者一定清楚:const是常量,是“只读”而“不可写”的。这个说法毋庸置疑的正确,然而不够具体,因为语法上可能会出现问题,例如这节说的“常指针”和“指针常量”。

永远不要死记硬背,下面的代码只是为了先看下“常指针”和“指针常量”在语法上长什么样子:

1 const int* pt  //常指针

2 int* const pt; //指针常量

很显然,这两者区别就是const的位置,当然也可以说是int*位置的不同,但是int*代表int类型的指针,再看之前所说的const理解为一个修饰词,可以试着理解下面的话:
常指针const int* pt中const修饰int*,连起来说就是“常整型指针”,但是随着指针指向的数据类型不同这个说法也将随之改变,例如const char* pt就是“常字符型指针”,因此省略中间的指针指向的数据类型名,统一称为“常指针”。

再来看常指针的作用。仍然以const int* pt为例:const修饰了int*,并未直接修饰pt,也就是说指针变量pt并不是“只读”的,而说的是pt是指向整型常量的指针,指针指向的数据不可更改。因此常指针的作用是保护指向的数据不被更改。

如果理解了常指针,指针常量就比较好理解了:int* const ps中,const修饰指针ps本身,因此指针ps就是“只读”的,不能再改变指针本身的值,也即不能改变指针的指向,但指向的数据却是能更改的。

三.常引用和引用常量

常引用和引用常量实际上跟常指针和指针常量基本一致,只不过这里把指针换成了引用就可以了,并且作用与常指针和指针常量是一致的,因此不再赘述。但是要说明:实际上不存在引用常量这个说法,也不存在引用常量这个东西。可以尝试在VS中作如下定义:

int a=0;
int& const b=a;

编译时并不会报错,但是会有如下提示
warning : 使用了记时错误: 忽略引用上的限定符

而当去掉const时此警告就会消失,也就说明了其实并不存在引用常量这个东西。

实际上这就涉及了一个问题:引用的本质是什么?

一般教科书上说:引用就是“别名”。确实这个说法没有大问题。但这并不是本质。

引用不占据内存空间这种说法是错的,如果反编译看汇编代码,会发现引用实际上被解释为一个指针常量,而这也恰好符合引用本身不能更改的原则。

这样看引用常量不存在的原因很明显了:引用本身就被解释为指针常量,再用const修饰完全没有意义。

总结:

常量指针:指向常量的指针。

  • 指针本身可以改变,可以再次指向另外的对象。
  • 不能通过指针修改其所指向的对象的值。
  • 对象本身的值可以直接修改。

指针常量:指针类型的常量。

  • 指针本身的值不能改变,即不能再指向另外的对象。
  • 可以修改指针所指对象的值。

猜你喜欢

转载自blog.csdn.net/fly_sky_share/article/details/89977039