GTK2 C - 如何将二维数组结构传递给回调函数并更改此数组的值?
问题描述:
我在GTK +中C.写一个应用程序(战舰拼图)我有一个结构shippart:GTK2 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
我改变这是你写的方式,但结果仍然是相同的 - 它不起作用(当我点击“检查”时,我的意思是没有任何变化)。我使用调试器,并在地图[](在'buttonCheckHandler()')内字面上有废话。在放置船只(我打印.type和.hiddenType)后,一切都很好,当你点击.type中的地图值时会发生变化,但是'buttonCheckHandler()'没有任何效果。任何其他想法? – tuptus 2014-12-02 16:40:43