2011-03-22 82 views
2

我正在處理C中的宏,試圖模擬objet行爲,但使用C和我有一個定義從宏中的另一個結構中的結構定義的變量的問題。這是我的代碼...它的工作原理:宏中結構的問題定義

#include <stdio.h> 
#include <stdlib.h> 

#define STACK_MAX_CAPACITY 10 
#define DECLARE_STACK(Type)        \ 
    typedef struct MetaPile_##Type;      \ 
                 \ 
    typedef struct Pile_##Type_t{      \ 
     Type q[STACK_MAX_CAPACITY];      \ 
     int pos;          \ 
    } Pile_##Type;          \ 
                 \ 
    typedef struct MetaPile_##Type_t{     \ 
     void (* push) (Pile_##Type* p, Type val);  \ 
     void (*init) (Pile_##Type* p);     \ 
    } MetaPile_##Type;         \ 
                 \ 
    void init_##Type(Pile_##Type* p){     \ 
     p->pos = 0;          \ 
     int i;           \ 
     for(i=0; i<STACK_MAX_CAPACITY; i++){   \ 
      p->q[i]=0;         \ 
     }            \ 
    }             \ 
                 \ 
    void push_##Type(Pile_##Type* p, Type val) {  \ 
     if(p->pos < STACK_MAX_CAPACITY){    \ 
      p->q[p->pos]=val;       \ 
      p->pos++;         \ 
     }            \ 
    }             \ 
    MetaPile_##Type TheMetaPile_##Type;     \ 
    void initTheMetaPile_##Type(){      \ 
     TheMetaPile_##Type.init = &init_##Type;   \ 
     TheMetaPile_##Type.push = &push_##Type;   \ 
    }             \ 
                 \ 

DECLARE_STACK(int) 

int main(){ 

    int i; 

    initTheMetaPile_int(); 
    Pile_int pi; 

    TheMetaPile_int.init(&pi); 

    push_int(&pi, 2); 
    push_int(&pi, 3); 
    push_int(&pi, 4); 
    push_int(&pi, 5); 
    push_int(&pi, 6); 

    for(i=0; i<STACK_MAX_CAPACITY; i++){ 
     printf("%d",pi.q[i]); 
    } 

    return 0; 
} 

第一結構定義DINAMIC類型感謝的數組,表示一個客體的attributs方宏(樁_ ##型),以及其他結構(MetaPile_ ## Type),通過函數指針來管理objet的「方法」。 init函數作爲構造函數並初始化我的「objet」pi。

現在我想要在Pile _ ##類型中引用一個類型爲MetaPile _ ## Type(稱爲示例myClass)的變量,以便能夠使pi-> myClass-> push並調用功能push_int。但是,當我做:

typedef struct Pile_##Type_t{      \ 
    Type q[STACK_MAX_CAPACITY];      \ 
    int pos;          \ 
    MetaPile_##Type myClass;      \ 
} Pile_##Type;          \ 

我有一個misunderstandable錯誤...

D:\main.c|40|warning: useless keyword or type name in empty declaration| 
D:\main.c|40|error: syntax error before "MetaPile_int"| 
D:\main.c|40|warning: no semicolon at end of struct or union| 
D:\main.c|40|warning: type defaults to `int' in declaration of `Pile_int'| 
D:\main.c|40|warning: data definition has no type or storage class| 
D:\main.c|40|error: syntax error before '*' token| 
D:\main.c|40|error: syntax error before '*' token| 
D:\main.c|40|error: syntax error before '*' token| 
D:\main.c||In function `init_int':| 
D:\main.c|40|error: `p' undeclared (first use in this function)| 
D:\main.c|40|error: (Each undeclared identifier is reported only once| 
D:\main.c|40|error: for each function it appears in.)| 
D:\main.c|40|error: syntax error before '*' token| 
D:\main.c||In function `push_int':| 
D:\main.c|40|error: `p' undeclared (first use in this function)| 
D:\main.c|40|error: `val' undeclared (first use in this function)| 
D:\main.c||In function `main':| 
D:\main.c|47|error: syntax error before "pi"| 
D:\main.c|49|error: `pi' undeclared (first use in this function)| 
||=== Build finished: 12 errors, 4 warnings ===| 

我不知道做什麼用myClass相關聯的確定指標worong,我使用*也不過錯誤persits 。謝謝,如果有人可以幫助。

+0

哇,是創建模板的C方式嗎?至少可怕...:S – 2011-03-22 22:16:19

回答

4

你的問題不是宏的用法,這隻會分散你的注意力。

typedef struct MetaPile_int; 

只是在語法上不正確。一個struct的一個簡單的向前聲明如下:

struct MetaPile_int; 

但如果你只是想使您的生活更輕鬆做到這一點是這樣的:

typedef struct MetaPile_int MetaPile_int; 

這是struct和的向前聲明標識符MetaPile_int的定義在同一時間。

爲了得到它的工作,首先嚐試它沒有把它放在宏中。或者使用一個編譯器,幫助您跟蹤宏中的錯誤,例如clang。

+0

@Jens ...謝謝!是的你是對的,實際上我在我的代碼中有一些關於我的結構的不好的定義。我改變了他們。由於U表示前向聲明必須是struct MetaPile ## Type,並且我必須使用相同的結構MetaPile ## Type語法來定義此類型的任何變量。謝謝!! – jomaora 2011-03-22 22:31:48

2

刪除typedef struct MetaPile_##Type;行 - 那應該做什麼(除了導致你的錯誤,那是)?

+0

@Erik ...我做到了,但錯誤仍在繼續。其實我認爲我不能刪除這一行,因爲它是struct MetaPile _ ## Type的前向聲明;這是後面定義的一些行。 – jomaora 2011-03-22 21:50:29

+1

@jomaora:刪除該typedef後,您的代碼在這裏編譯沒有錯誤。而且,如果你需要一個前向聲明(你不需要),你可以使用'struct MetaPile _ ## Type_t;'不是一個不完整的typedef。 – Erik 2011-03-22 21:52:56

+0

@Erik ...在這裏不起作用... :(刪除或更改我的定義爲struct MetaPile _ ## Type_t ;.:S – jomaora 2011-03-22 22:03:33

0

您嘗試聲明之前插入一個完整的結構(MetaPile_##Type),改變它們的順序一樣,[在MetaPile_##Type你只用指針Pile_##Type_t,和指針的大小已知]: 編輯: 這個聲明適用於我:

#define DECLARE_STACK(Type)        \ 
    struct Pile_##Type_t;      \ 
                 \ 
    typedef struct MetaPile_##Type_t{     \ 
     void (* push) (Pile_##Type_t* p, Type val);  \ 
     void (*init) (Pile_##Type_t* p);     \ 
    } MetaPile_##Type;         \ 
                 \ 
    typedef struct Pile_##Type_t{      \ 
     Type q[STACK_MAX_CAPACITY];      \ 
     int pos;          \ 
    MetaPile_##Type myClass;      \ 
    } Pile_##Type;          \ 
                 \ 
    void init_##Type(Pile_##Type* p){     \ 
     p->pos = 0;          \ 
     int i;           \ 
     for(i=0; i<STACK_MAX_CAPACITY; i++){   \ 
      p->q[i]=0;         \ 
     }            \ 
    }             \ 
                 \ 
    void push_##Type(Pile_##Type* p, Type val) {  \ 
     if(p->pos < STACK_MAX_CAPACITY){    \ 
      p->q[p->pos]=val;       \ 
      p->pos++;         \ 
     }            \ 
    }             \ 
    MetaPile_##Type TheMetaPile_##Type;     \ 
    void initTheMetaPile_##Type(){      \ 
     TheMetaPile_##Type.init = &init_##Type;   \ 
     TheMetaPile_##Type.push = &push_##Type;   \ 
    }             \ 
                 \ 

它應該做的工作。

+0

Hi @MByD,謝謝。很好地交換錯誤留下的聲明。我添加一個變量MetaPile _ ##輸入樁_ ##類型...我沒有看到你的代碼。 – jomaora 2011-03-22 22:06:32

+0

@ jomaora,當然,忘了補充說... – MByD 2011-03-22 22:08:41