Создайте двумерный целочисленный массив, используя одномерный массив - PullRequest
0 голосов
/ 25 января 2019

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

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

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Чтобы реализовать массив с R строками и C столбцами с элементами типа T, можно выделить память с помощью:

T *MyArray = malloc(R * C * sizeof *MyArray);
if (!MyArray) ReportError…

Затем можно получить доступ к элементу в строке r и столбце c с помощью:

MyArray[r*C + c] = NewValue; // Set element [r, c] to NewValue.

T Value = MyArray[r*C + c]; // Get value of element [r, c].

Можно освободить память с помощью:

free(MyArray);

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

#include <stdio.h>
#include <stdlib.h>


typedef int T;

typedef struct { T *A; size_t R, C; } Array2D;


void ReportError(void)
{
    fprintf(stderr, "Error, something went wrong.\n");
    exit(EXIT_FAILURE);
}

// Create a 2D array.
Array2D CreateArray2D(size_t R, size_t C)
{
    Array2D X = { malloc(R * C * sizeof *X.A), R, C };
    if (!X.A) ReportError();
    return X;
}


// Destroy a 2D array, releasing its memory.
void DestroyArray2D(Array2D X)
{
    free(X.A);
}


// Set the value of an element in a 2D array.
void SetArray2DElement(Array2D X, size_t r, size_t c, T x)
{
    X.A[r*X.C + c] = x;
}


// Get the value of an element in a 2D array.
T GetArray2DElement(Array2D X, size_t r, size_t c)
{
    return X.A[r*X.C + c];
}

// Get a pointer to an element in a 2D array.
T *GetArray2DReference(Array2D X, size_t r, size_t c)
{
    return &X.A[r*X.C + c];
}


// Example use.
int main(void)
{
    Array2D A = CreateArray2D(3, 4);

    for (size_t r = 0; r < 3; ++r)
        for (size_t c = 0; c < 4; ++c)
            SetArray2DElement(A, r, c, 10*r + c);

    // Show how to use reference.
    for (size_t i = 0; i < 3; ++i)
        *GetArray2DReference(A, i, i) = 100*i;

    for (size_t r = 0; r < 3; ++r)
    {
        for (size_t c = 0; c < 4; ++c)
            printf(" %3d", GetArray2DElement(A, r, c));
        printf("\n");
    }
}

Большинство реализаций C поддерживают массивы переменной длины, которые можно использовать для реализации двумерных массивов. Если вас не волнует возможность использовать код в реализациях C, которые не поддерживают это, вы можете использовать:

T (*MyArray)[C] = malloc(R * sizeof *MyArray);
if (!MyArray) ReportError…

Затем вы можете получить доступ к элементу в строке r и столбце c с помощью:

MyArray[r][c] = NewValue;

T Value = MyArray[r][c];
0 голосов
/ 25 января 2019

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

int **make2D(int c, int r) {
    int **arr;
    arr = malloc(c*sizeof(&c)); // Note &c is just the size of an integer pointer.
    for (int i = 0; i < c; i++) {
        arr[i] = malloc(r*sizeof(r)); // Note r is just the size of an integer
    }
    return arr;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...