Возможно, вы знаете объектно-ориентированный язык, такой как Java или Python, и теперь вы изучаете язык Си. Разница между 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
где ptr(x)
указывает на адрес памяти x
. Так, в Java board
указывает на адрес памяти, отличный от board[0]
.
Вы говорите, что в C & board выдает тот же адрес памяти, что и & board [0] и & board [0] [0]. Но я могу получить доступ к первому элементу только через плату [0] [0] (или) * доска [0] (или) ** доска. Почему это так?
Хотя выражения &board
и &board[0]
и &board[0][0]
дают один и тот же адрес, система типов языка C не позволяет вам получить доступ к значению char
. В компиляторе C типы (концептуально):
board: type char[3][3]
board[0]: type char[3]
board[0][0]: type char
Предполагая переменную типа 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
Недостатком является то, что такие типы типов могут привести к ошибкам кодирования.