C語言中二維陣列名與陣列地址、首行地址、首行首元素地址關係與區別詳解(初學者必須掌握)
阿新 • • 發佈:2019-01-02
C語言作為很多大學理工科都會學習的語言,作為一種程式設計入門語言。
但是相對於其他高階程式語言來說相對是比較難,尤其是指針,不知道有多少莘莘學子都是因為它,從C語言入門到放棄。
想當年,筆者在大一學習C語言時也是被折磨的不輕,那個時候弄氣泡排序都不會。可能是那個時候邏輯思維不行吧,感覺工作後思維能力變強了,難道是被逼的,不知道你們有沒有這種感覺。
不扯了!
進入主題,今天來探討二維陣列名到時是個啥?與陣列地址、首行地址、首行首元素地址、指標到底有什麼關係區別。
在C語言中地址就是指標,指標就是地址。我們的陣列名也是地址,但是它到底是誰的地址呢?
有人說是陣列地址,有人說是首元素地址,如果是二維陣列 有人或許會說是首行地址。
沒毛病,他們的值都是相等,他們都重疊在一起的!但是他們所代表的意義卻大不一樣。下面用程式碼來揭開他們的神祕面紗。
/* 測試 二維陣列 陣列名和整個陣列地址、首行地址、首行首地址的區別和聯絡 */ void arrPositonTest() { char a[4][30] = { "abcd","efjh","ijkl","mnop" }; //&a 代表的是陣列首地址,+1 步長=4*30*1 = 120 printf("&a=%d,&a+1=%d\n", &a, &a + 1); //a 也就是陣列名 代表的是陣列首行地址,+1 跳過一行 步長=1*30*1=30 printf("a=%d,a+1=%d\n",a,a+1); //a 是首行地址 步長是整個一維陣列,也是整個一維陣列的首地址 。(*一維陣列首地址) 就是首元素地址,不理解可看一維陣列地址分析。 //*a 就是首行首元素地址,+1 跳過一個元素 步長 = 1*1 printf("*a=%d,*a+1=%d\n", *a, *a + 1); //儘管 整個二維陣列地址、首行地址、首行首元素地址他們的值是一樣的,但是他們本質不一樣,也就是+1代表的步長不一樣! printf("整個二維陣列地址:%d,首行地址:%d,首行首元素地址:%d\n",&a,a,*a); //我們知道*a代表二維陣列首行首元素地址,那麼**a 也就是首行首元素的內容了! //*(*a+0):第一個元素內容,*(*a+1):第二個元素內容,*(*a+30):第二行第一個元素內容,*(*a+31):第二行第二個元素內容。 printf("**a:%c,*(*a+1):%c,*(*a+30):%c,*(*a+31):%c\n", *(*a + 0), *(*a + 1), *(*a + 30), *(*a + 31)); //當然我們取第二行元素的內容,同樣可以使用第二行行地址來取。 //a+1代表第二行地址,*(a+1):第二行首元素地址,*(a+1)+1:第二行第二個元素地址,知道地址就可以用*取出內容。 //*(*(a+1)):第二行第一個元素內容,*(*(a+1)+1):第二行第二個元素內容。和上面取出來一樣,從側面也驗證了二維陣列在記憶體中還是線性儲存的。 printf("*(*(a+1)):%c,*(*(a+1)+1):%c\n", *(*(a + 1)), *(*(a + 1) + 1)); //一維陣列地址分析 char b[30] = { "wxyz" }; //&b 代表的是整個一維陣列的首地址,+1 表示跳過整個一維陣列 步長=1*30 = 30。 //相當於二維陣列的陣列名a 代表的陣列首行地址 a+1 步長是整個一維陣列的長度。 // *a 等價於 *(&b) b也就是陣列首個元素的地址,所以*a +1是跳過一個元素。 printf("&b=%d,&b+1=%d\n", &b, &b + 1); //b 也就是一維陣列名 代表首元素地址,+1 跳過一個元素 步長=1*1=1 printf("b=%d,b+1=%d\n",b,b+1); //知道b是首元素地址,那麼*b就是首元素的內容了*(b+1)也就是第二個元素的內容了。 printf("*b=%c,*(b+1)=%c\n", *b, *(b + 1)); return; }
你有耐性看完麼,雖然技術不咋地,但是我們仍然的需要努力。三維陣列或者更多維的陣列都是一樣的,我們只需要把陣列名當做變數最近的那個[]方括號裡面內容的地址就行了。比如char a[30] = "add";a代表的首元素地址char b[3][30]={"abc","bcd","ddd"},
b代表的是最近方括號是誰?是行,那麼b代表的就是行的地址,三維的話,不知道叫啥,姑且就叫棟吧,就是棟的地址。然後在進行推導。
在主函式中呼叫它
驗證結果截圖:
886了,下次見。