2014-09-25 197 views
-3

我有一個'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

回答

3

第一件事。 取而代之的是:如果你打算通過正常的工會變量來使用這些函數指針

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,請改用結構。

0

您的語法錯誤。指針功能的指定不使用任何*這樣的代碼:

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