geophoenix
c語言程式設計的過程中,不可避免的會碰到二維或二維以上的陣列作為函式的形參的情況,在以前的程式設計過程中,習慣了動態陣列的應用,很是使用直接定義高維陣列。最近在程式設計的過程中就碰到了這個問題:有如下的測試程式:
voidtest(double **x,int row,int col);
voidtest(double **x)
intmain(int argc, char *argv)
編譯時提示cannot convert 'double [*][3]' to double **'。
將呼叫方式強制進行型別轉換:test((double **)x),編譯通過,執行出錯,提示非法越界。
據傳:因為棧上分配的陣列和堆上分配的陣列在記憶體排列上可能不相同
,直接定義的陣列是儲存在程式的堆疊區,資料占用連續的區間;而動態申請的陣列是在系統的遠堆上(
far heap
),除最後一維的元素是連續存放的外,其他維上的元素有可能不是在一塊連續的記憶體區域裡。
//棧上:
int ia[2][2] = ; //4個元素是連續排列的記憶體段
//堆上:
int **p = new int*[2]; //只有每行內是連續排列,各行並不一定連續排列
for ( int i = 0; i < 2; i++ )
for ( int i = 0; i < 2; i++ ) }
所以對棧上的陣列用int **p指向首位址,因為int **p一次解引用為位址指標,而非堆上的指向陣列的指標,所以二次解引用會出錯。
如果找乙個通用方程只能用:
void f( int *p, int row, int col ) //給出陣列的行和列,對堆上的陣列不合適
cout < < endl;
} }
int main();
f( (int*)ia, 2, 2 );
}採用上面的通用辦法還是比較麻煩,這無形中對程式設計增加了難度,為了避免這個麻煩可以採用動態陣列的形式,將原來採用直接定義的陣列全部換成動態陣列,類似開頭例子中被注釋掉的那部分**,當然這樣也有後續的麻煩,動態陣列的生命週期完成後必須釋放記憶體空間,這也有點羅嗦,但是畢竟可以直接使用陣列的形式,比上面的通用方式還是要簡單一點。
如果執意要使用直接定義的陣列該怎麼辦呢?有如下幾種方法:
方法一:
voidtest(double (*x)[3], int row, int col);
呼叫方式:test(x,row,col);
呼叫用方式 test(x,row,col);
方法二:
voidtest(double x[3], int row,int col);
呼叫方式 test(x,row,col);
對於多維陣列作為引數,除第一維之外的其它維必須指定維數,否則是肯定編譯不過去的。
從上面的對直接定義的陣列的引用情況看,直接定義的陣列的使用比較麻煩,一旦直接定義陣列的維數發生變換,函式的定義必須相應的修改,否則程式就會出錯,這也增加了程式進一步開發的麻煩,為了一勞永逸的解決這個問題,建議還是使用動態陣列的方法,雖然需要手工釋放記憶體,但是除卻了後續的麻煩。
二維陣列 作為函式引數
前言 今天在實現裝配線排程程式時候,用到了二維陣列,並將其作為函式的引數。在寫程式的時候,遇到一些問題,即二維陣列做函式的引數應該如何正確表示。我寫程式的錯誤如下程式所示 1 include 2 void print int a 3 3 67intmain 8 10print a 11return0...
linux C 二維陣列 作為函式引數
c語言中怎麼用二維陣列作為函式引數 可以用二維陣列名作為實參或者形參,在被呼叫函式中對形引數組定義時可以指定所有維數的大小,也可以省略第一維的大 明,如 void func int array 3 10 void func int array 10 二者都是合法而且等價,但是不能把第二維或者更高維的...
C 中將二維陣列作為引數的函式
將乙個二維陣列作為引數傳遞到函式中,函式原型中該引數應定義為 列數為4的int型別二維陣列 int a 4 true int a 4 true int a 4 false對上述 的理解 將與前面的型別結合,第一行首先定義了乙個指標a,它指向乙個有4個int元素的陣列,而在另外的部落格裡我們說過,基本...