2011-12-29 3 views
7

У меня есть следующий фрагмент кода:Два одномерные массивы и указатели

char board[3][3] = { 
        {'1','2','3'}, 
        {'4','5','6'}, 
        {'7','8','9'} 
        }; 

printf("address of board : %p\n", &board); 
printf("address of board[0] : %p\n", &board[0]); 

Оба printf() отчетности все печатают то же значение: 0x0013ff67

  1. По моим сведениям, доска (то есть) имя массива представляет адрес первого подмашины (то есть) board[0] и

  2. board[0] Репрезентации ЭНЦ адрес первого элемента в первом массиве (т.е.) board[0][0]

Почему я получаю один и тот же адрес во всех моих printf() заявления? Я ожидаю разные адреса для обоих заявлений.

Я довольно новичок в этом и не понимаю этого поведения. Пожалуйста, просветите меня.

ответ

1

По моим сведениям, доска (то есть) имя массива представляет собой адрес первой подрешетки (т.е.) плату [0]

Это только справедливо, если board используется вне этих контекстов

  • Как операнд & оператора
  • в качестве операнда sizeof

Если это применимо, выражение board представляет массив и сохраняет тип массива (char[3][3]). Применение к нему оператора & приводит к получению адреса массива, который, конечно, равен адресу его первого элемента, просто имеющего другой тип (char(*)[3][3] вместо char(*)[3]). То же, что и в отношении массива board, верно в отношении его первого вспомогательного массива board[0].

Когда вы используете его вне этих контекстов, вы получаете адрес первого элемента (подмассива в вашем случае). Этот адрес не является объектом, а просто значением. Значение не имеет адреса, но объекты имеют. Попытка применить & к ней не удалась. Например,

Обратите внимание, что все сказанное выше относится к C; не обязательно к C++.

+0

Привет, спасибо за ваш ответ, и я частично понимаю. Можете ли вы предоставить простую примерную программу, объясняющую ваш комментарий. Я бы очень помог. Спасибо. – intex0075

+0

@intex ваш вопрос * есть * простая примерная программа, которую я бы предоставил. –

5

Хотя это 2D-массив, внутри памяти он будет представлен как линейный массив. поэтому, когда вы говорите, board [0] [0], он все еще указывает на первый элемент в этом линейном массиве и, следовательно, на тот же адрес памяти.

1

Конечно, это напечатает тот же адрес.
Подумайте о 2D массивов, как это ни на минуту,

INT ** PTR;


Адрес *ptr делает равным &(**ptr).

Потому что в основном, это то, что делает ваш код.

и помните, что в памяти 2D-массивы будут отображаться линейно.

1

Возможно, вы знаете объектно-ориентированный язык, такой как 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 

где ptr(x) указывает на адрес памяти x. Итак, в Java board указывает на другой адрес памяти, чем board[0].


Вы говорите, что в C, & плата дает тот же адрес памяти, как & платы [0] и & доски [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 

Недостатком является то, что такие броски типа может привести к кодирования ошибок.

+0

Вы говорите, что на C, и доска дает тот же адрес памяти, что и доски [0] и & board [0] [0]. Но я могу получить доступ к первому элементу только с помощью платы [0] [0] (или) * платы [0] (или) **. Почему это так?? – intex0075

Смежные вопросы