C++における2次元配列を関数パラメータとして


まず、2 D配列には、次の2つの定義があります.
    A. 
int Arr[2][3]={{1,2,3},{4,5,6}};

    B. 
int **Arr=new int* [2];
for(int i=0;i<2;i++)
    Arr[i]=new int[3];
//initialize
for(int i=0;i<2;i++)
    for(int j=0;j<3;j++)
        Arr[i][j]=i*3+j+1;

しかし、2つの方法には重要な違いがあります.方式Aが宣言する2次元配列は行ごとに連続的に格納され、方式Bの各行間は一般的に連続的に格納されません.
例えば、両方の方式は、Arr[i][j]または*(*(Arr+i)+j)によって要素にアクセスすることができるが、方式Aは、以下のような一次元配列のアクセス方式によって要素にアクセスすることができる
*(Arr[0]+i*cols+j)
このアクセス方法は方式Bに対して正しくない.
この性質をA 2次元配列で連続的に格納することで、2次元配列を1次元ポインタに変換して関数パラメータとして使用することができ、良好な拡張性を有する.
1.rows行、cols列を有するA方式で定義された2次元配列Arrが知られている場合、関数Funcのパラメータとして次のように宣言することができる.
void Func(int *A,int rows,int cols){
    for(int i=0;i<rows;i++){//      
        for(int j=0;j<cols;j++)
            cout<<*(A+i*cols+j)<<" ";
        cout<<endl;
    }
}

int main(){
    Func(Arr[0],2,3);//         Arr[0]   Arr!
    return 0;
}

1次元ポインタではなく2次元ポインタを関数パラメータとして利用したいかもしれません.
void Func(int **A,int rows,int cols);
では、参照時にFunc(Arr,2,3);「int(*)[3]タイプの実参加int**タイプのパラメータが互換性がない」というエラーメッセージが表示されます.すなわち、パラメータタイプが一致しません.したがって,方式Aで定義した2次元配列は,上記のように1次元ポインタに変換して関数パラメータとするしかない.2 Dポインタを関数パラメータとして利用する方法は,方式Bに適用される.
2.方式Bで定義された2次元配列は行単位で連続的に記憶されないため、関数パラメータとしては2次元ポインタのみ、すなわち次のように宣言する
void Func(int **A,int rows,int cols){
	for(int i=0;i<rows;i++){
		for(int j=0;j<cols;j++)
			cout<<A[i][j]<<" ";
		cout<<endl;
	}
}

int main(){
    Func(Arr,2,3);
    return 0;
}

以上、2次元配列を関数パラメータとして、まず、二次元配列がそのように定義されている(A or B)ことを明らかにし、それに対応する関数宣言方式を採用する.両関数宣言方式は異なる行列数に対して良好な拡張性を持っている.以上は二次元配列を基礎として議論したが、原理は三次元以上の多次元配列に通じるように広がり、処理方式は同じである.