前面写了指针数组和数组指针,指针函数和函数指针。现在又来了一对比较让人模糊的概念。还是原来的套路先看英文:
- 指针常量:constant pointer;即: 常量类型的指针,或者也可以说指针类型的常量。(int *const p)
- 常量指针:Pointer to a constant;即:指向常量的指针。(const int *p, int const *p)
(Ps:指向常量的指针:指你不能通过一个常量指针去改变指针指向位置的值;这里有深意后面你会理解。)
这个问题是有一个巨大的难点,就是不论是中文还是代码的写法,都十分的相似,甚至说这两都是指针。以至于我在初学时费了老大力气也没记住。
后来我发现一个重要的点,不管我们声明的是什么,我们声明的变量p目的是为了使用。现在观察下面:
// 指针常量
int *const p;
// 常量指针
const int *p;
int const *p;
我发现:
- 指针常量:const更接近p,决定了p是一个常量;* 决定了这个常量的类型
- 常量指针:* 更接近p,决定了p是一个指针;const决定了这个指针指向的值类型
下面看详细用法:
指针常量:指针类型的常量
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
int a = 5;
int b = 10;
// 定义一个指针常量,指针常量本质上既是指针又是常量
// 指针的属性:决定了它里面存的是地址。
int *const p = &a;
// 常量的属性:决定了它只能被赋值一次
// p = &b; // 再次赋值错误
qDebug() << p << " : " << *p;
return app.exec();
}
运行结果
0x73fd1c : 5
我们发现指针常量的使用和引用是如此的类似。其实引用就是用指针常量来实现的。指针和引用的区别我们后面再说。
常量指针:指向常量的指针
const int a = 1;
static int b = 2;
int b2 = 20;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
const int c = 3;
int c2 = 30;
int const *p; // 声明一个常量指针
p = &a; // 可以指向一个全局的常量
qDebug() << p << " : " << *p;
p = &b; // 可以指向一个静态变量
b = 4;
qDebug() << p << " : " << *p;
p = &c; // 可以指向一个局部的常量
qDebug() << p << " : " << *p;
p = &b2; // 可以指向一个全局的变量
qDebug() << p << " : " << *p;
p = &c2; // 可以指向一个局部的变量
qDebug() << p << " : " << *p;
// *p = 4; // 不可以通过一个常量指针来改变指向对象的值。
return app.exec();
}
运行结果:
0x405018 : 1
0x404010 : 4
0x73fc5c : 3
0x404014 : 20
0x73fc58 : 30
这里我们发现一个有趣的现象:常量指针可以指向:一个全局的常量、一个静态变量、一个局部的常量、一个全局的变量、一个局部的变量;而唯一不能做的就是你不能通过一个常量指针去改变指针指向位置的值。
这个常量的意义在这里。