2

次のコードがあります

#define PROC_ADD

void main(void)
{
    while(1)
    {
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
    }
}

ただし、コードは実行されます。ただし、が未定義になったelse後はコードを実行しません。PROC_ADD

その理由は、コンパイル時にのみ定義および未定義にすることができ、実行時にはできないことが考えられると思います。しかし、よくわかりません。

4

6 に答える 6

4

あなたがしていることは、次のビルド時間に相当します。

int x = 1;

int main()
{
    if (x)
    {
        ...
        x = 0;
    }
    else
    {
        ...
    }
}

ifdef などはビルド時に発生しますが、あなたの例では問題ありません。if (実行時フォームまたはビルド時フォームのいずれか) を評価すると、どのブランチを取るかが決定されます。決定が下された後に何かを変更しても、その決定は変更されません。

于 2009-11-26T07:48:33.763 に答える
3

#define前処理中にのみ機能します。そう

#define PROC_ADD 
void main(void) 
{
#ifdef PROC_ADD 
// Do this code here then undefined it to run the code in the else 
// processing work 
#undef PROC_ADD 
#else 
// now that PROC_ADD has been undefined run this code 
// processing work 
#endif 
}

は次のように処理されます:PROC_ADDRが定義されているため、プリプロセッサは分岐を完全に除外して#elseから を実行します#undef。そのため、#else分岐コードは前処理を生き残ることはなく、コンパイラに到達することもありません。

于 2009-11-26T07:38:15.577 に答える
3

条件は、ifdefプリプロセッサが到達したときに評価されます。undef PROC_ADD'd コードの内部でifdefは、プリプロセッサはコードのどのセクションを含め、どのセクションを無視するかを既に決定しています。

さらに、 yes: ifdefundefなどは前処理時に処理されます。コンパイラは、これらのいわゆるディレクティブを見ることさえありません。もちろん、これは実行時コードもこれらのディレクティブを認識しないことを意味します。

編集:プリプロセッサは、テキストファイルを1回通過することで機能します。プリプロセッサは、テキスト ファイルに C コードが含まれていても気にしません。あなたifdefの とelseがたまたまwhileループ内にあるという知識はありません。

于 2009-11-26T07:38:59.070 に答える
2

では、2 番目のコメント セクションで表されるコードを常に実行する必要がありますか? やってみませんか

#ifdef PROC_ADD
// Do the stuff to be done if PROC_ADD is defined
#undef PROC_ADD
#endif
// Do the stuff to always be done

編集

OK - 実行時の動作を変更したい場合は、実行時の構造 (フラグとして機能する変数など) を使用する必要があります。私たちが皆言っているように ;)、プリプロセッサ ディレクティブはコンパイル時に 1 回だけ評価されます。

于 2009-11-26T07:39:02.080 に答える
2

ほぼすべてのプログラミング言語または構文で、実行が条件の 1 つの分岐に入ると (この場合、条件#ifdefは、分岐の実行中に条件が変更されても、他の分岐は実行されません。

これで「Hello」と表示されるとは思わないでしょう。

if (i == 1)
    i = 0;
else
    printf("Hello\n");

基本的にあなたが言っているのは、elseブランチの下のコードは常に実行されるべきであり、それをブランチから取り出して直接コードに入れるということです

コンパイラと実行の両方が、条件を 1 回通過するだけで、一致が見つかるとそれ以上検索しません。

于 2009-11-26T07:47:43.500 に答える
1

次のように考えてください:セクションでが設定されているにもelseかかわらず、次のコードの一部が実行されません。xfalseif

条件はif(x)行自体でチェックされます-そのブロックに入ると、後続のelse各セクションを再計算しません-コンパイラーはすでにそれについて決定を下しています。

bool x = true;
if(x)
{
  //do something
  x = false;
}
else
{
  //else code
}
于 2009-11-26T07:52:27.187 に答える