2011-03-05 71 views
18

我是一位Ruby程序員,他最終爲C開發了一個代碼生成程序。它就像要求豪華轎車拖着一輛20世紀60年代的卡車一樣。任何方式。如何將二維數組返回給C中的函數?

這是我認爲應該工作,但不工作。

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

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

//inside main 
drawLine(pixels()); 

我在我的辦公桌上敲了一下頭,試圖讓這件事情奏效。請幫忙。

+4

這您可能感興趣http://stackoverflow.com/questions/4570366/pointer-to-local-variable – jweyrich

+0

似乎是什麼問題? –

+0

@SOE閱讀Mahesh的回答,瞭解問題所在。 –

回答

4

非常感謝大家的回答,並且更具體地說明了陣列指針關係的詳細解釋。

我封裝在一個結構數組

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

這是一個非常好的解決方案,請注意,如果這些是大型數組,並且您的編譯器不擅長優化,那麼最終可能會創建不必要的副本。 – user470379

1

最簡單的方法很可能將被宣佈在主要的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); 
} 

您還可以使用mallocfree並存儲在堆上的像素,但如果這像素陣列將會變得更大,實際上沒有必要,它只是增加了額外的複雜性,以確保您的內存始終得到正確分配和釋放。

+0

你的做法很好。我感到唯一的擔憂是,由於我們的應用程序有望在嵌入式設備上運行,因此代碼審查清單要求儘量減少全局變量。該代碼將具有數百像素像功能。 –

+0

@Akshar我沒有使用任何全局變量......我定義了一些事情,但是如果你真的想要你可以在任何地方重複2,但是你可以隨時爲自己設置一個很大的維護頭痛如果有人得到新的大小錯誤,這些值的變化和/或非常難以調試錯誤。 – user470379

20

你可憐的東西。在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); 
} 
+0

我只是嘗試了這段代碼 - snippetand得到了:「錯誤:無效轉換從'void *'到'float *'」在createArray.You需要添加一個強制轉換:「float * values =(float *)calloc m * n,sizeof(float));「 ..同樣的浮動** – Alex

+1

@Alex你可能編譯它就好像它是C++代碼?它是有效的C和無效的C++。 – aschepler

2

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 
} 

因爲,二維數組管理資源它自己,它應該返回的資源回用免費自由存儲區。

+0

我想你想讓我在像素函數裏面使用malloc。然後我需要記住要釋放它。 –

1
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()); 
+0

您有唯一正確的答案!太糟糕了,你沒有解釋任何事情。如果你已經添加了一些解釋,請隨時向我發送評論,如果我認爲它很好,我會檢查並確認。 – Olaf

相關問題