本篇文章,將提到4個概念:
1、普通變量
2、指針變量
3、內存(內存空間)
4、地址
我們先看內存是什麼?內存是實實在在的硬件,可以存放數據!在我們的一塊可編程的芯片的內部有大把的內存。
形象一點,內存就像一個個的小格子,每個格子的大小是一個字節,可以存放一個字節的數據。
那這麼多內存如何區分呢?那就得靠地址。地址是內存的標識,每一個地址都對應一個內存。所以內存和地址是一一對應密不可分的。
接著看,什麼是普通變量?
如 char a; 就是一個普通變量。普通變量a其實是語言本身創造了,是為了更方便的表示內存,創造內存。我們對a進行訪問其實就是直接對內存進行訪問。至於a表示的內存的地址是多少,程序員一般不用關心。編譯器會自動分配地址,也就是常說的為a分配一個地址。如果想知道a的地址也可以通過&a得知。
再看指針變量,他和普通變量的區別在於,普通變量是和一塊內存空間關聯。而指針變量卻是和兩塊內存空間想關聯:
1、保存指針變量本身的空間,這個空間大小是固定的,32位系統中是4個字節。
2、指針指向的內存空間。
如char* a; 指針變量a,他本身需要一個空間,也就是上面說的(1)。
而(1)這個空間存放的內容是另一個內存空間的首地址。指針變量可以通過改變自己去訪問其他地方的內存空間。
如果說普通變量有兩種形態:
1、a 表示一塊內存空間
2、&a 表示當前內存空間的地址
那麼指針變量就具有3種形態:
1、a 表示指針a對應的內存空間
2、&a 表示當前指針對應的內存空間的首地址
3、*a 表示指針a所指向的變量對應的整個內存空間。
如果硬要說第4種形態,就是是p->x,這種形態出現在結構體變量訪問自己的成員的時候。p->x結合之後看出一個整體,其實就是代表x對應的那塊內存。這裡需要注意的是“->”這個符號,不要理解成指針p指向x,而應該將p->x看成一個整體,“->”只是一個操作符將p和x結合到一起,就可以表示x所對應的內存。
以上結論是具有通用性的。思考下,如果p是結構體指針,那麼*p又是什麼呢?雖然說*p的值意義不大。*p就是對應整個結構體的變量內存空間。這個普通的*a解釋起來是一樣的——表示指針a所指向的變量對應的整個內存空間。(可以用程序證明這一點,為了文章主線,證明過程我想放到《解引用結構體指針的值是什麼》這篇文章中單獨講述)
以上就簡單介紹完了普通變量、指針變量、內存(內存空間)、地址,這四個概念,並且詳細對比了普通變量和指針變量的區別。
接下來,看看地址與指針以及數字常量的區別。
1、指針也稱為指針變量,地址是個常量。指針指向地址。地址僅僅是內存的標號。
2、如何把一個數強制轉換為一個指針類型。
把一個數強制轉換成指針類型:如int*(0)那麼,那麼int*(0)是一個指針,而不是地址。(編譯器會為int*(0)分配內存)
其實就是: int* p = int*(0); 那麼p 就相當與這個int*(0)。
這個指針指向0這個地址。所以此時0表示地址,int*(0)是指針。
3、雖然指針不是地址,但是和地址相匹配,可以將地址賦值給指針。當然也可以直接給指針賦值一個數字常量。但是一般不要這麼做,應為這個數所代表的地址,可能是你不該訪問的,可能會導致段錯誤。
所以指針的賦值一般是將變量取地址賦值給指針,或者通過指針賦值給指針(p = &a 或者 p = p1)。
最後,簡單描述下。指針與內存空間的關系——指針是內存空間的控制器。不同類型的指針,擁有不同的內存管理能力。如int*a 和
char* a管理內存的方式是一樣的。進一步理解可以升入到結構體變量指針(類變量指針),各自有著各種管理內存的方法。
如果你能理解指針是內存的控制器,那麼就能理解鏈表的實現。鏈表會在另外一篇博客詳細介紹。
指針和內存進一步的分析,我也放到另一篇博客~~就到這裡~~