2016-06-30 2 views
1

Я пытаюсь создать глобальный 2D массив целых чисел в C, но я не совсем уверен, как это сделать. Для массива 1D, вы можете просто положитьСоздание глобального 2D-массива неизвестного размера в C

int numbers[]; 

, но, очевидно, вы не можете оставить две скобки пустыми, как

int numbers[][]; 

Так как я могу это сделать? Я не уверен в легком пути.

Спасибо!

+1

Вы не можете объявить 'int numbers [];' без инициализатора для компилятора, чтобы определить, насколько он большой. Как вы планируете инициализировать 2D-массив? – dbush

+0

Два наиболее распространенных способа сделать это - использовать 1-мерный массив, а затем вычислить индекс, например 'i + j * inner_len', или использовать массив указателей или указатель на блок указателей. Вы также можете сделать указатель на неизвестные массивы размера, но будьте осторожны, если вы это сделаете. Вы должны использовать круглые скобки, такие как 'int (* numbers) [];', и тогда вы действительно не можете делать 'numbers [i]', потому что sizeof (int []) не является надлежащим размером внутреннего массива, поэтому вы должны либо вычислять смещения по-разному, либо отбрасывать в правильный полный тип, например '((int (*) [inner_len])). – hacatu

+0

Вы не можете сделать это с помощью массивов. длина массива должна быть известна во время компиляции. То, что вы ищете, это список какого-то рода. –

ответ

-1

Для этого вам понадобится указатель на int. C не имеет двухмерного массива bultin, но у вас есть способы обойти это. У вас есть два варианта здесь:

симулировать 2D массив через вспомогательную функцию

либо вы симулировать 2-ое измерение; Я предлагаю вспомогательную функцию для этой цели, что-то вроде:

int getTwoDimensionArray(int ** array, int rowSize, int x, int y) 
{ 
    return (*array)[x + y*rowSize]; 
} 

void setTwoDimensionArray(int ** array, int rowSize, int x, int y, int value) 
{ 
    (*array)[x + y*rowSize] = value; 
} 

Пусть говорят, что вы хотите, чтобы выделить массив 5x7 динамически, вы будете использовать эти функции, как, например:

Сначала выделить массив 1D:

int * myArray = (int*) malloc(5*7); 

После того, как вы бы установить значение 10 в положении х = 2, Y = 2, как, что setTwoDimensionArray (& myArray, 5, 2, 2, 10);

И позже, если вы хотите получить обратно значение: INT значение = getTwoDimensionArray (& MyArray, 5, 2, 2);

Есть массив массивов так имитации 2D-массиву

int getTwoDimensionArray(int ** array, int rowSize, int x, int y) 
{ 
    return (*array)[x][y]; 
} 

void setTwoDimensionArray(int ** array, int rowSize, int x, int y, int value) 
{ 
    (*array)[x][y] = value; 
} 

Распределение массива массива:

int ** myArray = (int**) malloc(5); 
for (int i=0; i<5; ++i) 
{ 
    myArray[i] = (int*) malloc(7); 
} 

Вы бы использовать вспомогательные функции так же, как вы делали с вариант № 1

setTwoDimensionArray(&myArray, 5, 2, 2, 10); 
int value = getTwoDimensionArray(&myArray, 5, 2, 2); 

C++

Конечно, если вы можете использовать C++, у вас есть больше возможностей, см Multidimensional Containers in C++

+0

вопрос читает UNKNOWN SIZE –

+0

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

+0

Неизвестный имеет определение скважины ... его просто неизвестно. BTW Я не дал этого -1 –

0

Для построения 2D-массива, идея состоит в том, чтобы создать сплющенных 2D массива(таким образом, 1D-массив). Это фактически означает, что все столбцы будут помещаться горизонтально, один за другим. Вам нужно будет вычислить индекс для доступа к элементам.

Предположим, что в вашем массиве будет N строк и M столбцов. Вы не можете объявить его как:

int numbers[N][M]; 

Что вы можете сделать, это объявить его как:

int numbers[N*M]; 

так что ваши элементы будут находиться в диапазоне [0, N * M-1]. Затем, вы можете получить доступ к любому элементу массива с использованием индекса:

i*M + j;  

0 <= i <= N-1 где и 0 <= j <= M-1.


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

int **numbers; 

Затем выделить память для 2D-структуры:

int i; 
numbers = malloc(N*sizeof(int *));  // N is the number of the rows 
if (numbers == NULL) 
    return; 
for (i = 0 ; i < N ; i++) 
{ 
    numbers[i] = malloc(M*sizeof(int));  // M is the number of the columns 
    if (numbers[i] == NULL) 
     return; 
} 

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


Наконец, основываясь на ваш вопрос, позвольте мне отметить, что вы не можете объявить:

int numbers[]; 

как компилятор должен указание знать размер.

+0

malloc возвращает указатель на void, вам нужно указать malloc на нужный тип указателя, если компилятор не является таким умным. –

+1

@SaeidYazdani см. Эту ссылку о том, почему не бросать результат 'malloc': http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Marievi

+0

Хорошо знать. это может не вызвать проблем. Но я все равно продолжу выдачу результата malloc! –