我之前也寫過一篇「對c++中指標的簡單理解」,因為也是剛開始寫部落格,感覺弄得亂糟糟的,而且有種斷章取義的感覺。所以今天打算寫得細緻一點(其實也就是照著書上搬的)。提到陣列與指標我想大多數同我這樣的渣渣一樣,都覺得不好弄懂。以前老師上課吧,也沒認真聽,而且都是斷斷續續地在講。現在自己從圖書管裡面借了一本書來學習,終於大致弄懂了(估計也就是皮毛);不過掌握一點總比不會好吧。指標這個東西對於學語言(我所知的特別c和c++)都有特別大的用處。如果不學好,就會出現 有可能某一天你看別人寫的**,裡面全是指標,頓時你就傻眼了。我寫這個的目的也是為了鞏固自己所學的,順便就當做個筆記,以便於以後檢視。說實話,這個東西如果你不經常用到,就算你今天弄懂了,可能隔幾天又忘得差不多了。好了,費話扯得差不多了,就開始進入正題吧!
說到指標就先簡單說說計算機裡面的記憶體是怎麼回事吧。在計算機中,系統的記憶體就像是帶有編號的小房間,如果想使用記憶體就需要得到房間號。如圖1所示,定義乙個整型變數i;之後計算機就分配給它4個位元組,所以編譯器為變數i 分配了編號從2001到2004的房間(這兒的編號只是我隨意舉例的,在計算機中位址一般類似於這樣0044fa28,不過不影響我們對整體的理解);每個房間代表乙個位元組。
當為變數i=5賦值之後,就被連續地儲存在系統的記憶體中,如圖2所示(其實應該是2進製00000000 00000000 00000000 00000101)
在程式執行時,是根據變數與位址的對應關係,找到變數i的位址2001,然後從2001開始讀取4個位元組的資料放到暫存器中。由於通過位址能訪問指定的記憶體儲存單元,我們就可以說該位址「指向」該記憶體單元,之後我們就可以把位址形象的稱為指標,即乙個變數的位址稱為該變數的指標。這也就是對指標概念的引出。另外,如果有乙個變數專門用來 存放另乙個變數的位址,它就是指標變數(其實指標也是乙個變數,只是它僅用於儲存變數)。
資料型別 *指標變數名
如:int *p;
初始化:
a.在定義時初始化:
int i;
int *p=&i; (其中&是取位址符,表示把i的位址取出來賦給p)
b.在定義之後賦值:
int i,*p;
p=&i; (注意,這種情況下賦值的時候就不要*了)
例1:
#include void main()
注:其中p,q是變數名,*p,*q 表示取變數p,q所指向記憶體單元的值
如:int i=2015;
int *p=&i;
&和*的運算子優先級別相同,按自右向左的方向結合,因此&*p是先進行*運算,*p相當於變數i的值(2015),再進行&運算,&*p就相當於變數i的位址。*&i是先計算&運算答,&i就是取變數i的位址,然後進行*運算,*&a就相當於取變數i 所在位址的值(2015)。總之你只要記住兩個運算子的作用,和結合方向就知道結果了!
因為指標也是變數,所以同樣可以進行運算(本處就僅限於+-吧,我想其實剩除也行只是對於初學者意義不大)。
如圖3所示,當定義變數i,j(int i=3,j=4),且此處假設計算機在分配記憶體的時候i,j變數之間是連續分配的(等後面說到陣列的時候就更好理解了,這兒只是先提出一下)
如果int *p=&i; 之後,p就指向了101,p++之後,則p就指向了105,此處的加1並不是從101到102的變化,而是加了乙個單位的距離,可以理解成單位「1」;這個例子在計算機上基本上是不能實現的,因為在分配記憶體的時候,幾乎不可以是這樣連續分配的。說到陣列之後就容易理解了。
先簡單說一下什麼是陣列。陣列,作為同名、同型別的元素的有序集合,被順序存放在一塊連續的記憶體中(注意這兒是連續,且不僅僅限於一維陣列,n維陣列在記憶體中也是是連續儲存的,只是為人理解,人為的把它們的位址做了一些變化,如圖4),而且每個元素的儲存空間大小相同,比如是int 型的陣列則每個元素的大小都是4個位元組。(我只是搬運工哦,順便加了一些自己的理解)
如圖4.1所示,在定義乙個一維陣列int a[7] 之後,陣列a就被分配了等大小(都是4個位元組)的7個連續空間,從301-307;此時的陣列名a就代表該陣列的首位址(301,等價於&a[0]);之後我們就可以通過使用陣列名和下標的方式來引用陣列裡面的值。接著說二維數,如圖4.2所示,定義了個二維陣列int b[4][3],陣列b就被分配了等大小(都是4個位元組)的12個連續空間,從401-412;注意,這兒的陣列名就不代表首位址了,b[0]才代表該陣列的首位址(401,等價於&b[0][0]),同樣我們可以通過陣列名和下標的方式來使用陣列。同時,為了我們方便理解,才把二維陣列(n維也是一樣的理解)轉化成圖4.3的形式。此時,我們可以分別把b[0],b[1],b[2],b[3]叫作該每一行的行位址。
(2)&b[0][0]既可以看作是第0行的首位址,也可以看作是整個二維陣列的首位址;同理&a[m][n]就表示第m行的第n個元素的位址;
(3)*(b[n]+m)表示第m行第n列的值,因為b[n]代表第n行的首位址,然後再向右移動4個單位,再用*運算子,就表示它的值了
例2.
#include void main()
, };
for(int i = 0; i < 6; i++)
printf("%d ", *(a[0] + i)); //從首位址開始,一直往後移動
}
執行結果:
1 2 3 4 5 6 請按任意鍵繼續. . .
最後我們再來說說指標的運算。就拿我自己的接觸來說,指標的運算更多的就是在陣列裡面。其它地方幾乎也沒見過指標有運算的,說到底就是因為其它地方的變數分配的位址不是連續的,所以運算也是沒有意義的。
接著用圖4來說
在圖4.1中,我們定義了乙個陣列a[7],且進行了初始化。此時再定義乙個指標,int *p=a;(或int *p=&a[0]) 並把陣列的首位址初始化為陣列a的首位址,然後我們就可以通過指標p來運算元組了。
例3:
#include void main()執行結果:; int *p = a;
for(int i = 0; i < 7; i++)
printf("%d ", *p++); //從首位址開始,一直往後移動
}
1 2 3 4 5 6 7 請按任意鍵繼續. . .
注:(1)*p++ 相當於a[i++],表示輸出p所指向的值之後,指標p下移乙個單位(也就是4個位元組,若定義的陣列是long long a[7],單位長度就可能是8個位元組了,一定要理解p+1的含義)
(2)*++p 相當於a[++i],表示指標先移動乙個單位,然後輸出p所指向的值
(4)同理*++p也等價於*(++p)
在圖4.2中,我們定義了乙個二維陣列b[4][3],並也進行了初始化;此時再定義乙個指標int *p=b[0](或int *p=&b[0][0])並把陣列的首位址初始化為陣列a的首位址,然後我們就可以通過指標p來運算元組了,當然你也可以從中間擷取如:int *p=b[2];
例4:
#include void main()
, , , };
int *p = a[0];
for(int i = 0; i < 8; i++)
printf("%d ", *p++); //從首位址開始,一直往後移動
p = a[2];
printf("\n");
for(int i = 0; i < 4; i++)//從第2行開始,一起往後移動
printf("%d ", *p++);
}
1 2 3 4 5 6 7 8
5 6 7 8 請按任意鍵繼續. . .
好,陣列與指標就先跟大家扯到這兒(不應該是和我自己扯到這兒,估計也沒有看,留著以後自己慢慢回顧)! 未完待續!!!!!!!!!!
2023年4月9日11:34:25
指標與陣列,指標陣列 陣列指標
int a 10 print n a p,a p a,a print n a 1 p,a 1 p a 1,a 1 a做乙個指標,步長為4,指向乙個元素,a做乙個指標,步長為40,指向乙個維陣列 int b 3 4 print n b p,b p,b p b,b,b print n b 1 p,b 1...
指標陣列與陣列指標
1.指標陣列 指標陣列中每乙個元素都是乙個指標,也既是存放字串的首位址。所以指標陣列適合處理若干個長度不等的字串。定義的一般形式為 型別說明符 指標陣列名 陣列長度 例如 int p 3 宣告乙個陣列,指標陣列p,由3個int型別指標變數元素組成 從運算子的優先順序分析,由於 的優先順序大於 所以p...
指標陣列與陣列指標
呵呵,實在是厭倦了繞口的解釋。指標陣列,故名思義,就是指標的陣列,陣列的元素是指標 陣列指標,同樣,就是直想陣列的指標。簡單舉例說明 int p 2 首先宣告了乙個陣列,陣列的元素是int型的指標。int p 2 宣告了乙個指標,指向了乙個有兩個int元素的陣列。其實這兩種寫法主要是因為運算子的優先...