目次
1. 2次元配列
まず最初に、2 次元配列とポインター変数の間の関連概念をいくつか理解する必要があります。
二次元配列:
整数配列 [ 3 ][ 5 ]
1 次元配列と同様にメモリに連続的に格納され、各要素の差分は同じです。たとえば、x86 環境では、2次元配列の隣接する各要素の差分は 4 バイトです。
ただし、2 次元配列の特殊性により、通常は 2 次元配列を行列形式で出力します。
ただし、1 次元配列とは異なり、1 次元配列の先頭アドレスは最初の要素のアドレスですが、2 次元配列の先頭アドレスは最初の行のアドレスです。
2 次元配列の各行は 1 次元配列であり、この 1 次元配列は 2 次元配列の要素とみなすことができます。
したがって、2 次元配列は 1 次元配列の配列と考えることもできます。
この場合、int arr[3][5] は1 次元配列とみなされ、配列名は arr[3] になります。
2. ポインタの配列
(1) コンセプト
まず、ポインタの配列は配列であり、その配列には同じ型のポインタ変数、つまりアドレスが格納されます。
整数配列と同様に、整数変数は整数配列に格納され、文字配列は文字型変数を文字配列に格納します。
ポインタ変数には、int*、char*、short* など、さまざまな種類があります。そのため、ポインタ配列にもさまざまな種類があります。
(2) 書き方
int*parr[6]:
parr 配列名
int* は、配列に格納されているアドレスが指す要素の型が int であり、これらのアドレスの型も int* であることを示します
[6]はポインタ配列のサイズを示します。
(3) ポインタ配列は 2 次元配列をシミュレートします。
このうち、arr1、arr2、arr3は配列名を表し、配列名は配列の先頭要素のアドレスを表し、ポインタに相当します。
int * は、ポインター配列内のポインター変数の型を表します。
また、2 次元配列の特性により、parr[ i ] は配列名として表現できます。
配列名を記述するもう 1 つの方法は *(arr+i) です。ここで、arr は配列名を表し、i はトラバーサルを表します。
そして、 parr[ i ] == *( parr + i ) なので
したがって、parr[ i ][ j ] の別の書き方: *( *(parr+i)+ j ) ここで、 *(parr+i) は配列名、 j はトラバーサルです。
3. 配列ポインタ
(1) コンセプト
まず第一に、以前にポインター配列について学習したことがあり、ポインター配列は配列であり、ポインターを格納する配列であることを認識する必要があります。
配列ポインタは、配列のアドレスを格納する配列へのポインタです。
例えば:
int arr[10];
int(* p)[10] = &arr;
その前に、配列のアドレスを理解しましょう。
1 次元配列の研究を通じて、arr で表される配列名は配列の最初の要素のアドレスとしても表され、&arr は配列全体のアドレスを表すことがわかりました。
次に、ポインタの知識に従って、arr を int * で、&arr を int(*) で表すことができます [10]。
上に示したように、配列全体のアドレスはポインタ変数 p に格納されます。
(2) 配列ポインタを使用して 1 次元配列を出力する
(*p)[ i ] このうち (*p) は配列名として表現できる、理由は &arr = int (*p)[10] ポインタ変数 p に配列全体のアドレスを与え、は、p が変換用の &arr であることと同等です ( *p) = (*&arr) ここで、 * と & は互いに打ち消し合うため、 (*p) は配列名と同等です。
不十分 上記の書き方は推奨しません。
下の写真の書き込みの方が一般向けです。
(3) 2次元配列のパラメータ受け渡しをシミュレートする
仮定:
int arr[3][5] = {
{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
上記は 2 次元配列ですが、2 次元配列を呼び出してパラメータを渡す必要がある場合は、その行番号と列番号を一緒に渡す必要があります。
test(arr,3,5)//传参
void test (int arr[3][5],int r,int c)//传参调用
ただし、配列ポインターを使用して 2 次元配列パラメーターの受け渡しをシミュレートする場合、知識を理解する必要があります。
2次元配列の先頭アドレスは1行目のアドレスであり、2次元配列は1次元配列から構成される。
あるいは、2 次元配列の各行は 1 次元配列の配列アドレスとして表現できるとも言えます。
その後、次のように発展する可能性があります。
int arr0[5] = {1,2,3,4,5};
int arr1[5] = {2, 3, 4, 5, 6};
int arr2[5] = {3, 4, 5, 6, 7};
int arr3[] = {&arr0, &arr1, &arr2};
&arr0、&arr1、&arr2は、それぞれ二次元配列arr[3][5]の各行の配列アドレスを表します。
そして、2 次元配列 arr[ 3 ][ 5 ] (arr[ 3 ] は配列名に相当します) であることがわかります。
したがって、パラメータによる呼び出しは次のように記述できます。
void test ( int(*arr)[ 5 ], int r, int c )//传参调用
(* arr )[ 5 ] は、少し前までは (*p)[ i ] と同等で、2 次元配列の各行を 1 次元配列として扱い、arr と p は両方とも 1 次元配列全体のアドレスです。次元配列の場合、2 つは同じ意味になります。
違いは、 (* arr ) が 1 行目のアドレスを表し、印刷時に 2 行目と 3 行目のアドレスに到達するために内部をトラバースする必要があることです。
したがって、 *(arr+i) は配列名を表し、arr[ i ][ j ] 内の arr[ i ] を表します。
そしてhttp://t.csdn.cn/c6Q6Hでは、 arr[ i ] は *(arr+i) と書くことができるという書き方を学びました。ここで、 arr は配列名を表します。
したがって、このシミュレーションに導入すると、arr[i][j] を *(*(arr+i)+j) と書くことができます。ここで、*(arr+i) と arr[i] は配列名です。
最後に、2 次元配列のパラメーター受け渡しシミュレーションは次のように記述できます。