本篇文章分為三個大的部分
大標題1提出權限“概念”,大標題2驗證賦值規則
大標題3、4、5是我的個人理解。
大標題6是最直接的結論。
提醒
看懂這篇文章可能需要你知道並理解四種指針的定義,這是基礎。當然如果真的不懂,可以直接去文尾記住結論。
四種指針詳解戳這https://chouxianyu.github.io/2018/08/26/常量指針與指針常量/#more
指針修改指向內容的權限
普通指針=指針常量>常量指針=四號指針
這個權限指的是通過該指針是否可以修改內存,情況只有兩種:是和否。是的話就有權限,否的話就沒有權限,這個大小是0和1,false和true,是有和沒有,不是12345678的大和小。
普通指針很好說,四號指針也是個常量指針嘛,當然不可以修改內存
這個權限大小關系不難理解,前提是你有理解常指和指常這兩個名詞吧。
前邊的普指和指常都可以修改內存中的內容,而常指和四號則不可以。
指針賦值規則
指針間的賦值:權限大的可以賦值給權限小的(權限指操作內存即修改內存中的內容的權限)
權限大的可以賦值給權限小的,同級權限也可以,小賦值給大不行。
const int n = 0; //常量n
int m = 0; //變量m
int* p1; //普通指針
const int* p2; //常量指針 與int const* p2相同
//int* const p3=nullptr; //指針常量
//int const * const p4; //四號指針 既是常指又是指常,即自身不可修改,也不可通過它修改指向的內存
p1 = p2; //error 普指=常指
p1 = p3; //correct 普指=指常
p1 = p4; //error 普指=四號
p1 = &n; //error 普指=常指
p1 = &m; //correct 普指=普指
p2 = p1; //correct 常指=普指
p2 = p3; //correct 常指=指常
p2 = p4; //correct 常指=四號
p2 = &n; //correct 常指=常指
p2 = &m; //correct 常指=普指
//p3是指常,是常量 賦值當然不行了,更別說權限了,所以上邊不定義p3,
//要討論的是權限,在此定義並初始化以作示例,但定義只能有一個的啊,我在這提醒過了啊
int* const p3 = p1; //correct 指常=普指
int* const p3 = p2; //error 指常=常指
int* const p3 = p4; //error 指常=四號
int* const p3 = &n; //error 指常=常指
int* const p3 = &m; //correct 指常=普指
//p4是四號,是常量,同p3,不贅述
int const * const p4 = p1; //correct 四號=普指
int const * const p4 = p2; //correct 四號=常指
int const * const p4 = p3; //correct 四號=指常
int const * const p4 = &n; //correct 四號=常指
int const * const p4 = &m; //correct 四號=普指
這個規則是我自己想出來的,可能書上雲里霧里的背后就是這么個規律。我之前好像說過存在即合理..實際表述不太對,應該是存在就有原因。上邊的代碼應該囊括了所有“品種”指針的互相賦值,驗證也都符合預期。如有錯誤,歡迎指出。
賦值規則的過程
賦值得要滿足被賦值方的要求,就像你想娶我(捂臉),我就需要你一米八,寵我,其他的都不需要,有的話我也一點不碰。但只要你這兩點缺一點,我就不要,你是馬雲爸爸也不行!
賦值就是那么個意思,我是指常或者普指,我要求有權限修改內存,所以就只有指常和普指能娶我,能給我賦值,因為常指和四號沒有那個權限啊!反過來的話,我是常指和四號,我什么都不要,所以誰賦值都行,上面我們也能看到給常指和四號賦值的時候全都correct了。
賦值規則的必要性
賦值規則前提是不同指針的權限不同
我想多種指針是為了程序更好吧,不然只有一種指針能實現所有的功能,豈不是很可怕。給了程序員太大的權利,程序員一跑神犯錯,程序就極有可能崩潰。給予指針權限之差就像c++里override吧,也是一種對程序員的友好?這是一方面,這應該能說明賦予指針不同權限的必要。
然后才有了賦值規則
我們舉個例子,如果沒有這個規則,不同類型指針自由互相賦值:你定義一個常量n,然后再定義一個int* p,就是普指,普指按說是有修改內存的權利的,然后p=&n,拿到n的地址,是不是就可以通過p改變n了?(在存在不同權限指針的前提下)。如果沒有這個規則,我們可以很隨意地改變常量了。干嘛自己造了一座木屋,然后又給它澆上油?
斗膽扯內存
不管是指針常量還是常量指針還有普通指針,它們本身和那塊內存都是沒有本質關系的。
它們(也包括普通類型的指針)只是一個帶着鐐銬或者沒有鐐銬的工具,我們可以通過const控制指針的權限以及它本身,同時我們在使用它們時也不能超出它們的權限范圍和它們的個人承受力。
結論
int* p1; //普通指針
const int* p2; //常量指針 與int const* p2相同
int* const p3=nullptr; //指針常量
int const * const p4; //四號指針 既是常指又是指常
p1和p3可以互相賦值;
p2和p4可以互相賦值;
p1和p3可以給p2和p4賦值,反之不行;
p3和p4在程序中只能在定義時被賦值一次,因為它們是const類型的量。
作者:@臭咸魚
本文為作者原創,轉載請注明出處:https://chouxianyu.github.io/2018/09/01/指針間的互相賦值/#more
歡迎轉發和評論