維尼的蜂巢

RealTime??!! It’s amazing!!!!

C的巨集使用技巧1 三月 28, 2006

Filed under: VC++/C++/C — kevinlin @ 9:15 下午

其實在寫遊戲時巨集還蠻需要的因為比較方便,很多C++的書都說用inline來取代C語言底層的巨集,不過這種說法都太片面了,沒有考慮到巨集的一些獨特的功能。就本質上來說,巨集只是對編譯器的前置處理器做一些指示,做一些比較smart的text的替換的工作。所以他最嚴重的問題是出在這邊,他不會檢查類型或者其他的安全性的檢查,所以開發人員會增加不少麻煩。但是只要遵守著一條原則就可以避免,那就是不要用巨集來建立有函式功能的行為或著常數。

下面介紹一下幾個使用巨集的技巧:

1. 把列舉值轉換成字串
#define CaseEnum(a)   case(a): LogMsgToFile(#a, id, time)
switch( msg_passed_in )
{
  CaseEnum( MSG_YouWereHit );
    ReactToHit();
    break;

  CaseEnum( MSG_GameReset );
    ResetLogic();
    break;
}

上面這個經過編譯器的處理後 會變成下面這樣
switch( msg_passed_in )
{
  CaseEnum( MSG_YouWereHit );
    LogMsgToFile(“MSG_YouWereHit “, id, time);
    ReactToHit();
    break;

  CaseEnum( MSG_GameReset );
    LogMsgToFile(“MSG_GameReset", id, time);
    ResetLogic();
    break;
}

利用這個方式,可以很輕鬆並且可靠的把列舉的值轉換成有意義的輸出,例如字串想要輸出到LOG檔案或顯示到螢幕上。如果不用這樣的方法,就需要自己做一個的對照表。不過通常這個對照表的維護性很差(應該沒人會去記得要維護:P),而且不太可靠。另外一個方法是全部都使用字串,而不用列舉,但是在遊戲裡面理論上來說應該還不適合用字串的比較。所以這個方法算是一個快速又可靠的安全解決方案了。
 

 

另一個使用這的用法,是可以把一組列舉放在一個標頭檔裡,然後在使用的時候把他放在不同的列表裡,好讓我們同時取得列舉跟字串。
// data.h
DATA(MSG_YouWereHit)
DATA(MSG_GameReset)
DATA(MSG_HealthRestored)
// data.cpp
#define DATA(x) x,
enum GameMessages
{
            #include “data.h"
};
#undef DATA
#define DATA(x) #x, // 使列舉值轉換成字串
static const char* GameMessageNames[] =
{
  #include “data.h"
};
#undef DATA
 

One Response to “C的巨集使用技巧1”

  1. Gordon Says:

    #define CaseEnum(id) case id: LogMsgToFile(#a, id, time)

    switch( msg_passed_in )
    {
    case MSG_YouWereHit:
    LogMsgToFile(”MSG_YouWereHit “, id, time);
    ReactToHit();
    break;

    case MSG_GameReset:
    LogMsgToFile(”MSG_GameReset”, id, time);
    ResetLogic();
    break;
    }


發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s