2012-03-06 17 views
4

私は多少悪いことをするつもりです。私は条件を変更するループを再定義したい。これを行う方法はありますか? GCCのドキュメントからプリプロセッサでループを再定義する

、キーワードを再定義することはサポートされています:http://gcc.gnu.org/onlinedocs/cpp/Macros.html

を私は何をしようとしているが、私はそれで面白いものを作ることができるかどうかを確認するために、C++のための「確率論」のラッパーを作るです。 Aおそらくより合法的な使用は

for(int i=0; i < 10; ++i, ++global_counter) 

にマッピング

for(int i=0; i < 10; ++i) 

により、たとえば、実行中のプログラムにループの繰り返し回数をカウントするだろう

#include <iostream> 
#include <cstdlib> 

#define P 0.85 

#define RANDOM_FLOAT ((float)rand()/(float)RAND_MAX) 

#define RANDOM_CHANCE (RANDOM_FLOAT < P) 

#define if(a) if((a) && RANDOM_CHANCE) 

#define while(a) while((a) && RANDOM_CHANCE) 


// No more for loops or do-while loops 
#define do 
#define goto 

// Doesn't work :(
//#define for(a) for(a) if(!RANDOM_CHANCE) { break; } 


int main() { 
    srand(time(NULL)); 

    //Should output a random list of Y's and N's 
    for(int i=0; i < 100; ++i) { 
     if(i < 100) { 
      std::cout << "Y"; 
     } else { 
      std::cout << "N"; 
     } 
    } 

    std::cout << std::endl; 

    // Will loop for a while then terminate 
    int j = 0; 
    while(j < 100) { 
     ++j; 
     std::cout << j << "\n"; 
    } 

    std::cout << std::endl; 

    return 0; 
} 

達成することが可能です私は何をしようとしていますか?


編集:ありがとうございます - 本当にありがとうございます!

バイアスコインの場合、Pr(HT)== Pr(TH)であれば、公平なコイン(実際にはPを0.5にする)をシミュレーションすることができます。私はこのトリックを発見しませんでしたが、それは便利です。つまり、あなたはPの確率分布を近似することができます。

bool coin() { 
    bool c1 = false; 
    bool c2 = false; 

    if(true) { 
    c1 = true; 
    } 
    if(true) { 
    c2 = true; 
    } 

    //If they have different faces. 
    bool valid = (c1 && !c2) || (!c1 && c2); 
    bool result = c1; 

    if(valid) { return result; } 

    return coin(); 
} 
+2

これはすばらしいです...非常に多くの異なるレベルのように... – Mysticial

+0

メンタルですが、はい、素晴らしいです。 – BoBTFish

+16

誰かがあなたのコードを維持する必要がある場合は、どこに住んでいるのか分からないようにしてください。 –

答えて

8

forループにelseを追加しようとしましたか?それはそれを動作させるはずです。

#define for(a) for(a) if(!RANDOM_CHANCE) { break; } else 

for (int i = 0; i < 10; ++i) 
{ 
    // do something 
} 

/* should roughly compile to: 
for (int i = 0; i < 10; ++i) if(!RANDOM_CHANCE) { break; } else 
{ 
    // do something 
} 

or (differing only in whitespace): 

for (int i = 0; i < 10; ++i) 
    if(!RANDOM_CHANCE) 
    { 
     break; 
    } 
    else 
    { 
     // do something 
    } 
*/ 
+0

+1私は* Post *ボタンをまさに同じ答えでクリックしようとしていました。 – netcoder

4

あなたはすでにそれを示しています。ここでは、コンパイルの例です:それは今のところ、マクロに二つの引数を渡すよう

#include <iostream> 

unsigned globalCounter = 0; 

#define for(x) for(x, ++globalCounter) 

int main() { 
    for (int i=0; i<10; ++i); 
    for (int i=0; i<10; ++i); 

    std::cout << globalCounter << '\n'; 
} 

この出力20は、しかし、

for (int i=0; i<x; ++i, foobar+=20) 

のような既存のコードが破損します。

マクロオーバーロードまたは可変長マクロが必要です。私はこれをサポートしていません

g++ --std=c++0x source.cc 
./a.out 
20 20 

その後、

unsigned globalCounter = 0; 
#define for(...) for(__VA_ARGS__, ++globalCounter) 

#include <iostream> 

void main() { 
    int another = 0; 
    for (int i=0; i<10; ++i, ++another); 
    for (int i=0; i<10; ++i, ++another); 

    std::cout << globalCounter << ' ' << another << '\n'; 
} 

:後者はC99でサポートされており、C++ 11には、それを導出するので、あなたは悪が起こることをしたい場合。マクロは子供に危害を与える可能性があります。

+0

それをバリデーションにして、最後のスニペットではそれを壊さないでしょう。 '(__ VA_ARGS__、++ globalCounter)のための#define(...) '。 (C++ 11)。 –

+0

@R。 Martinho Fernandes:しかし、C++は私の知識にバリデーショナルなマクロを持っていないので、C99の答えを追加しました。 –

+0

私が言及したように、variadicマクロはC++ 11で追加されました。 –

1

ブロックがforステートメントに属していないため、このブロックは機能しません。変換は

for (int i=0; i < 100; ++i) 
{ 
    if (!RANDOM_CHANCE) 
    { 
     break; 
    } 
} 

// unrelated to the 'for' above. 
{ 
    if(i < 100) { 
     std::cout << "Y"; 
    } else { 
     std::cout << "N"; 
    } 
} 

代わりに、あなただけの

#define for(...) for(__VA_ARGS__) if(RANDOM_CHANCE) 

を書くことができるようにコードが

for (int i=0; i < 100; ++i) 
    if (RANDOM_CHANCE) 
    { 
     if(i < 100) { 
      std::cout << "Y"; 
     } else { 
      std::cout << "N"; 
     } 
    } 

なりなり(私はvariadic macrosを使用していることに注意してください。)


そして、あなたはincreament部分が空になることはありませんことを保証できる場合global_counterの事のために、それは簡単です:

#define for(...) for(__VA_ARGS__, ++ global_counter) 

そうでない場合(例えば、コード内for(;;)がある)、Iそれが可能だとは思わない。

+0

私は最初の問題をマクロに 'else'を追加することで解決できると思います(私の答えを見てください)。 –

関連する問題