Java や Python などのオブジェクト指向言語を知っていて、現在は C 言語を学んでいる場合もあるでしょう。考えたときの Java と C の違いchar board[3][3]
は、C ではboard
変数がメモリ内で隣接するメモリ アドレスにある 9 文字として表されることです。そのようです:
board: 1 2 3 4 5 6 7 8 9
C では、および と&board
同じメモリ アドレスが生成されます。&board[0]
&board[0][0]
これとは対照的に、Java では変数は次のように宣言されchar[][] board
、そのメモリ表現は概念的に次のようになります。
board: ptr(A) ptr(B) ptr(C)
A: 1 2 3
B: 4 5 6
C: 7 8 9
whereptr(x)
は のメモリアドレスを指しますx
。したがって、Java では、 はboard
とは異なるメモリ アドレスを指しますboard[0]
。
C では、&board は &board[0] および &board[0][0] と同じメモリ アドレスを生成します。しかし、最初の要素には、board[0][0] (または) *board[0] (または) **board 経由でのみアクセスできます。なんでそうなの??
式&board
and&board[0]
とは同じアドレスを生成しますが、C 言語の型システムにより、値&board[0][0]
にアクセスできません。char
Cコンパイラでは、型は(概念的に)次のとおりです。
board: type char[3][3]
board[0]: type char[3]
board[0][0]: type char
type の変数を想定すると、次のchar
ように記述できます。
char c;
c = board[0][0];
しかし、書くことはできません:
char c;
c = board; // Error
c = board[0]; // Error
割り当ての左側の型が右側の型と互換性がないためです。
アドレスが を指していることが確実な場合はchar
、型キャストを使用できます。
char c;
c = *(char*)board; // Works OK
c = *(char*)board[0]; // Works OK
欠点は、そのような型キャストがコーディングのバグにつながる可能性があることです。