一、概念:
1.1、指標陣列(char*p[4]):表示p是含有4個元素的陣列,每個元素存放的資料是指標型別。
1.3、指標與陣列的關係:
其實指標的本質就是陣列,一級指標是一維陣列,二級指標是二維陣列,以此類推。注意: 「」與「*」都是取資料符號,但「」取得是陣列自身元素的資料,而"*"取得是間接取p值的資料,(也就是變數a的值)。
int *p \\即p指向位址在記憶體的資料長度為1個int ,注意int*p與int(*p)[1]完全不一樣,相當於變數和陣列的區別。
int (*p)[1] \\表示p是個指標,p指向位址(p值)的資料空間長度為1個int(只有1個元素的陣列,它與變數還是有區別的),此時將p指向位址的資料空間看作乙個陣列。該指標定義中有1個「*」和1個「」兩個取資料符,也就是說表示式p中含有兩個取資料符結果才是資料。
int (*p)[4] \\表示p是個指標,p指向位址(p值)的資料空間長度為4個int,該資料空間看作含4個元素的陣列。如p[2]表示式的值為位址,表示指標p指向位址偏移2個單位(int(*)[4]即2x4位元組後在記憶體中的位址;如p[2][3]表示式為資料,表示指標p指向位址先整體偏移2個單位(int(*)[4])即8位元組,再偏移3個元素,即*(p+2)+3的位址,取該位址在記憶體中的資料即*(*(p+2)+3)=p[2][3]。
注意:型別相同長度不同的指標,不能直接賦值,如下
int a[3]=; \\陣列a長度為3個int。
int *p=null;
p=a; \\等價於p=&a[0],此時的a代表第一元素的位址。
p=&a \\此時a代表整個陣列(長度3個int)的位址,這種寫法是不規範的,正確寫法:p=(int*)&a
1.4、指標變數p是個位址,而陣列的陣列名a也是個位址,從而可以這樣賦值p=a,由此衍生的指標陣列、陣列指標所產生的表示式及運算千變萬化,經常看到乙個表示式都不知道,最終所求的值是位址還是資料。網路上看了好多推演的教程,也思考了很久,但看到好多推演斷層式的表示式,還是想不明白。最終自己找到「以不變應萬變」的方法,算是自己的感悟吧!
二、「3部曲」
(1)不管多少維的陣列,表示式中"」比維數只要少乙個,那麼這個表示式的值就是位址,並且該位址是該維的首位址,如二維陣列a[3][2],三維資料b[2][3][2],一維陣列c[10]。
(2)任何維數陣列所表示的位址表示式("」比維數少),增加""結合成新表示式時(結合「*」相當於增加乙個""),只要「」的個數少於維數,無論怎麼結合都是位址偏移(有多少個「[i]」或「*」要結合,那麼直接加i就行),並且它結果還是個位址,只有當「」的個數等於維數,表示式的值才是元素值(也就是該記憶體位址中的資料)。注意: 「」與「*」都是取資料符號,等效的。
部曲3:p+1偏移代表什麼。若p在指標定義表示式中是陣列,則偏移乙個元素;若p在指標定義表示式中是指標變數,則偏移指標定義中指向的整個資料的長度。
三、案例分析
案例1(指標陣列):
int n[3][4] = ;
int *pn[3] = ; \\pn先與結合,所以pn為一維陣列。
printf("%d\n", (*(pn + 2))[3]); \\陣列pn少,pn為位址且偏移2,取資料符*(pn+2)等價pn[2],即一維陣列pn結合1個""就是元素值(資料),因pn[2]的值為n[2],而n為二維陣列,n[2]少了1個""表示為位址,n[2]在結合1個「」即n[2][3]=12表示元素(資料)。
printf("%d\n", pn[1][2]); \\陣列pn結合1個""即pn[1]就是元素(資料),因pn[1]的值為n[0],而n為二維陣列,n[0]少了1個""表示為位址,n[0]在結合1個「」即n[0][2]=3表示元素(資料)
printf("%d\n", *(pn + 1)[1]); \\陣列pn少,pn為位址且偏移1,(pn+1)沒有[ ]還是個一維陣列的位址,跟"[1]"結合,既結合「」又偏移1,滿足「」個數 等於維數,即為pn陣列的元素pn[2],因pn[2]=n[2],而n為二維陣列,n[2]少了1個""表示為位址,與「*」結合,相當於增加乙個"",即*n[2][0]=9。這裡要特別注意運算優先順序。
案例2(陣列指標):
int a[14] = ;
int(*p)[2] = a; //p先與*結合,所以p是指標,長度為2個int。從指標的定義看,指標有兩個取資料符,也就是說表示式中含有兩個取資料符結果才是資料,類推int(*p)[2][3]要3個取資料符結合才是資料。
printf("%d\n", p); //p的不夠2個取資料符,為位址。
printf("%d\n", *p); //p的不夠2個取資料符,為位址。
printf("%d\n", **p); //p結合2個取資料符,為資料。
printf("%d\n", p[1]); //p的不夠2個取資料符,為位址。
printf("%d\n", *p[1]); //p結合2個取資料符,為資料。
printf("%d\n", p[1][1]); //p結合2個取資料符,為資料。
案例3(陣列指標):
int n[3][4] = ;
int (*pn)[4]=n; \\pn與*先結合,因此pn為指標變數,並且指向的陣列長度為4。等價式pn=n,即可將pn當做二維陣列n運算。
printf("%d\n", (*(pn + 2))[3]); \\pn偏移2單位還是位址,再與*結合(相當於pn增加乙個""),即pn[2]=n[2],最後n[2]和[3]結合即n[2][3],所以n[2][3]=12是陣列的元素。
printf("%d\n", pn[1][2]); \\pn=n,即pn[1][2]=n[1][2],而n[1][2]中「」個數等於陣列維數,n[1][2]=6為陣列元素。
printf("%d\n", *(pn + 1)[1]); \\pn偏移1單位還是位址,跟"[1]"結合,既增加「」又偏移1,即pn[2],因pn[2]=n[2],而n為二維陣列,n[2]少了1個""表示為位址,與「*」結合,相當於增加乙個"",即*n[2][0]=9。
C 指標與陣列的關係及運算
陣列其實是乙個位址,這個位址儲存的是陣列的第乙個元素的記憶體位址。因此可以將陣列名賦值給乙個指標,或者你也可以將陣列名當成乙個指標使用。以下訪問陣列的 都是正確的。int array 10 int parray array 直接將陣列名賦值給指標 訪問陣列的第乙個元素可以如下方式 array 0 正...
指標與陣列及函式關係
1.對於c 的九種內建基本型別來說。在程式中出現該名稱,即表示指向該型別的乙個變數 或常量等 通常我們對於變數作為右值,即去變數位址空間的值。但對於陣列名和函式名則不同 因為陣列的值和函式值很難或無法表示 如 int arr 2 c 規定陣列名代表指向首元素的位址,即陣列名作為右值,取的是第乙個元素...
指標與陣列的關係
指標與陣列的關係 指標與陣列是c語言中很重要的兩個概念,它們之間有著密切的關係,利用這種關係,可以增強處理陣列的靈活性,加快執行速度,本文著重討論指標與陣列之間的聯絡及在程式設計中的應用。1 指標與陣列的關係 當乙個指標變數被初始化成陣列名時,就說該指標變數指向了陣列。如 char str 20 p...