6

私はCのポインターに関するいくつかの記事を読み始めましたが、理解できない例が1つあります。

例はここからです:http://en.wikibooks.org/wiki/C_Programming/Pointers_and_arrays

ここにあります:

少し違う問題を見てみましょう。2次元配列が必要ですが、すべての行を同じ長さにする必要はありません。私たちが行うことは、ポインターの配列を宣言することです。以下の2行目は、Aをポインターの配列として宣言しています。各ポインタはフロートを指します。適用可能なコードは次のとおりです。

float  linearA[30];
 float *A[6];

 A[0] = linearA;              /*  5 - 0 = 5 elements in row  */
 A[1] = linearA + 5;          /* 11 - 5 = 6 elements in row  */
 A[2] = linearA + 11;         /* 15 - 11 = 4 elements in row */
 A[3] = linearA + 15;         /* 21 - 15 = 6 elements        */
 A[4] = linearA + 21;         /* 25 - 21 = 4 elements        */
 A[5] = linearA + 25;         /* 30 - 25 = 5 elements        */

 A[3][2] = 3.66;          /* assigns 3.66 to linearA[17];     */
 A[3][-3] = 1.44;         /* refers to linearA[12];           
                             negative indices are sometimes useful.
                             But avoid using them as much as possible. */

私の質問は、配列の名前が最初のメンバーへのポインターであるため、なぜA[0]5つの要素のみへのポインターであり、のすべてへのポインターではないのかということです。linearA

そしてA[1] = linearA + 5;、同じ理由で、6つの要素が連続していますか?の6番目のメンバーへのポインタではないA[1]はずlinearAですか?

誰かが私の間違いはどこにあるのか説明できますか?

4

5 に答える 5

3

いくつかの例外を除いて、Cでは、配列名は配列の最初の要素へのポインターに変換されます。linearAは、次の式の配列30ですfloat

A[0] = linearA;

へのポインタに変換されますfloat

Aへのポインタの配列6ですfloat。の要素はA、へのポインタ型floatです。配列へのポインタではなく、へのポインタもそうA[0]です。float

また、CではaA[i][j]と同等です(ポインタを逆参照してaを*(A[i] + j)生成します)。A[i][j]floatfloatfloat

于 2013-03-20T21:58:22.990 に答える
1

A[0]の最初の要素へのポインタですlinearA。は連続した配列であるため、このポインタは実際には、適切なオフセットを追加することによりlinearA、30個の要素のいずれかにアクセスできます。linearAただし、このコードでは、配列内のさまざまなオフセットを指すことにより、2D配列をエミュレートしますlinearA。その結果、2Dのような配列アドレス指定が行われます。n番目の行A[n]の場所(つまり、のオフセット)に移動し、この行内のm番目の要素に移動します。linearAA[n][m]

于 2013-03-20T22:03:17.373 に答える
1

これは、この行が6つのポインターの配列を設定しているためfloatです。

float *A[6];

そして、この行は、それらのポインターの最初のものを30の最初の要素に設定します。

A[0] = linearA; 

したがって、Aの各要素は、元の配列のサブセクションを指します。ただし、それらを割り当てる必要があります。最初はランダムなアドレスを指します。

最初のアドレスは初期アドレス(&linearA[0])で、次の5つは次のアドレスです。これらは、に関してアクセス可能A[0][0]ですA[0][5]。配列がポインタに対応する方法のため、30を超えない限り、上昇し続けることができます。

A[n]ただし、配列の任意の部分に割り当てることができます。元の配列の一部である限り、そのメンバーと次の5つ(または必要な数)を指します。

たとえば、をポイントA[1]すると&linearA[6]、効果的に2次元配列を設定できます(1つに似ていますが、1つとしては動作しません)。

于 2013-03-20T22:12:58.447 に答える
1

私の質問は、配列の名前が最初のメンバーへのポインターであるため、A [0]が5つの要素のみへのポインターであり、linearAのすべてへのポインターではない理由です。

配列の最初のfloatであり、ポインタであるため、アドレスの一部を指すようにA[0]設定します。したがって、配列が開始する場所を指し、配列が終了する場所の概念がない5つの要素のみへのポインタではありません。linearAA[0]A[0]

そして、A [1] = linearA + 5; 同じ理由で、6つの要素が連続していますか?A [1]はlinearAの6番目のメンバーへのポインターであると想定されていませんか?

yesA[1]は6番目の要素を指しますが、前に述べたようにその開始アドレスです。

于 2013-03-20T22:18:17.643 に答える
1

投稿した例は、 Iliffeベクトルと呼ばれるやや難解な手法を示しています。これはCでジャグ配列を実装する1つの可能な方法です。ジャグ配列は、各行の長さが異なる行列です。

Cでは配列は1次元であるため、linearAすべての要素を含む単一の配列を作成します。これは、それぞれ異なるサイズの行のシーケンスとして解釈されます。ポインタ配列Aには、各行の最初の要素へのポインタが含まれており、行と列のインデックスを使用して要素にアクセスできます。

このコードは、Cポインターと配列のいくつかの興味深い機能を表示します。

linearA + 5

ポインター演算:ポインター(または配列)に整数を追加すると、元のポインターの後にn個の要素を指すポインターが得られます。

A[3][2] = 3.66;

This nice syntax allows you to think of this structure as a two-dimensional matrix.

Also, and this is probably the main point of the example, pointers and arrays are interchangeable. Here, A[3] is a pointer to float, since A was defined as an array of pointers to floats; appending [2] gives us the element 2 places after the one pointed by the original pointer. This is similar to the pointer arithmetic above, only in this case the pointer is dereferenced. Actually, array access is defined in terms of pointers so X[5] is equivalent to *(X+5).

A[3][-3]

This shows that there is nothing stopping you from accessing an element outside of a given row. In this case, you are accessing the element 3 places before the one pointed by A[3]. This is something that is rarely needed, and it only works in this case because you built the matrix to have contiguous elements. Usually, accessing elements outside the allocated range of an array will crash your program.

Finally, to answer your question:

And A[1] = linearA + 5; is 6 elements in a row -- for the same reason? Isn't A[1] supposed to be a pointer to the 6th member of linearA?

As pointers and arrays are interchangeable, A[1] is both a pointer to the sixth element in linearA and an array starting from the sixth element in linearA. There is nothing in the language saying that the latter is 6 elements long, you have to implement that logic in your code.

于 2013-03-20T23:06:26.033 に答える