Как создать многомерный массив, размерность которого основана на переменной в C? - PullRequest
0 голосов
/ 12 февраля 2019

По сути, я хочу иметь возможность ввести размер n в терминале и создать соответствующий массив nD.

В настоящее время я могу создать только одномерный массив с размеромсоответствующий массив nD.

Ответы [ 3 ]

0 голосов
/ 12 февраля 2019

Используйте указатели на указатели / двойные указатели (**).Для массива nD вы повторяете процесс динамического выделения (malloc) n раз в цикле и ссылаетесь каждый с указателем на вновь выделенный массив.Единственная проблема заключается в том, что последний массив не использует двойные указатели, поэтому ваш код времени выполнения должен знать, когда использовать значения вместо двойных указателей в последнем измерении.Используя это, вы все равно можете выполнить установку / получение с помощью обычного синтаксиса, например M[1][2][3][1] = 5; (учтите, что 0 - это первый элемент!).

Также убедитесь, что инициализирует ваши значения.

Хороший пример и трактат о указателях с двумя массивами можно найти в «Языке программирования C» от ​​Kerningham / Richie, который легко доступен онлайн.

Примечание: есть и другие элегантные и не очень элегантныерешения этого.Например, используя макросы / метапрограммирование для написания кода распределения во время компиляции и передачи опции define (-DDIMS=4) или структур данных с возможностью вложения, представляющих массивы, подобные деревьям (см. Литературу по классической структуре данных для многомерных массивов.)

0 голосов
/ 13 февраля 2019

Вы можете установить размер массива во время выполнения, используя VLA.Массивы переменной длины являются частью C99.Так что это будет работать только с C99 или выше.Хотя C11 имеет VLA в качестве опции, все основные компиляторы поддерживают его.

Допустим, вы хотите, чтобы пользователь вводил размер двумерного массива из терминала.

#include <stdio.h>

int main(void)
{
   unsigned int row1, col1;

   printf("%s", "Enter number of rows and columns in a 2-D array: ");
   int row1, col1; // number of rows and columns in a 2-D array
   scanf("%u %u", &row1, &col1);

   int array2D[row1][col1]; // declare 2-D variable-length array

}

array2d является2D массив объявлен во время выполнения.Затем просто напишите код ниже, чтобы использовать его.

В ранних версиях C sizeof всегда выполнялась операция во время компиляции, но при применении к VLA sizeof работает во время выполнения.Напечатает количество байтов в VLA:

0 голосов
/ 12 февраля 2019

Вы не можете, число измерений массива является частью типа, поэтому его нужно знать во время компиляции.Вы можете сделать простую математику, чтобы отобразить то, что вы хотите, в массив 1d.

Пример:

Пусть размеры = 3

  • w: 4
  • h: 8
  • d: 16

Код:

int* data = (int*)malloc(sizeof(int) * w * h * d);
int x = access(1,2,3);  //it will map to location: 1 + 2 * (4) + 3 * (4 * 8)
free(data);


int access(int x, int y, int z){
   return data[x + y * (w) + z * (h * w)];
}

Общая реализация может выглядеть следующим образом

int numDimensions;
printf("Enter number of dimensions:");
scanf("%d", &numDimensions);
int* dimensionSizes = (int*)malloc(sizeof(int) * numDimensions);

//Read each dimension's size
int totalElements = 1;
for(int i = 0; i < numDimensions; ++i){
    printf("Enter size for dimension %d:", i);
    scanf("%d", &dimensionSizes[i]);
    totalElements *= dimensionSizes[i];
}

//allocate 1d array
int* data = (int*) malloc(sizeof(int) * totalElements);

//Read the coordinates you want to store data to
int* position = (int*)malloc(sizeof(int) * numDimensions);
for(int i = 0; i < numDimensions; ++i){
    printf("Enter location in dimension %d:", i);
    scanf("%d", &position[i]);
}

//Read the value you want to store
int value;
printf("Enter value for that position:");
scanf("%d", &value);

//Write the data to the calculated 1d location
data[to1d(position, dimensionSizes, numDimensions)] = value;

int to1d(int* position, int* dimensionSizes, int numDimensions){
    int multiplier = 1;
    int position1d = 0;
    for (int i = 0; i < numDimensions; ++i){
        position1d = position1d + position[i] * multiplier;
        multiplier = multiplier * dimensionSizes[i];
    }
    return position1d;
}
...