GTK2 C - 如何将二维数组结构传递给回调函数并更改此数组的值?

问题描述:

我在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 
} 

,但我的代码是相当可怕的阅读和已了解,现在我把事情搞糟了。你可以帮我吗?

二维数组和指针数组之间存在差异(又名破旧二维数组)。

当传递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