2016-11-23 6 views
0

これは私の2D配列int myarray[79][24];行0の要素を変更すると、同時に別の要素行24が変更され、その逆もあります。C 2D Arrayは同時に2つの要素を変更します

たとえば、myarray[35][0] = 'X';は、myarray[35][0]myarray[34][24]を同時にXに変更します。そして、私がmyarray[40][24] = 'X';を試したときに、それはmyarray[40][24]myarray[41][0]を同時に変更します。

最初の行と最後の行が互いにミラーリングしているようです。これをどうやって止めることができますか?

+1

問題を示す[最小限の完全で検証可能な例](http://stackoverflow.com/help/mcve)を投稿してください。入力、期待される出力、実際の出力の例を示します。 –

答えて

3

仕様:6.5.2.1 Array subscripting

連続添字演算子は多次元配列オブジェクトの要素を指定します。 Eが次元i×j×...×kのn次元配列(n≧2)である場合、E(lvalue以外の として使用される)は(n-1) - 次元j×...×kの2次元配列。単項演算子*がこのポインタに明示的に適用される場合、または添字の結果暗黙的に に適用される場合、結果は参照される(n-1)次元の 配列であり、それは左辺以外の値として使用される場合にはポインタに変換されます。 。配列は行優先順位で格納されます(最後の添字は最も速く変化します)。

Cは、プログラマが多く行うことができる言語です。たとえば、IndexOutOfBoundsErrorはありません。配列は最初のセルへのポインタに過ぎず、配列長の次のセルの予約があります。

int [79] [24]を宣言すると、79 * 24セルの予約が行われます。彼らは一つずつ行く。配列のディメンションが79x24の場合、最初のディメンションでは0〜78、2番目のディメンションでは0〜23のインデックスが使用されます。アドレス34,24のセルは実際には34,23の後に1つあり、メモリの35,0である。

のは、サイズ6x4販売のアレイ上の例を持ってみましょう:

Your array represented as expected by you with values: 
+---+---+---+---+---+---+---+ 
| | 0 | 1 | 2 | 3 | 4 | 5 | 
+---+---+---+---+---+---+---+ 
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 
+---+---+---+---+---+---+---+ 
| 1 | 0 | 0 | 0 | 0 | 0 | 0 | 
+---+---+---+---+---+---+---+ 
| 2 | 0 | 0 | 0 | 0 | 0 | 0 | 
+---+---+---+---+---+---+---+ 
| 3 | 0 | 0 | 0 | 0 | 0 | 0 | 
+---+---+---+---+---+---+---+ 

Your array with cell adresses (where start is the adress of cell 0,0): 
+---+------------+------------+------------+------------+------------+------------+ 
| | 0   | 1   | 2   | 3   | 4   | 5   | 
+---+------------+------------+------------+------------+------------+------------+ 
| 0 | start  | start + 1 | start + 2 | start + 3 | start + 4 | start + 5 | 
+---+------------+------------+------------+------------+------------+------------+ 
| 1 | start + 6 | start + 7 | start + 8 | start + 9 | start + 10 | start + 11 | 
+---+------------+------------+------------+------------+------------+------------+ 
| 2 | start + 12 | start + 13 | start + 14 | start + 15 | start + 16 | start + 17 | 
+---+------------+------------+------------+------------+------------+------------+ 
| 3 | start + 18 | start + 19 | start + 20 | start + 21 | start + 22 | start + 23 | 
+---+------------+------------+------------+------------+------------+------------+ 
1

配列の範囲は、最初のディメンションでは0〜78、2番目のディメンションでは0〜23です。配列の範囲外の要素にアクセスしようとすると、その動作は定義されておらず、何かが起こります。これがあなたの問題を引き起こす可能性があります。インデックス[x] [24]にアクセスしたい場合は、int myarray[79][25]のように配列を宣言する必要があります。

"ミラーリング"は明らかにメモリ内で配列要素が互いに隣り合って配置されているため、非常に長い行のように想像することができます。したがって、たとえば[1][23]のインデックスの直後に(おそらく)インデックス[2][0]があります。それは(おそらく)保証されていないので、そのような構造を使用することは良い考えではありません。それが定義されていても、それは非常に混乱しています。

1

あなたは

int myarray[79][24]; 

int n = myarray[34][24]; 

さにアクセスすると言う定義もののので、配列のためのメモリは、連続しています厳密に範囲外です。

myarray[35][0]にアクセスする可能性がありますが、その動作は未定義です。

+0

myarray [34] [24]は、24個のセルに対して34個のスペースを予約し、次にそれらの24個のセルが割り当てられたスペースと一致するように定義されていると思います。メモリページの切り替えに違った働きをするかもしれませんが、私はそうは思わないでしょう。私はドキュメンテーションを探します。 – xenteros

+0

@xenteros申し訳ありませんが、私はより明確にすべきでした。 'int myarray [79] [24]' int n = myarray [34] [24] 'は厳密には範囲外です。 –

+0

http://open-std.org/JTC1/SC22/WG14/www/docs/n1570.pdf – xenteros

関連する問題