Как вернуть 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());
Я ударился головой о стол, пытаясь заставить эту работу работать. Пожалуйста помоги.
Ответы
Ответ 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());