配列とポインターを扱う場合、型の減衰がどのように発生するかを理解することが重要です。 2 次元配列は double ポインターに分解されると予想されるかもしれませんが、常にそうとは限りません。なぜこれが起こるのかを掘り下げ、動作の違いを調べてみましょう。
テスト ケースが示すように、1 次元配列は実際に単一のポインターに減衰します。
<code class="cpp">std::is_same<int*, std::decay<int[]>::type>::value; // true</code>
これは、ポインター演算が単一のポインターで実行できるためです。
ただし、2 次元配列は二重ポインターに減衰しません。 :
<code class="cpp">std::is_same<int**, std::decay<int[][1]>::type>::value; // false</code>
その理由は、ダブル ポインターには配列の次元に関する追加情報が必要であるためです。たとえば、int[5][4] の場合、コンパイラーは各「内部」配列の長さが 4 であることを認識します。 int (*)[4] にキャストするとこの情報が保持され、ポインター演算が可能になります。
ただし、int ** にキャストすると、このディメンション情報が失われます。これは単なるポインタへのポインタになり、意味のあるポインタ演算を実行するには十分ではありません。
次の点を考慮してください:
<code class="cpp">char *tmp = (char *)p // Work in units of bytes (char) + i * sizeof(int[4]) // Offset for outer dimension (int[4] is a type) + j * sizeof(int); // Offset for inner dimension int a = *(int *)tmp; // Back to the contained type, and dereference</code>
このコード配列アクセスを手動で実行し、コンパイラがディメンション情報に依存していることを示しています。 int** はこの情報を提供しないため、ポインター演算には適していません。
1 次元配列は単一のポインターに減衰しますが、多次元配列はダブル ポインターに減衰しません。必要な寸法情報が欠如しているためです。この動作により、単次元ポインターを使用した意味のあるポインター演算が引き続き可能になります。
以上が多次元配列が単次元配列とは異なる方法でポインタに変化するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。