1. 程式人生 > >二級指標和二維陣列詳解(轉)

二級指標和二維陣列詳解(轉)

一個函式形如:

void f(float **p){

/* 想要在函式體中按二維陣列的方式訪問*/

    p[1][1] = 0;//c++用vc編譯ok,執行出錯(非法訪問)

}

float **p; //其實這裡的p並不是一個二位陣列的指標,只不過是一個指向指標的指標

像你這樣訪問肯定是會出問題的。

例如:

float a[2][2]={0,1,2,3};

float **p=(float**)a;//強制將二維陣列指標轉為指向指標的指標

則此時

p[0]=0;

p[1]=1;

p[2]=2;

p[3]=3;

p[0][0]=*(*(p+0)+0)=**p;

p[0][1]=*(*(p+0)+1);

對於p[0][0]:由於*p=0; ====> **p=*(0);引用地址為零的記憶體,必然是錯誤的。

對於p[0][1]=*(*p+1)====>*(4),引用了非法記憶體

同樣,對於p[1][0]=*(1),p[1][1]=*(5),均引用了非法記憶體

所以說,二位陣列並不能簡單的轉換成指向指標的指標。

正確的指向二維陣列的指標應該是:

float a[5][10];

float (*p)[10];//只需要定義為指向第二維的指標,忽略第一維

p=a;

p[0][1]=a[0][1];

二級指標和二維陣列並不等價。

二級指標是一個指向指標的指標

而二維陣列其實就是一個指標,char a[3][4]; a是指向整個二維陣列的首地址。它相當於(char *)[n],並不是char **;

所以不能直接:t=a;

要這樣:t = (char **)a;

我們知道char array[]=”abcdef”; array是陣列的首地址,

那麼在二維陣列中array當然也是陣列的首地址,

看看這個定義char Array[][3] ={“ab“,“cd“,“ef“};

怎麼知道的呢?定義這樣一個數組,在vc除錯視窗中

我們看到:

Array ---------0x64324234

|------Array[0]---0x64324234 “ab“

|------Array[1]---0x64324337 “cd“

|------Array[2]---0x6432433A “ef”

已經很明白了,實際編譯器是這樣實現二維陣列的,實際上Array是“一維指標陣列“的首地址,其中每一個元素指標都對應一個字串,那麼好我們來看看是否可以這樣來使用Array二維陣列.

char **pArray = Array;編譯器提示出錯,怎麼辦呢?加個(char **)試試,仍然出錯,設斷看一下pArray的值和Array的值是相等的,但我們是否可以象使用Array那樣來同樣輸出字串呢?很明顯是不行的,編譯器不會把pArray+i處理成pArray+i*3尋找到第i個指標的地址,而只是簡單的加了一個i.這說明編譯器只做了很簡單的將地址值賦給了pArray,而它實際沒有任何意義.我們不能用它來訪問任何資料.很奇怪嗎?

再來看看這樣定義char *p[] = {“ab“, “cd“, “ef“};定義了一個指標陣列.char **sp = p;這樣的用法經常看到,為什麼這樣就可以使用sp來訪問字串了呢,的確編譯器在編譯的時候識別出了sp是一個指向一維陣列的指標的指標,那麼我們就可以把它做為陣列名來操縱整個陣列了.