Как вернуть 2D-массив функции в C? - PullRequest
22 голосов
/ 05 марта 2011

Я программист на Ruby, который закончил разработку кода, генерирующего для C. Это все равно что просить лимузин буксировать грузовик 1960-х годов. В любом случае.

Вот то, что я думал, должно работать, но не работает.

float[][] pixels()
{
  float x[][]= { {1,1},{2,2} };
  return x
}

void drawLine(float x[][2])
{
  //drawing the line
}

//inside main
drawLine(pixels());

Я ударился головой о стол, пытаясь заставить эту штуку работать. Пожалуйста помоги.

Ответы [ 5 ]

25 голосов
/ 05 марта 2011

Бедняжка. В C указатели и массивы тесно связаны. Также вам обычно нужно передавать размер массива в виде отдельной переменной. Начнем с:

#include <stdio.h>

float** createArray(int m, int n)
{
    float* values = calloc(m*n, sizeof(float));
    float** rows = malloc(n*sizeof(float*));
    for (int i=0; i<n; ++i)
    {
        rows[i] = values + i*m;
    }
    return rows;
}

void destroyArray(float** arr)
{
    free(*arr);
    free(arr);
}

void drawLine(const float** coords, int m, int n);

int main(void)
{
    float** arr = createArray(2,2);
    arr[0][0] = 1;
    arr[0][1] = 1;
    arr[1][0] = 2;
    arr[1][1] = 2;
    drawLine(arr, 2, 2); 
    destroyArray(arr);
}
5 голосов
/ 25 апреля 2016
float (*pixels(void))[2] 
{
  static float x[2][2]= { {1,1},{2,2} };
  return x;
}

void drawLine(float (*x)[2])
{
  //drawing the line
  //x[0][0];
}

//inside main
drawLine(pixels());
4 голосов
/ 05 марта 2011

Спасибо всем за ваши ответы и, более конкретно, за подробное объяснение связи между массивом и указателем.

Я инкапсулировал массив в структуру

 struct point_group1 {
        float x[3];
        float y[3];
};

struct point_group1 pixels(){
    struct point_group1 temp;

    temp.x[0] = 0.0;
    temp.x[1] = 1.0;
    temp.x[2] = -1.0;

    temp.y[0] = 0.0;
    temp.y[1] = 1.0;
    temp.y[2] = 1.0;

    return temp;    
}



struct point_group1 points1  = pixels();
axPoly(points1.x, points1.y ,3, 0.0);
3 голосов
/ 05 марта 2011

В C/C++, когда вы передаете массив функции, он исчезает как указатель, указывающий на первый элемент массива.Итак, в функции pixels() вы возвращаете адрес выделенной переменной стека.Адрес возвращаемой переменной больше недействителен, поскольку при возврате pixels() выделенная переменная стека выходит из области видимости.Таким образом, вместо этого вы должны использовать переменную, чье хранение является динамическим (т. Е. Использовать malloc, calloc).

Итак, для двумерного массива вы можете использовать float** arrayVariable;.Кроме того, если вы передаете это функции, вам следует опасаться, сколько у нее строк и столбцов.

int rows, columns;

float** pixels()
{
    // take input for rows, columns
    // allocate memory from free store for the 2D array accordingly
    // return the array
}

void drawLine( float** returnedArrayVariable )
{
  //drawing the line
}

Поскольку двумерный массив сам управляет ресурсами, он должен вернуть ресурсы обратно вбесплатный магазин, используя бесплатно .

1 голос
/ 05 марта 2011

Самым простым способом, вероятно, будет объявление массива float в main и наличие pixels просто для заполнения:

#define PIXEL_X_SIZE 2
#define PIXEL_Y_SIZE 2

int pixels(float x[][PIXEL_X_SIZE], int len) {
    /* I don't know if you want the logic of this method to ever change,
       but this will be roughly equivalent to what you do above */
    if (len < PIXEL_Y_SIZE) {
        /* the length of the passed array is too small, abort */
        return -1;
    }

    x[0][0] = x[0][1] = 1;
    x[1][0] = x[1][1] = 2;
    return 0;
}

void drawLine(float x[][PIXEL_X_SIZE]) {
    /* this will work fine */
}

int main() {
    float pixel_array[PIXEL_Y_SIZE][PIXEL_X_SIZE];
    pixels(pixel_array, PIXEL_Y_SIZE);
    drawLine(pixel_array);
}

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

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