withSortTableRows
の配列になるように定義しました。その識別子は現在、配列として固定されており、他の目的には使用できません。次に、それを型として使用してポインターを宣言しようとしています (私は思います)。int の配列へのポインターを宣言する場合は、次のようにします。ints
int SortTableRows[20]
int *SortTableRowsPtr;
SortTablesRowPtr = SortTablesRows;
2 番目の質問では、2 次元配列として扱っているポインターへのポインターに値を代入していますが、これはコンパイラーにとって実質的な違いはありません (ただし、このコンテキストでは意味がありません)。多次元配列は、1 次元配列と同じように線形にメモリに格納されます。配列typedef
の型を定義してから、それへの初期化されていないポインタを作成し(これにより が作成されますint **
)、有効なものを指しているかのようにアクセスします(これはコンパイルされますが、確実にクラッシュします)。
これを機能させるには、20 個の int の配列を定義してから、それを指す必要があります。
SortTablesRows table[10] = {}; // equivalent to int table[10][20];
SortTablesRowPtr = table;
これは、20 個の int の配列へのポインターを宣言しているためです。つまり、
int (*SortTablesRowPtr)[20];
この回答を拡張しました。ステップバイステップでより簡単に説明するのに役立ちます。3 行 10 列のテーブルを考えてみましょう。それは定義されています:
int table[3][10];
次に、このテーブルへのポインタを設定できます。2 次元であるため、これは正しくありません。
int *ptr = table; // wrong - incompatible pointer
ただし、これは 2 行目 (および最初の列) を指します。
int *ptr = table[1];
つまり、10 個の int の配列へのポインターが必要です。つまり、型を指すポインターが必要ですint n[10]
。これを行うには、次のように記述できます。
int (*ptr2)[10] = table;
ptr2
を使用して、ポインター、配列、またはその両方としてテーブルに直接アクセスできるようになりました。現状では、最初の行と最初の列を指しています。1 つ追加するptr2
と、次の行が選択されます。
ptr2[1][3] = 3; // change row 2, column 4
(*(ptr2 + 1))[4] = 10 // row 2, column 5 (yuck)