前面寫了指針數(shù)組和數(shù)組指針,指針函數(shù)和函數(shù)指針?,F(xiàn)在又來了一對(duì)比較讓人模糊的概念。還是原來的套路先看英文:
- 指針常量:constant pointer;即: 常量類型的指針,或者也可以說指針類型的常量。(int *const p)
- 常量指針:Pointer to a constant;即:指向常量的指針。(const int *p, int const *p)
(Ps:指向常量的指針:指你不能通過一個(gè)常量指針去改變指針指向位置的值;這里有深意后面你會(huì)理解。)
這個(gè)問題是有一個(gè)巨大的難點(diǎn),就是不論是中文還是代碼的寫法,都十分的相似,甚至說這兩都是指針。以至于我在初學(xué)時(shí)費(fèi)了老大力氣也沒記住。
后來我發(fā)現(xiàn)一個(gè)重要的點(diǎn),不管我們聲明的是什么,我們聲明的變量p目的是為了使用?,F(xiàn)在觀察下面:
// 指針常量
int *const p;
// 常量指針
const int *p;
int const *p;
我發(fā)現(xiàn):
- 指針常量:const更接近p,決定了p是一個(gè)常量;* 決定了這個(gè)常量的類型
- 常量指針:* 更接近p,決定了p是一個(gè)指針;const決定了這個(gè)指針指向的值類型
下面看詳細(xì)用法:
指針常量:指針類型的常量
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
int a = 5;
int b = 10;
// 定義一個(gè)指針常量,指針常量本質(zhì)上既是指針又是常量
// 指針的屬性:決定了它里面存的是地址。
int *const p = &a;
// 常量的屬性:決定了它只能被賦值一次
// p = &b; // 再次賦值錯(cuò)誤
qDebug() << p << " : " << *p;
return app.exec();
}
運(yùn)行結(jié)果
0x73fd1c : 5
我們發(fā)現(xiàn)指針常量的使用和引用是如此的類似。其實(shí)引用就是用指針常量來實(shí)現(xiàn)的。指針和引用的區(qū)別我們后面再說。
常量指針:指向常量的指針
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; // 聲明一個(gè)常量指針
p = &a; // 可以指向一個(gè)全局的常量
qDebug() << p << " : " << *p;
p = &b; // 可以指向一個(gè)靜態(tài)變量
b = 4;
qDebug() << p << " : " << *p;
p = &c; // 可以指向一個(gè)局部的常量
qDebug() << p << " : " << *p;
p = &b2; // 可以指向一個(gè)全局的變量
qDebug() << p << " : " << *p;
p = &c2; // 可以指向一個(gè)局部的變量
qDebug() << p << " : " << *p;
// *p = 4; // 不可以通過一個(gè)常量指針來改變指向?qū)ο蟮闹怠? return app.exec();
}
運(yùn)行結(jié)果:
0x405018 : 1
0x404010 : 4
0x73fc5c : 3
0x404014 : 20
0x73fc58 : 30
這里我們發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象:常量指針可以指向:一個(gè)全局的常量、一個(gè)靜態(tài)變量、一個(gè)局部的常量、一個(gè)全局的變量、一個(gè)局部的變量;而唯一不能做的就是你不能通過一個(gè)常量指針去改變指針指向位置的值。
這個(gè)常量的意義在這里。