что такое 'интервал *userMask[3][4]', указывающий?

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

22
задан razlebe 20 July 2011 в 11:45
поделиться

9 ответов

Короткий ответ

Данный userMask объявляется, поскольку

int *userMask[3][4];

тогда userMask имеет тип int*[3][4]. Это - 2-й массив указателей на интервал. Размер внешнего размера равняется 3, размер внутреннего размера равняется 4. Действительно это - не что иное как с 3 элементами 1d массив, какой тип элемента - другой с 4 элементами 1d массив, который тип элемента int*.

Steps объяснил

Поэтому, если Вы делаете

userMask[2][maskElement][user]

тогда по существу с первыми двумя индексами, Вы выбираете конкретный указатель из 2-го массива:

int * p = userMask[2][maskElement];

тогда Вы выбираете интервал, где-нибудь смещает от того указателя путем выполнения

p[user]

теперь, когда код - все в userMask[2][maskElement][user].

Допустимый Код C

, Чтобы сделать это шаг за шагом с допустимым кодом c (не волнуются, не понимаете ли Вы еще все в следующем):

int * userMask[3][4] = { { 0 } };
int ** pa = userMask[2]; /* int*[4] becomes int** implicitly */
int * pi = pa[maskElement];
int i = pi[user];

assert(i == userMask[2][maskElement][user]);

Различие между Массивами и Указателями

, Таким образом, я думаю, что показываю Вам что-то важное. Массив выше делает не , содержат указатели на массивы. Позволяет взгляду, как отличающийся они ведут себя, который не ожидают многие c программисты:

int array[5][4][3];
/* int[4][3] implicitly converts to int(*)[3] (pointer to first element) */
int (*parray)[3] = array[0]; 
int ** pint = (int**) array[0]; /* wrong!! */

Теперь, что произойдет, если мы сделаем parray[1] и pint[1]? Первое усовершенствует парирование на [1 112] байты (3 * sizeof(int)), второе усовершенствует на [только 1 114] байты. Таким образом, на самом деле, в то время как первое дает Вам корректный массив array[0][1], второе даст Вам ( char * )array[0] + sizeof( int* ), который является где-нибудь, мы действительно не хотим, чтобы он был. Но захват неправильного смещения не является всем об этом. Поскольку это не знает, что к массиву получают доступ, это попытается интерпретировать то, что в [1 117] как int*. Скажите, что Ваш массив был инициализирован с [1 119]. Тогда это сделает следующий индексный шаг, базирующийся от адреса 0x00 (Выполнение pint[1][0], например). О, noes - совершенно неопределенное поведение! Таким образом, действительно важно подчеркнуть различие.

Заключение

Это было больше, чем Вы попросили, но я думаю, что довольно важно знать эти детали. Особенно, если Вы хотите передать 2-е массивы функциям тогда, это знание действительно полезно.

36
ответ дан Lii 29 November 2019 в 03:40
поделиться

Это - двухмерная антенная решетка, где каждый элемент является указателем на int, и все указатели инициализируются для обнуления.

В Вашем продолжении, Вы показываете, что массив используется как это:

if(userMask[2][maskElement][user] && blah)
    result = true;

В этом случае, каждый элемент в userMask должен на самом деле указать на массив int с. (int* может указать на сингл int или массив int с. Для определения этого проверьте код, который присваивает значения userMask. Например, возможно записать:

int userArray[2] = { 10, 20 };

userMask[0][0] = userArray; // userMask[0][0] points to the
                            // first element of userArray.

Тогда следующие индексы кода в [1 110]:

int value = userMask[0][0][1]; // sets value = userArray[1], giving 20.
17
ответ дан ChrisN 29 November 2019 в 03:40
поделиться
int *userMask[3][4] = {0};

2-мерный массив, где каждый участник является указателем на интервал Кроме того, все участники инициализируются к нулевым указателям.

int (*userMask)[3][4];

был бы указатель на 2-мерный массив ints. Скобки в C связывают более трудный, чем *, таким образом, круглая скобка необходима для создания указателя на массив.

cdecl простая утилита, которую можно загрузить для объяснения сложных объявлений:

cdecl> explain int *userMask[3][4]
declare userMask as array 3 of array 4 of pointer to int

Это может также сделать противоположное:

cdecl> declare userMask as pointer to array 3 of array 4 of int
int (*userMask)[3][4]
10
ответ дан Robert Gamble 29 November 2019 в 03:40
поделиться
if(userMask[2][maskElement][user] && blah)
   result = true;

вторая часть здесь - то, что нет никаких массивов в C; существует только адресная арифметика с указателями. По определению, p[i] всегда эквивалентно *(p+i), таким образом

userMask[2][maskElement][user]

эквивалентно

*((userMask[2][maskElement])+user)

, код где-нибудь присваивает вектор (я поставил деньги, которые это от malloc (3c) или подобный вызов) к указателю в том массиве; теперь Ваш, если говорит

, ЕСЛИ пользовательский-th элемент вектора в userMask[2][maskElement] ненулевой

ТОГДА, ЕСЛИ вздор ненулевой (из-за & & оценка короткого замыкания, второе соединенное не становится оцененным, если первое соединенное 0)

ТОГДА результат набора = верно.

3
ответ дан Charlie Martin 29 November 2019 в 03:40
поделиться

Примените вывернутое наизнанку правило.

int *userMask[3][4] = {0};

Запуск в innerpost части объявления,

userMask

является именем

userMask[3] 

, выделяет место для (вектор), 3 из них

userMask[3][4] 

выделяют место для 4 userMask[3]

int *

, говорит нам, что userMask объекты являются указателем типа на int

, и затем = {0} инициализатор, где все элементы 0. Так

int *userMask[3][4] = {0};

3x4 массив интервала *, инициализирован к 0.

2
ответ дан Charlie Martin 29 November 2019 в 03:40
поделиться

Я думаю, что оператор получает доступ к третьей строке массива usermask, затем получает доступ к maskElement'th указателю в той строке, и так как это - международный указатель, это может указать на начало международного массива (думайте символьные строки), который я предполагаю, что это делает, и тот массив подындексируется пользователем.

0
ответ дан Cameron 29 November 2019 в 03:40
поделиться

помогает, читаете ли Вы его как это:

type variablename[array_spec];

в этом случае: интервал* usermask[3][4];

, таким образом, это - матрица int*.

теперь, так как c не дифференцируется между указателем и массивами, можно использовать индексацию массива на указателях.

int* i;
int the_int_behind_i = *(i+1);
int also_the_int_behind_i = i[1];

Этому нужно i для указания на область, где несколько ints выстроены в линию друг позади друга, конечно, как массив.

Примечание, что индексный оператор [] используемый в последних примерах похож на array_spec в первом, но эти два очень отличаются.

Так: [пользователь] userMask [2] [maskElement]

выборы usermask указатель, сохраненный в [2] [maskElement], и, оценивает его для пользователя пользователь

0
ответ дан JK. 29 November 2019 в 03:40
поделиться

userMask[2] имеет тип int*[],
userMask[2][maskElement], имеет тип int*,
и таким образом userMask[2][maskElement][user] имеет тип int.

, объявление

int *userMask[3][4] = {0};

является стенографией для [1 113]

int *userMask[3][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};

, где каждый из нулей неявно преобразовывается в (int*)0.

0
ответ дан pdc 29 November 2019 в 03:40
поделиться

Это - матрица, где каждый элемент является указателем.

, Если бы это указывало на матрицу размера [3] [4], код был бы

int userMask[3][4]={0};
-1
ответ дан martjno 29 November 2019 в 03:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: