C/C++言語の2次元配列を関数とするパラメータのまとめ
4572 ワード
一、ケース1:実パラメータは2次元配列である.1
二、ケース2:実パラメータはポインタ配列である.1
三、ケース3:実パラメータは配列ポインタである.2
四、ケース4:実相は二次元ポインタである.2
五、まとめ3
5.1単一降格3
5.2実質:伝達指針4
C/C++言語の2次元配列を関数とするパラメータのまとめ
一、ケース1:実相は二次元配列
例えばint a[3][3];
呼び出し形式print(a);
//ポインタ形式
二、ケース2:実相はポインタ配列
たとえば
呼び出し形式print(a);
//ポインタ形式
三、ケース3:実相は配列ポインタ
例えばint(*a)[3];
int b[3][3] = {0};
a = b;
呼び出し形式print(a);
//ポインタ形式
四、ケース4:実相は2 Dポインタ
たとえば
呼び出し形式print(a);
//ポインタ形式
五、まとめ
シーケンス番号
実パラメトリック形式
2 D配列int a[3][3];
ポインタ配列int*a[3];
配列ポインタint(*a)[3]
2 Dポインタint**a;
1
void print(int** a);
ⅹ
√
ⅹ
√
2
void print(int* a[3]);
ⅹ
√
ⅹ
√
3
void print(int (*a)[3]);
√
ⅹ
√
ⅹ
4
void print(int a[3][3]);
√
ⅹ
√
ⅹ
5
void print(int a[4][3]);
√
ⅹ
√
ⅹ
6
void print(int a[3][4]);
ⅹ
ⅹ
ⅹ
ⅹ
7
void print(int a[][3]);
√
ⅹ
√
ⅹ
8
void print(int a[][]);
ⅹ
ⅹ
ⅹ
ⅹ
9
void print(int a[3][]);
ⅹ
ⅹ
ⅹ
ⅹ
備考:√は呼び出しに成功したことを示す.xは呼び出しに失敗したことを示す.
表から、次のことがわかります.
(1)1と2の形式は完全に等価である.
(2)3,4,5,7の形式は完全に等価である.
(3)8と9は不正な形式に属する
(4)4,5,6,7を通過することによって、分かる:
伝達配列では、低次元次数が一致することが必要です.6必然的に不法である.
高次次元の次元については関数に渡されず,象徴的な意味での表示であり,実際の意味はない.
5.1単一降順
配列は毎回ポインタに下げることができますが、毎回1回しか下げられません.毎回の関数呼び出しに対して順次1級下がるしかなく、何度も下がると必ずエラーを報告する.すなわち,2次元配列については配列ポインタで値を伝えることができるが,2次元ポインタで渡すとエラーが報告される.
5.2実質:伝達指針
実パラメトリックパラメータ間で伝達される実質:常に伝達されるのはポインタであり、配列ではないことを覚えておいてください.
2 D配列の実パラメータの場合、パラメータが渡されると、配列ポインタになります.形式パラメータの[]では、変換するたびにポインタの1つしか変換できません.変換後のポインタが、実パラメータに渡されたポインタと一致すると、パラメータ間でパラメータの転送ができます.
--------------------------------------------------------------------
PS:本当に2次元ポインタを渡すときは、2次元配列の次元も考慮する必要があります.
例えば、int a[10];正しい関数パラメータ形式はvoid print(int*a,int n)であるべきである.
2 Dポインタも同じです.3 Dポインタも.以上の知識を身につけて、パラメータを正確に伝えることができれば、問題ではないはずです.
二、ケース2:実パラメータはポインタ配列である.1
三、ケース3:実パラメータは配列ポインタである.2
四、ケース4:実相は二次元ポインタである.2
五、まとめ3
5.1単一降格3
5.2実質:伝達指針4
C/C++言語の2次元配列を関数とするパラメータのまとめ
一、ケース1:実相は二次元配列
例えばint a[3][3];
呼び出し形式print(a);
//ポインタ形式
void print(int** a); //ERROR
void print(int* a[3]); //ERROR; , ;
void print(int (*a)[3]); //OK
//
void print(int a[3][3]); //OK void print(int(*a)[3]);
void print(int a[4][3]); //OK void print(int(*a)[3]);
void print(int a[3][4]); //ERROR void print(int(*a)[4]);
void print(int a[][3]); //OK void print(int(*a)[3]);
void print(int a[][]); //ERROR , void print(int** a);
void print(int a[3][]); //ERROR , void print(int (*a)[3]);
// ; ,
二、ケース2:実相はポインタ配列
たとえば
int* a[3]
int b[3][3] = { 0 };
for(int i = 0; i < 3; ++i){ a[i] = b[i]; }
呼び出し形式print(a);
//ポインタ形式
void print(int** a); //OK
void print(int* a[3]); //OK
void print(int (*a)[3]); //ERROR
//
void print(int a[3][3]); //ERROR void print(int (*a)[3]);
void print(int a[4][3]); //ERROR void print(int(*a)[3]);
void print(int a[3][4]); //ERROR void print(int(*a)[4]);
void print(int a[][3]); //ERROR void print(int(*a)[3]);
void print(int a[][]); //ERROR void print(int** a);
void print(int a[3][]); //ERROR ; ,
三、ケース3:実相は配列ポインタ
例えばint(*a)[3];
int b[3][3] = {0};
a = b;
呼び出し形式print(a);
//ポインタ形式
void print(int** a); //ERROR
void print(int* a[3]); //ERROR
void print(int (*a)[3]); //OK
//
void print(int a[3][3]); //OK void print(int(*a)[3]);
void print(int a[4][3]); //OK void print(int(*a)[3]);
void print(int a[3][4]); //ERROR void print(int(*a)[4]);
void print(int a[][3]); //OK void print(int(*a)[3]);
void print(int a[][]); //ERROR void print(int**a);
void print(int a[3][]); //ERROR ; ,
四、ケース4:実相は2 Dポインタ
たとえば
int** a;
int b[3][3] = { 0 };
int* c[3];
for(int i = 0; i < 3; ++i){ c[i] = b[i]; }
a = c;
呼び出し形式print(a);
//ポインタ形式
void print(int** a); //OK
void print(int* a[3]); //OK void print(int** a);
void print(int (*a)[3]); //ERROR
//
void print(int a[3][3]); //ERROR void print(int(*a)[3]);
void print(int a[4][3]); //ERROR void print(int(*a)[3]);
void print(int a[3][4]); //ERROR void print(int(*a)[4]);
void print(int a[][3]); //ERROR void print(int(*a)[3]);
void print(int a[][]); //ERROR void print(int**a);
void print(int a[3][]); //ERROR ; ,
五、まとめ
シーケンス番号
実パラメトリック形式
2 D配列int a[3][3];
ポインタ配列int*a[3];
配列ポインタint(*a)[3]
2 Dポインタint**a;
1
void print(int** a);
ⅹ
√
ⅹ
√
2
void print(int* a[3]);
ⅹ
√
ⅹ
√
3
void print(int (*a)[3]);
√
ⅹ
√
ⅹ
4
void print(int a[3][3]);
√
ⅹ
√
ⅹ
5
void print(int a[4][3]);
√
ⅹ
√
ⅹ
6
void print(int a[3][4]);
ⅹ
ⅹ
ⅹ
ⅹ
7
void print(int a[][3]);
√
ⅹ
√
ⅹ
8
void print(int a[][]);
ⅹ
ⅹ
ⅹ
ⅹ
9
void print(int a[3][]);
ⅹ
ⅹ
ⅹ
ⅹ
備考:√は呼び出しに成功したことを示す.xは呼び出しに失敗したことを示す.
表から、次のことがわかります.
(1)1と2の形式は完全に等価である.
(2)3,4,5,7の形式は完全に等価である.
(3)8と9は不正な形式に属する
(4)4,5,6,7を通過することによって、分かる:
伝達配列では、低次元次数が一致することが必要です.6必然的に不法である.
高次次元の次元については関数に渡されず,象徴的な意味での表示であり,実際の意味はない.
5.1単一降順
配列は毎回ポインタに下げることができますが、毎回1回しか下げられません.毎回の関数呼び出しに対して順次1級下がるしかなく、何度も下がると必ずエラーを報告する.すなわち,2次元配列については配列ポインタで値を伝えることができるが,2次元ポインタで渡すとエラーが報告される.
5.2実質:伝達指針
実パラメトリックパラメータ間で伝達される実質:常に伝達されるのはポインタであり、配列ではないことを覚えておいてください.
2 D配列の実パラメータの場合、パラメータが渡されると、配列ポインタになります.形式パラメータの[]では、変換するたびにポインタの1つしか変換できません.変換後のポインタが、実パラメータに渡されたポインタと一致すると、パラメータ間でパラメータの転送ができます.
--------------------------------------------------------------------
PS:本当に2次元ポインタを渡すときは、2次元配列の次元も考慮する必要があります.
例えば、int a[10];正しい関数パラメータ形式はvoid print(int*a,int n)であるべきである.
2 Dポインタも同じです.3 Dポインタも.以上の知識を身につけて、パラメータを正確に伝えることができれば、問題ではないはずです.