2009-08-01 4 views
1

C初心者マクロが「定義している」開発者が使用していることを聞きたいと思います。私はこれらのマクロの中に\ n個の\ tののなどを追加することができパーソナルプリプロセッサディレクティブ

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

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

:私は、私が使用になった冗長性をスキップするヘッダーにこれらを置くことについて考えてきましたか?ソースコードからマイナスのものを引き渡したい場合は、

#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

わかりません。なぜマクロに空白を入れたいのですか?前処理されたソースは人間(通常)によって見られることはないため、可読性は向上しません。 –

+2

他の人が言っているように、Cプリプロセッサを使ってC構文を書き直すのは、一般的には貧弱な形です。また、あなたがそれを行う方法に応じて、ここで終わるかもしれないhttp://thedailywtf.com/Articles/The_Secret_to_Better_C.aspx – Falaina

答えて

6

あなたは改行

#define SOMETHING whatever\ 
This is part of the macro 

をエスケープすることにより、しかし他のものに空白を置くことができる。それは本当ににこれを行うための素晴らしい方法ではないと述べています。

エディタマクロを調べて、ショートカットを入力してエディタに展開させることができます。

+1

@JB:エディタのマクロは間違いなくここに行きます。 :D –

16

開始する前に、アンダースコアで始まるマクロ名を使用しないでください。これらは、コンパイラおよび標準ライブラリライタ用に予約されており、独自のコードでは使用しないでください。

さらに、あなたが提案しているマクロは、読者から何が起こっているのかを隠すため、非常に悪い考えです。それらのための唯一の正当化はあなたに非常に少量のタイピングを保存するように思われます。一般に、賢明な選択肢がない場合にのみ、マクロを使用してください。この場合は1つあります。コードを書くだけです。

1

このようなことがありますが、この種の「個人用言語」は、C言語では一般的には使用されません。

これを自分のためだけに実行している場合は、#defineを自由に使用してください。ただし、他のユーザーとの作業を開始すると、この種類のもの。

+0

@ Greg:まさに私はプリプロセッサを使って私がパスする。最初のコードブロックを読んだことがありますか? –

+0

私は確かにやった。私はあなたが「渡す」ことを意味しているかどうか分かりませんでした。プリプロセッサを実行して*マクロを置き換えるだけでなく、コード内で宣言され使用されている他のマクロもすべて置き換えることに注意してください。マクロの特定のサブセットのみを適用するように要求することはできません。 –

+0

とにかく、既にプリプロセッサを通して実行されたCコードを人に与えることは、難読化と見なすことができます。誰もこれをしません。 –

1

Cマクロを不必要に使用すると、特にコードを展開するときに苦労することになります。 Cマクロには用途がありますが、これはそうではありません。

編集:私の答えはあなたの質問に接していることを認識していますが、あなたはあなたがCの初心者だと言っているので、これについて言及すべきだと思いました。 "C macro pitfalls"を検索し、マクロを使用しない理由の完全なリストを取得します。以前は、hereについて議論されています。

4

あなたは間違ったパスに向かっています。 他人には慣れていない独自のcpp指令を作成しないでください。これはコードを理解しにくくし、ある時点で維持します。

良いCコードを読み込もうとしてください - 良いCコードはこれらのものを使用していません。正当な理由があります。

0

一般的に私は、入力を省くためにあなた自身のマクロを定義しないように伝える他の回答者に強く同意します。難読化はそれに値するものではありません。また、あなたが示唆している特定のマクロは凶悪です。しかし、Stroustrup氏の第一エドに、彼は私はむしろ(時々)のようなものを行います。

 
#define Kase break; case 
0

私はelifの構築のPythonに慣れになったので、私は多くの場合、次のように定義します。

#define elif(test) else if(test) 

で私の目的ではありません。タイピングを減らすには、一貫したコード幅を維持しながらインデントを論理的に保つことです(私のコードは80文字を超えないようにします)。

if(...) 
{ 
    ... 
} 

elif(...) 
{ 
    ... 
} 

else 
{ 
    ... 
} 
+2

"else if(test)"(1行で)と言うだけではどうですか? –

0

それは常により良いです:私はこれになる私のマクロで

if(...) 
{ 
    ... 
} 

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

    else 
    { 
     ... 
    } 

...でなければなりません...

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

...なぜなら、私これにこんなことを言いますループ変数をマクロに渡します。 ブロック - マクロに特定の最適化問題があります。すべてのコンパイラは、 "ブロックスコープ"変数に最適化されたobjコードを保証するものではありません。

たとえば、次のコードは、gccの最適化オプションを除いてコンパイルすると、& iの2つの別々のアドレスを出力します。 -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を使用することはできますが含まれずにフォーマットされたソースに含まれますか?

誰もがこの場合、プリプロセッサはあなたを助けません。 エディタコマンドを使用すると、入力時に自動的にコードを書式設定できます。

3

DO NOT DO IT誰もあなたのコードを読むことができません。

注意の例として、Steve Bourne's original sources for the Bourne shellをチェックしてください。彼はマクロを使用して、ある種のpidgin Algolスタイルでコードを記述しています。