繁体   English   中英

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

[英]GTK2 C - how to pass 2D array of structures to callback function and change this array's values?

我正在用C的GTK +编写一个应用程序(战舰难题)。我有一个结构shippart

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()声明了它。 我填写了所有这三个字段,用户单击了地图的单个部分(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数组和指针数组(又称衣衫2的 2D数组)之间有区别。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM