抽象看存儲編譯
如:我們定義 int a= 10,則a需要存儲在計算機裡面,我們把其看成2段值=(記憶體位址,值)。
假如 a 的記憶體位址為 001EFECO,即在計算機中a被存為 =(記憶體位址,值)=(001EFECO,10)。
則計算機編譯時:
獲得a的記憶體位址:001EFECO。
獲得記憶體位址所對應的值:10
根據初始我們的定義 int,計算機得知 目前位址所對應的值為 int型
(int的定義是為了告訴計算機,某個位址所對應的值為int型)。
即:計算機獲得這個記憶體位址,找個這個内容,再根據 内容的定義,把内容顯示出來。
指針定義:
簡單地說,指針是存儲記憶體位址的變量。
用上面的流程來說:
計算機獲得這個記憶體位址(指針的),找個這個内容(指針的),再根據 内容的定義(發現還是個記憶體位址),沒辦法,計算機隻好再來1次, 計算機獲得這個記憶體位址,找個這個内容,再根據 内容的定義,把内容顯示出來把内容顯示出來。
如:
int ptr = &a; &a是獲得a的記憶體位址 = 0023FEF4。 僅僅是告訴計算機,ptr是個指針(它的記憶體位址所對應的值還是個記憶體位址)。
假如 ptr初始為 (001EFOOO,NULL);
*ptr = &a的語義為: 将 &a指派給 ptr,即ptr =(001EFOOO,0023FEF4);
舉例說明
- 列1 簡單指派:
#include <iostream>
using namespace std;
int main()
{
int a=;
int *ptr = &a;
cout << "ptr at:"<< ptr << endl ;
cout << "ptr ="<< *ptr << endl ;
return ;
}
輸出結果:
*ptr輸出時,先獲得ptr所對應的位址,即:0023FEF4。
再根據記憶體 0023FEF4的定義(int a=12),獲得0023FEF4 代表int型,值為12. 即:
ptr=(001EFOOO,0023FEF4),而在記憶體0023FEF4處有: (0023FEF4,12)
-
列2 中間改變指派
在列1的基礎上,再指派1次,如:
#include <iostream>
using namespace std;
int main()
{
int a=;
int *ptr = &a;
cout << "a ="<< a<< endl ;
*ptr =;//中途改變指派
cout << "ptr at:"<< ptr << endl ;
cout << "ptr ="<< *ptr << endl ;
cout << "a ="<< a<< endl ;
return ;
}
輸出結果:
然後我們發現:
初始的時候 a=12.但是中間對ptr指派後,a = 13了。
因為執行 *ptr =13 這句話時,流程為;
獲得: ptr=(001EFOOO,0014F9F8),注:每次執行a值的記憶體位址是變化的。
而a = (0014F9F8,12)
執行:*ptr =13 ,即 0014F9F8 =13. 即執行後,是把0014F9F8 進行了變化。故而a也發生了變化。
若: 将 *ptr =13 替換成: ptr =13,得到結果:
e:\源碼\hello\hello.cpp(9): error C2440: “=”: 無法從“int”轉換為“int *”
這是因為:
指針的類型 和 指針所指向的類型是2碼事情,注意區分,具體可參考部落格:
http://www.cnblogs.com/ggjucheng/archive/2011/12/13/2286391.html
*和&複合運用
研究如下情況:
**ptr (列3)
*&ptr(列4)
&*ptr(列4)
&&ptr(列5)
下面分别舉例說:
**ptr的意思是,ptr是指向指針的指針,如: ptr = (001EFOOO,0014F9G9)。
則: 0014F9G9必須是一個指針的位址。
- 列3
#include <iostream>
using namespace std;
int main()
{
int a= ;
int *ptr = &a;
//int **pi = 30; //不能初始化,類型錯誤,因為30是int型。
//int **pi = ptr; //不能初始化,類型錯誤,因為ptr是指向int型的記憶體位址,而不是指針的位址。
int **pi = &ptr; // 成功,獲得ptr的位址,而ptr是個指針
cout << "ptr at:"<< &ptr << endl ;//ptr本身的記憶體位址
cout << "ptr is:"<< ptr << endl ;//ptr本身的記憶體位址所指向的記憶體位址
cout << "ptr ="<< *ptr << endl ;//ptr本身的記憶體位址所指向的記憶體位址 所代表的值
cout << "pi at: "<< &pi << endl ;//pi本身的記憶體位址
cout << "pi is: "<< pi << endl ;/pi本身的記憶體位址所指向的記憶體位址
cout << "pi =: "<< *pi << endl ;//pi本身的記憶體位址所指向的記憶體位址 所代表的值(ptr指針本身的記憶體位址)
cout << "pi =: "<< **pi << endl ;//實質是 ptr本身的記憶體位址所指向的記憶體位址 所代表的值
return ;
}
`
得到結果:
解釋如下:
ptr = (0014FB78 , 0014F84) 而 (0014FB84 , 12).
0014FB78 代表ptr本身的記憶體位址,ptr本身是個指針。即指針本身的記憶體位址。根據ptr的定義,是指向int值的指針。
0014F84是ptr這個指針所指向的記憶體位址,通過*ptr = &a指派過來的,也就是a的值 = (0014FB84 , 12)
pi = (0014FB6C, 0014FB78)
0014FB6C代表pi本身的記憶體位址,pi本身是個指向指針的指針。即指針本身的記憶體位址。
根據pi的定義 ,0014FB78必須是另外一個指針本身的記憶體位址,即 *pi後,得到 0014FB78。 而0014FB78是 ptr本身的記憶體位址。
故而 * pi = (0014FB78)= *ptr = a值 =12.
-
列4
#include
using namespace std;
int main()
{
int a=12 ;
int *ptr = &a;
cout << "ptr at:"<< &ptr << endl ; cout << "ptr is:"<< ptr << endl ; cout << "ptr ="<< *ptr << endl ; cout << "*&ptr ="<< *&ptr << endl ; cout << "&*ptr ="<< &*ptr << endl ; return 0;
}
輸出結果:
解釋如下:
ptr =(0025F7E8,0025F7F4),a = (0025F7F4,12)
則:
&ptr = (0025F7E8) = ptr的本身記憶體位址所指向的值 = 0025F7F4
&*ptr = &(12) = 12這個值所存儲的位址 = &a = 0025F7F4
- 列5
繼續用上面的結果,分析 &&ptr
&&ptr = & (0025F7E8) ,而值 0025F7E8 所存儲的位址 =(X,0025F7E8), X在哪裡?也就是天知道…..
數組
大爺的,寫累了,後面再說吧。。。。