2009-08-01 84 views
1

作爲C新手我想聽聽Macro「define」開發人員正在使用什麼。我一直在思考把這些在頭跳過冗長我已經習慣於:個人預處理器指令

#define TS_ typedef struct { 
#define _TS(x) } x; 

#define I(x)_ { int i; for (i = 1; i <= x; i++) { 
#define _I } } 

我可以添加這些宏內\ n \ t等?正如我想通過我的源代碼減去額外包括:

#define TS_ typedef struct {\n 
#define _TS(x) } x;\n 

#define I(x)_ { int i;\n\tfor (i = 1; i <= x; i++) {\n 
#define _I \t}\n}\n 

這些工作?

ie:我可以使用協處理器將我的源代碼替換爲我的個人包含格式化的源代碼,而不包含?

鏈接到良好的預處理器的提示和技巧也讚賞。

+3

我不明白。爲什麼你想把空格放入宏?由於預處理源不會被人類看到(通常),因此它不會提高可讀性。 – 2009-08-01 09:03:59

+2

正如其他人所說,使用C預處理器試圖重寫C語法通常被認爲是不好的形式。也取決於你如何做到這一點,你可能會在這裏結束http://thedailywtf.com/Articles/The_Secret_to_Better_C.aspx – Falaina 2009-08-01 10:27:46

回答

6

可以把空格中通過轉義換行符

#define SOMETHING whatever\ 
This is part of the macro 

但正如其他人說這是不是真的要做到這一點的好方法。

查看編輯宏可以更好地輸入快捷方式並讓編輯器擴展它。

16

在開始之前,請不要使用以下劃線開頭的宏名 - 這些是爲編譯器和標準庫編寫器保留的,不能用於您自己的代碼中。

此外,我會說你建議的宏都是非常糟糕的想法,因爲它們隱藏了讀者所發生的事情。他們唯一的理由似乎是爲您節省很少量的打字。通常,只有在沒有明智的選擇時才使用宏。在這種情況下有一個 - 只需編寫代碼。

1

可能做到這一點,但這種「個人語言」通常不在C世界中使用,特別是如果你期望其他人在未來閱讀你的代碼。

如果你只是爲自己做這件事,然後隨意#define任何你想要的,但期望一旦你開始與任何人(或爲)任何人工作,你將無法繼續使用這種事情。

+0

@Greg:這就是爲什麼我問我是否可以使用預處理器來創建我可以然後傳遞。你讀過第一個代碼塊嗎? – 2009-08-01 09:05:54

+0

我確實。我不太明白你的意思是「傳遞」。請注意,不僅運行預處理器將替換*您的*宏,而且它還將替換代碼中聲明和使用的所有其他宏。你不能要求它只應用一個特定的宏子集。 – 2009-08-01 09:08:50

1

不必要地使用C宏會導致您陷入痛苦的世界,特別是如果您嘗試使用它來擴展代碼。 C宏有用途,但這不是它。

編輯:我意識到我的回答與你的問題是相切的,但我認爲我應該提到這點,因爲你說你是C新手。搜索「C宏陷阱」以獲得不使用宏的完整列表。之前已經討論過here

4

你正在走向錯誤的道路。 不要組成你自己的cpp指令,這些指令對別人不熟悉 - 這會使你的代碼難以理解,並在某些時候保持不變。

嘗試找到一些很好的C代碼來閱讀 - 良好的C代碼不使用這些東西,有一個很好的理由。

0

總的來說,我非常同意其他的答覆者,他們告訴你不要純粹爲了保存輸入而定義自己的宏。迷惑不值得。另外,你所建議的特定宏是可惡的。然而,在Stroustrup的第1版,他做的東西我比較喜歡(有時):

 
#define Kase break; case 
0

我就習慣了Python的elif的結構,所以我經常定義如下:

#define elif(test) else if(test) 

我的目的這樣做是不是減少鍵入,它是保持合理的縮進邏輯,同時保持一致的代碼寬度(我不讓我的代碼寬度超過80個字符)。我這麼說是因爲我這...

if(...) ... 
else if(...) ... 
else ... 

...應該是...

if(...) 
{ 
    ... 
} 

else 
    if(...) 
    { 
     ... 
    } 

    else 
    { 
     ... 
    } 

用我的宏變爲:

if(...) 
{ 
    ... 
} 

elif(...) 
{ 
    ... 
} 

else 
{ 
    ... 
} 
0

它始終是更好地將循環變量傳遞給宏。 塊 - 宏有一定的優化問題。所有編譯器不保證「塊範圍」變量的優化obj代碼。

例如,以下代碼在編譯時未將任何優化選項編譯爲gcc時,會爲& i打印兩個單獨的地址。當使用-O2選項編譯時,相同的代碼將在兩個塊中打印相同的地址。

{ 
    int i; 
    printf("address of i in first block is %u\n", &i); 
} 
{ 
    int i; 
    printf("address of i in sec block is %u\n", &i); 
} 

命名適當的語言結構使代碼更具可讀性。 我喜歡你的想法,如果你按照下面的方式。

#define GREEN 1 
#define YELLOW 2 
#define RED 3 

# define NUM_COLORS 3 

#define COLOR_ITER (color,i)   \ 
    for(i=GREEN, color = colors[i]; \ 
     i < NUM_COLORS;    \ 
     color = colors[++i]) 

int colors[3] = {GREEN, YELLOW, RED}; 

int 
fun() { 

    int j; 
    color_t clr; 

    COLOR_ITER(clr, j) { 
     paint(clr); 
    } 

} 

在這裏,不管它是怎麼寫的,宏,COLOR_ITER,它的名​​字,意味着你是循環的所有可用的顏色和做「事」爲每一種顏色。這是一個非常易於使用的宏。

而且你quesion

我可以使用proprocessor與我個人來代替我的源代碼包括以格式化源不包括哪些內容?

正如大家解釋的預處理器在這種情況下不會幫助你。 您可以使用您的編輯器命令自動格式化您的代碼,只需鍵入它。