Подтвердить что ты не робот

Как вернуть 2D-массив функции в C?

Я программист 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());

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

4b9b3361

Ответ 1

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

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

 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);

Ответ 2

Ты бедная. В 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);
}

Ответ 3

В 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
}

Так как 2D-массив сам управляет ресурсами, он должен вернуть ресурсы обратно в свободное хранилище, используя бесплатно.

Ответ 4

Самый простой способ - это объявление массива float в основном и 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 и хранить пиксели в куче, но если это будет тем больше, чем будет располагаться массив пикселей, нет необходимости, и это просто добавляет дополнительную сложность, чтобы убедиться ваша память всегда правильно распределяется и освобождается.

Ответ 5

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());