我有'Circle'和'Triangle'的结构。我正在尝试创建两个函数指针的并集,指向两个函数,每个函数在两个结构上运行。我认为其余部分应该是自我解释的。
代码如下:
struct Triangle
{
char color;
char shade;
int base;
int height;
};
struct Circle
{
char color;
char shade;
int radius;
};
void drawCircle(struct Circle* x);
float areaCircle(struct Circle* x);
void drawTriangle(struct Triangle *x);
float areaTriangle(struct Triangle* x);
在main()函数中:
typedef union uCircle
{
void(*draw)(struct Circle*);
float(*area)(struct Circle*);
}uc;
typedef union uTriangle
{
void(*draw)(struct Triangle*);
float(*area)(struct Triangle*);
}ut;
uc(*vtc[2])(struct Circle*);
vtc[0].(*draw) = &drawCircle;
vtc[1].(*area) = &areaCircle;
ut(*vtt[2])(struct Triangle*);
vtt[0].(*draw) = &drawTriangle;
vtt[1].(*area) = &areaTriangle;
我得到的错误是:
Structs.c:117:9: error: expected identifier before ‘(’ token
vtc[0].(*draw) = &drawCircle;
Structs.c:118:9: error: expected identifier before ‘(’ token
vtc[1].(*area) = &areaCircle;
^
Structs.c:121:9: error: expected identifier before ‘(’ token
vtt[0].(*draw) = &drawTriangle;
^
Structs.c:122:9: error: expected identifier before ‘(’ token
vtt[1].(*area) = &areaTriangle;
看起来这是一些我似乎无法识别的简单的语法错误。我做错了什么?
答案 0 :(得分:3)
第一件事。 而不是:
uc(*vtc)(struct Circle*);
vtc.(*draw) = &drawCircle;
vtc.(*area) = &areaCircle;
你应该用这个:
uc vtc;
vtc.draw = drawCircle;
vtc.area = areaCircle;
如果您打算通过普通的union变量使用这些函数指针。
第二件事。 请记住,工会一次存储一名成员。
所以,而不是这个
vtc.draw = drawCircle;
vtc.area = areaCircle;
将具有
的效果 vtc.area = areaCircle;
可以访问并覆盖vtc.draw
。
换句话说,在初始化vtc.draw
后访问vtc.area
将导致未定义的行为,并且可能会发生奇怪的事情。
如果您同时需要draw
和area
,请改用结构。
答案 1 :(得分:0)
你的语法错了。指针函数的赋值不使用任何*
代码:
vtc.draw = drawCircle;
你的方法是错误的,包含函数指针的uc
和ut
变量应该是struct
,而不是union
。
我猜你正试图重新发明closures。
您可能希望定义包含函数的结构,即vtable。像
这样的东西struct object;
struct methods_st {
void (*drawer)(struct object*);
double (*area)(struct object*);
};
struct object {
struct methods_st* vtable;
char color, shade;
};
struct circle {
struct object head;
int radius;
};
static void circle_drawer (struct object*oc) {
struct circle*c = (struct circle*)oc;
draw_circle_of_radius (c->radius);
}
static float circle_area (struct object*oc);
static struct method_st circle_vtable = { circle_drawer, circle_area };
如果不够清楚,请查看GTK内的Gobject。