在Union(C)中存储函数指针

问题描述:

我有一个'Circle'和'Triangle'的结构。我试图创建两个函数指针的联合,指向在两个结构上运行的两个函数。我认为其余的应该是自我解释。在Union(C)中存储函数指针

的代码如下:

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; 

看起来像这是我似乎无法识别的一些简单的语法错误。我究竟做错了什么?

+2

你为什么试图使用结构这样的联合? Union一次只能存储一个成员。 – askmish 2014-09-25 05:16:16

+1

你打算有'uc(* vtc)(struct Circle *);'声明一个变量'vtc',它是一个函数指针,返回'ut'并把一个指向'struct Circle'的指针作为单个参数?因为那正是你得到的。 *'vtc'和'vtt'都是函数指针。我怀疑这不是你的意图。 – WhozCraig 2014-09-25 05:16:19

+0

由于绘图和区域的函数签名是不同的(void vs float),我不能简单地创建一个函数指针数组(一种类型)。为了使它工作,我试图创建这两个函数指针的联合。这个联合是作为函数指针的类型。 – Prasad 2014-09-25 05:19:44

第一件事。 取而代之的是:如果你打算通过正常的工会变量来使用这些函数指针

uc vtc; 
vtc.draw = drawCircle; 
vtc.area = areaCircle; 

uc(*vtc)(struct Circle*); 
vtc.(*draw) = &drawCircle; 
vtc.(*area) = &areaCircle; 

你应该使用这个。

第二件事。请记住,工会一次只能存储一个成员。

所以,与其这样

vtc.draw = drawCircle; 
vtc.area = areaCircle; 

将有

vtc.area = areaCircle;易于接受和覆盖vtc.draw效果。

换句话说,在初始化vtc.area后访问vtc.draw将导致未定义的行为并且可能发生奇怪的事情。

如果您想同时使用drawarea,请改用结构。

您的语法错误。指针功能的指定不使用任何*这样的代码:

vtc.draw = drawCircle; 

而且你的做法是错误的,包含函数指针的ucut变量应该是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 }; 

东西,如果这是不够清晰,看里面Gobject从GTK。

+0

实际上,函数指针应该位于原始的三角形和圆形结构中。 – Wlerin 2014-09-25 05:20:18

+0

我试了你的方式,得到这个: Structs.c:117:5:错误:请求成员'绘制'的东西不是结构或工会 此外,使用联合是问题定义的一部分 – Prasad 2014-09-25 05:23:03