二維陣列和雙重指標的轉換及使用 - w3c菜鳥教程

文章推薦指數: 80 %
投票人數:10人

二維陣列和雙重指標的轉換及使用,我們在學習c語言的時候經常會寫這樣的程式void func1 int p void func2 int a int main 即一維陣列. 二維陣列和雙重指標的轉換及使用 2021-06-1620:37:34字數2231閱讀6127 我們在學習c語言的時候,經常會寫這樣的程式: voidfunc1(int*p) voidfunc2(inta) intmain() 即一維陣列與指標作為函式引數的互換使用,我們可以一眼看出這個程式是可以通過編譯的. a是陣列a[10]第一個元素的地址,作為引數傳遞到函式中去,接收方是*p,在函式中可以使用*p,或者p[0]來訪問元素.看起來陣列和指標可以這樣互換著使用,編譯器會把它們編譯成一樣的東西. 問題的提出: 再來看下面的**,為什麼這些**會報錯? voidfunc1(int(*p)[10]) voidfunc2(int(*p)) voidfunc3(int**p) intmain() 分析: 當把a作為引數傳給函式時候,a代表的是"指向陣列的指標",該陣列一共有10個int型的元素.a本身確實是一個指標,但是這個指標是指向陣列的,不是指向"陣列的首元素". 接收方也需要是此型別,int(*p)[10]表示p這個指標是指向陣列,該陣列有10個int元素,跟傳入引數形式一致,因此pass. error1和error2自然就是因為不匹配. 當把p作為引數傳給函式的時候,p代表的是"指向指標的指標",也叫做雙重指標,所以接收的時候int**p型別相匹配,pass. 小結: 一維陣列和指標可以互換使用,這是由於編譯器幫我們規定了陣列名=首元素的地址,我們才能夠這樣用. 因此不要以為二維陣列和雙重指標也可以用類似的方法來互換使用. 這當然不會是本文的最終目的.我要說明的是, 當我們非得將**p和a這樣的形式混用時,我們應該怎麼做. 作為引數時: 看下面的程式: voidfunc4(int*p) intmain() 這次我們可以將**p送給*p,原因在於:*p表示一個指標陣列,p就是這個指標陣列的陣列名,也就是第一個元素(這個元素是指標)的地址,說白了,就是指標的地址.當然,作為形式引數,p這裡就是一個變數,即從"地址",變成了"指標"(變數),所以送過來的p是雙重指標,接收的p還是雙重指標, 當然可以編譯通過, 這又是編譯器玩的一個花樣.可以看出,這個過程其實我們還是沒有擺脫上面所說的,編譯器幫我們規定了陣列名=首元素的地址. 在函式內使用時: 看下面的程式: #include usingnamespacestd; voidfunc1(int**c,inta,intb) func1(p,2,3); }編譯執行,如果你像我一樣運氣好的話,程式不會崩潰,你會得到一組數字: 03436320 如果定義a[2][3]這樣的二維陣列,我們在使用的時候編譯器會將a[x][y]採用形如p+3*x+y的定址方式,因為編譯器知道我們的一行是3個元素. 在func1函式裡,傳入的是雙重指標,接收的是**p也是雙重指標,可是使用的時候呢? 上面的是錯誤的示例,因為在函式內部編譯器不知道你這個陣列是幾行幾列的. 它沒法將c[x][y]轉換成p+3*x+y的定址方式.所以我需要同時傳入兩個額外的引數a和b來表示陣列的行列,在使用的時候我就可以手動將c[x][y]轉換成p+a*x+y,再加上取值符號就可以取出正確的值:*(p+a*x+y) 實際上如果你使用c[x][y]這樣的形式(如上面的程式),編譯器不會報錯,但是你執行的時候,就有很大的機率崩潰,因為編譯器將行列錯誤的進行了解析. 這時編譯器是這樣編譯的: 它取出c[x]作為行的首地址,再加上y. 由於c[0]一定是傳入陣列的首地址,所以c[0][y]這樣的訪問都是ok的,只要你不越界. c[1]我們就不知道是個什麼東西了,c[1][y]這樣的訪問就是一個隨機數,當訪問到無法訪問的地方時,程式就會崩潰. 最後的總結: 1.一維陣列和指標可以比較簡單的互換使用 2.二維陣列和雙重指標儘量不要互換使用,除非你真的知道這些底層的編譯原理,並且有十分的把握 相關推薦 iOS開發之應用首次啟動顯示使用者引導 GetPixel取畫素點 python單例模式 二維陣列和雙重指標的轉換及使用 ubuntu修改ls顏色 相關推薦 iOS開發之應用首次啟動顯示使用者引導 GetPixel取畫素點 python單例模式 二維陣列和雙重指標的轉換及使用 ubuntu修改ls顏色 相關閱讀 iOS開發之應用首次啟動顯示使用者引導 GetPixel取畫素點 python單例模式 二維陣列和雙重指標的轉換及使用 ubuntu修改ls顏色 關於黑盒測試用例的設計 topic 科技 教育 python 社會 linux 數碼 java c++ 遊戲 演算法 資料庫 健康 文化 mysql 汽車 娛樂 科學 財經 資料結構 C語言 職場 php oracle c# 作業系統 C 工作 體育 網路 sql



請為這篇文章評分?