java Ошибка объявления многомерного массива [duplicate]

Цитирование C11, глава §6.5.3.2:

Унарный оператор * обозначает косвенность. Если операнд указывает на функцию, результат будет обозначать функцию; если он указывает на объект, результатом будет lvalue, обозначающий объект. Если операнд имеет тип '' указатель на тип '', результат имеет тип '' type ''. Если недопустимое значение было присвоено указателю, поведение унарного оператора * не определено.

blockquote>

Таким образом, ваш код вызывает неопределенное поведение .

Также, связанный, из главы §6.2.5:

Тип void содержит пустой набор значений; это неполный тип объекта, который не может быть завершен.

blockquote>

Итак, указатель на void является недопустимым операндом для разыменования.


Один вероятный практический случай и возможное решение

. Иногда для создания дженериков мы бросаем определенный указатель на void *, передаем это как аргумент функции, а затем внутри функции, которую мы выполняем он возвращается к исходному типу, основанному на некоторой известной информации. Это, в соответствии с главой §6.3.2.3, совершенно верно:

[...] Указатель на любой тип объекта может быть преобразован в указатель на void и обратно; результат будет сравниваться с исходным указателем.

blockquote>

Если это ваш случай и вы разыскиваете внутри функции, вы можете наложить указатель на

до разыменования.

357
задан Peter Mortensen 9 July 2015 в 22:30
поделиться

6 ответов

Попробуйте следующее:

int[][] multi = new int[5][10];

... что является короткой рукой для чего-то вроде этого:

int[][] multi = new int[5][];
multi[0] = new int[10];
multi[1] = new int[10];
multi[2] = new int[10];
multi[3] = new int[10];
multi[4] = new int[10];

Обратите внимание, что каждый элемент будет инициализирован по умолчанию значение для int, 0, поэтому вышеупомянутые также эквивалентны:

int[][] multi = new int[][]{
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
687
ответ дан Alexis C. 20 August 2018 в 19:25
поделиться
  • 1
    Самое интересное - вы можете иметь разные столбцы в разных строках. Например: - int [] [] multi = new int [5] []; multi [0] = новый int [10]; multi [1] = new int [6]; multi [2] = new int [9] также отлично – JavaTec 9 March 2016 в 22:25
  • 2
    @JavaTec, если мы хотим жестко кодировать значение, с другим столбцом, как мы должны это делать? – Muneeb ul Hassan 28 August 2016 в 04:46
  • 3
    Hi Muneeb, если я правильно понял, вы спрашиваете в многомерном массиве с разным размером столбца для каждой строки, как назначать значения. Вот как: int [] [] multi = new int [] [] {{1,2,3}, {1,2,3,4}, {1}}; и вы можете получить доступ к ним / напечатать их так: for (int i = 0; i & lt; multi.length; i ++) {for (int j = 0; j & lt; multi [i] .length; j ++) {System.out.println ( & quot; row: & quot; + i + ":" + j + "значение:" + multi [i] [j]); }} – JavaTec 31 August 2016 в 17:39
  • 4
    Нужно ли использовать new int[][] в =new int[][]{...} варианте? Можем ли мы написать ={...}? – Nawaz 25 May 2017 в 07:56
  • 5
    @Nawaz Нет, массивы являются объектом в Java, а память выделяется объектам только с помощью ключевого слова new. – roottraveller 13 June 2017 в 09:40
int rows = 5;
int cols = 10;

int[] multD = new int[rows * cols];

for (int r = 0; r < rows; r++)
{
  for (int c = 0; c < cols; c++)
  {
     int index = r * cols + c;
     multD[index] = index * 2;
  }
}

Наслаждайтесь!

4
ответ дан Albeoris 20 August 2018 в 19:25
поделиться
  • 1
    Это было бы полезно на языке, который не поддерживает 2D-массивы, такие как C! – Alaa 29 September 2014 в 17:34
  • 2
    C поддерживает многомерные массивы. – Ricardo Cruz 17 May 2015 в 19:30
int [][] twoDim = new int [5][5];

int a = (twoDim.length);//5
int b = (twoDim[0].length);//5

for(int i = 0; i < a; i++){ // 1 2 3 4 5
    for(int j = 0; j <b; j++) { // 1 2 3 4 5
        int x = (i+1)*(j+1);
        twoDim[i][j] = x;
        if (x<10) {
            System.out.print(" " + x + " ");
        } else {
            System.out.print(x + " ");
        }
    }//end of for J
    System.out.println();
}//end of for i
6
ответ дан axierjhtjz 20 August 2018 в 19:25
поделиться

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

int marks[][]={{50,60,55,67,70},{62,65,70,70,81},{72,66,77,80,69}};

Здесь int представляет собой элементы целочисленного типа, хранящиеся в массиве, и имя массива - «метки». int является типом данных для всех элементов, представленных внутри скобок «{» и «}», потому что массив представляет собой набор элементов, имеющих один и тот же тип данных.

Возвращаясь к нашему заявлению, написанному выше: каждая строка элементов должна быть записана внутри фигурных скобок. Строки и элементы в каждой строке должны быть разделены запятыми.

Теперь посмотрите на инструкцию: вы можете получить 3 строки и 5 столбцов, поэтому JVM создает 3 * 5 = 15 блоков памяти , Эти блоки могут быть индивидуально обозначены как:

marks[0][0]  marks[0][1]  marks[0][2]  marks[0][3]  marks[0][4]
marks[1][0]  marks[1][1]  marks[1][2]  marks[1][3]  marks[1][4]
marks[2][0]  marks[2][1]  marks[2][2]  marks[2][3]  marks[2][4]

ПРИМЕЧАНИЕ. Если вы хотите сохранить элементы n , то индекс массива начинается с нуля и заканчивается на n- 1 . Другой способ создания двумерного массива состоит в том, чтобы сначала объявить массив, а затем выделить для него память, используя новый оператор.

int marks[][];           // declare marks array
marks = new int[3][5];   // allocate memory for storing 15 elements

Объединив два выше, мы можем написать:

int marks[][] = new int[3][5];
64
ответ дан informatik01 20 August 2018 в 19:25
поделиться

Наиболее распространенная идиома для создания двумерного массива с 5 строками и 10 столбцами:

int[][] multD = new int[5][10];

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

int[][] multD = new int[5][];
for (int i = 0; i < 5; i++) {
  multD[i] = new int[10];
}
25
ответ дан João Silva 20 August 2018 в 19:25
поделиться
  • 1
    Также поймите, что только примитивы не требуют инициализации. Если вы объявите массив как Object[][] ary2d = new Object[5][10];, вы все равно должны инициализировать каждый элемент 2D-массива. – Armand 5 March 2014 в 02:28
  • 2
    Если вы не будете обращаться с футляром null безопасно для любых не примитивов. Независимо от того, нужно ли инициализировать каждый элемент, вы полностью зависите от своего дизайна. Кроме того, просто для уточнения - примитивы не могут быть нулевыми и получать экземпляр к определенному значению по умолчанию, если оно не назначено вами. Например. int не может быть нулевым, и если вы скажете int i; без присвоения значения, используется значение по умолчанию для 0. Читайте об этом здесь – indivisible 3 May 2014 в 06:21
  • 3
    Еще одно уточнение, значения по умолчанию передаются только переменным класса / экземпляра. Локальные переменные (внутри методов) должны быть инициализированы вручную перед использованием. – indivisible 3 May 2014 в 06:33

Эти типы массивов называются зубчатыми массивами в Java:

int[][] multD = new int[3][];
multD[0] = new int[3];
multD[1] = new int[2];
multD[2] = new int[5];

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

 int[][] multD = {{2, 4, 1}, {6, 8}, {7, 3, 6, 5, 1}};

Вы можете легко перебирать все элементы в вашем массиве:

for (int i = 0; i<multD.length; i++) {
    for (int j = 0; j<multD[i].length; j++) {
        System.out.print(multD[i][j] + "\t");
    }
    System.out.println();
}
41
ответ дан Peter Mortensen 20 August 2018 в 19:25
поделиться
  • 1
    Хорошо сказано! Это самый важный аспект самостоятельной инициализации. – Ahamed 24 December 2013 в 21:00
  • 2
    Это правильный ответ в любом случае – Pythoner 21 September 2016 в 19:51
  • 3
    @Victor как насчет int array[][] = new int[3][]; VS int array[][] = new int[][3]; ?? который является законным, поскольку я читал обе версии где-то. – roottraveller 13 June 2017 в 09:39
Другие вопросы по тегам:

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