2014-12-02 75 views
0

我在GTK +中C.寫一個應用程序(戰艦拼圖)我有一個結構shippartGTK2 C - 如何將二維數組結構傳遞給回調函數並更改此數組的值?

typedef enum { 
    water, single, top, bot, mid, left, right, waterU, shipU, unknown 
} shiptype; 

typedef struct { 
    GtkWidget *img; 
    shiptype type; //shiptype is typedef enum 
    shiptype hiddenType; 
} shippart; 

整個地圖是shippart(shippart battlemap[10][10])的二維陣列和我有它宣佈在我的main()。我填寫所有這3個字段,用戶單擊地圖上的單個部分(100箇中的1個)以將其標記爲水或船舶部分。當他想要檢查他的猜測是否正確時,他應該能夠點擊'檢查',如果他的猜測是正確的,他會將他的水印部分更改爲水,船舶標記的部分更改爲如果他做錯了什麼,它會取消它的標記。

一切都很好,直到檢查點。它只是不起作用,我認爲它是由傳遞這個地圖數組引起的。

void buttonCheckHandler(GtkWidget *widget, gpointer user_data) { 
    //this is most likely wrong, I found it somewhere in the other question here 
    //but honestly I tried everything and it just doesn't work 
    shippart * (*map)[MAP_SIZE] = (shippart *(*)[MAP_SIZE])user_data; 

    //this part might be unnecessary 
    int i, j; 
    for(i = 0; i<MAP_SIZE; i++) { 
     for(j = 0; j<MAP_SIZE; j++) { 
      if(map[i][j]->type == waterU) { 
       if(map[i][j]->hiddenType == water) { 
        gtk_image_set_from_pixbuf(GTK_IMAGE(map[i][j]->img), shiptypes[0]); 
        map[i][j]->type = water; 
       } 
       else { 
        gtk_image_set_from_pixbuf(GTK_IMAGE(map[i][j]->img), shiptypes[9]); 
        map[i][j]->type = unknown; 
       } 
       continue; 
      } 
      //... very similar lines to these 11 above 
     } 
    } 
} 

void makeOverlay(shippart map[][MAP_SIZE], (...)) { 
    //... 
    g_signal_connect(G_OBJECT(btnCheck), "clicked", G_CALLBACK(buttonCheckHandler), &map); 
    //... 
} 

int main(int argc, char *argv[]) { 
    shippart battlemap[MAP_SIZE][MAP_SIZE]; 
    fillMap(battlemap); //fills hiddenType's 
    makeUserMap(battlemap); //fills type's with 'unknown' and 2-4 fields with those from hiddenType 
    makeOverlay(battlemap, (...)); //almost everything with gtk 
} 

所以我的問題是:如何正確地從makeOverlay()傳遞這個映射到buttonCheckHandler()?它甚至有可能嗎?我曾經有shippart map[10][10]爲全局變量,它的工作(我buttonCheckHandler是這樣:)

void buttonCheckHandler(GtkWidget *widget, gpointer user_data) { 
    checkMap(); //without parameteres, because it changed global variable 
    //I tried same thing with checkMap(user_data); earlier but it didn't work 
} 

,但我的代碼是相當可怕的閱讀和已瞭解,現在我把事情搞糟了。你可以幫我嗎?

回答

0

二維數組和指針數組之間存在差異(又名破舊二維數組)。

當傳遞2D數組時,它會衰減到指向第一個元素的指針。您可以通過將指針視爲一維數組來訪問數據,但您必須計算索引。

shippart * map = user_data; 

... 

map[i*MAP_SIZE+j].type; 
//or 
(map+i*MAP_SIZE+j)->type; 

至於搞亂了你的源進行大的變化的時候,你應該使用一個版本控制系統。其中最廣泛的(也是原始的)是RCS,它也可以處理單個文件。無論何時您進行更改並使其正確編譯和運行,簽入的來源。隨着RCS,這是

ci -l filename.c 

-l立即提取新的可編輯的文件在檢查之後。然後,如果你做出錯誤的修改,就可以恢復到先前簽入的版本與

ls filename.c,v # <-- before deleting, make sure you actually have a checked-in file 
rm filename.c 
co -l filename.c 
+1

我改變這是你寫的方式,但結果仍然是相同的 - 它不起作用(當我點擊「檢查」時,我的意思是沒有任何變化)。我使用調試器,並在地圖[](在'buttonCheckHandler()')內字面上有廢話。在放置船隻(我打印.type和.hiddenType)後,一切都很好,當你點擊.type中的地圖值時會發生變化,但是'buttonCheckHandler()'沒有任何效果。任何其他想法? – tuptus 2014-12-02 16:40:43