web-dev-qa-db-ja.com

変数の代わりに#defineを使用する理由

C++の#defineのポイントは何ですか? 「マジックナンバー」の代わりに使用される例を見てきましたが、代わりにその値を変数に与えるだけでは意味がありません。

51
Greener

最近はほとんど文体的です。 Cが若かったとき、const変数のようなものはありませんでした。したがって、#defineの代わりに変数を使用した場合、誰かがその値を変更しないという保証はなく、プログラム全体に大混乱を引き起こします。

昔は、FORTRANは参照によってサブルーチンに定数さえ渡していました。また、「2」のような定数の値を別の値に変更することもできました(そして頭痛を引き起こす)。かつて、これは私が取り組んでいたプログラムで起こり、何かが間違っているという唯一のヒントは、プログラムがそれを終了するはずのSTOP 999にヒットしたときにABEND(異常終了)を取得することでした通常は。

41
Paul Tomblin

_#define_は、CおよびC++のプリプロセッサ言語の一部です。コードで使用される場合、コンパイラは_#define_ステートメントを必要なものに置き換えます。たとえば、常にfor (int i=0; i<=10; i++)を書くことにうんざりしている場合は、次のことができます。

_#define fori10 for (int i=0; i<=10; i++)

// some code...

fori10 {
    // do stuff to i
}
_

より一般的なものが必要な場合は、プリプロセッサマクロを作成できます。

_#define fori(x) for (int i=0; i<=x; i++)
// the x will be replaced by what ever is put into the parenthesis, such as
// 20 here
fori(20) {
    // do more stuff to i
}
_

特定のビルドで特定のコードのみを使用する場合は、条件付きコンパイル(_#define_のその他の主な用途)にも非常に役立ちます。

_// compile the following if debugging is turned on and defined
#ifdef DEBUG
// some code
#endif
_

ほとんどのコンパイラでは、コマンドラインからマクロを定義できます(例、_g++ -DDEBUG something.cpp_)が、次のようにコードに定義を追加することもできます。

_#define DEBUG
_

いくつかのリソース:

  1. ウィキペディアの記事
  2. C++固有のサイト
  3. GCCのプリプロセッサに関するドキュメント
  4. Microsoftリファレンス
  5. C固有のサイト (ただし、C++バージョンと異なるとは思わない)
115
supercheetah

仕事で困ったことがある。配列宣言で「マジックナンバー」を使用していると非難されました。

このような:

int Marylyn[256], Ann[1024];

会社の方針は、これらのマジックナンバーは携帯用ではないと説明されたためです。彼らは簡単なメンテナンスを妨げていること。私は、コードを読んでいるときに、配列の大きさを正確に知りたいと主張しました。私は議論を失ったので、金曜日の午後、問題のある「マジックナンバー」を#definesに置き換えました。

 #define TWO_FIFTY_SIX 256
 #define TEN_TWENTY_FOUR 1024

 int Marylyn[TWO_FIFTY_SIX], Ann[TEN_TWENTY_FOUR];

次の月曜日の午後、私は呼ばれ、受動的な反抗的な傾向があると非難されました。

23
Harpee

#defineは、ヘッダーやその他のタスクを保護するなど、通常のC++ではできないいくつかのジョブを実行できます。ただし、マジックナンバーとしては絶対に使用しないでください。代わりに静的constを使用する必要があります。

7
Puppy

Cはconstを使用していなかったため、#definesが定数値を提供する唯一の方法でした。 CとC++の両方にこれらが含まれるようになったため、#ifdef/ifndefを使用してテストする場合を除き、それらを使用しても意味がありません。

7

最も一般的な用途(定数の宣言以外)は、 ガードを含める です。

4
YXD

プリプロセッサによるコンパイルの前に定義が評価され、実行時に変数が参照されます。これは、アプリケーションの構築方法を制御することを意味します(実行方法ではありません)

変数で置き換えることができないdefineを使用するいくつかの例を次に示します。

  1. #define min(i、j)(((i)<(j))?(i):(j))
    これは実行時ではなく、プリプロセッサによって評価されることに注意してください

  2. http://msdn.Microsoft.com/en-us/library/8fskxacy.aspx

1
DanJ

#defineを使用すると、ヘッダーに値を設定することができます。値を設定しないと、ゼロより大きいサイズにコンパイルされます。ヘッダーは、ゼロより大きいサイズにコンパイルしないでください。

// File:  MyFile.h

// This header will compile to size-zero.
#define TAX_RATE 0.625

// NO:  static const double TAX_RATE = 0.625;
// NO:  extern const double TAX_RATE;  // WHAT IS THE VALUE?

編集:ニールがこの投稿へのコメントで指摘しているように、ヘッダーの明示的な値の定義はC++では機能しますが、Cでは機能しません。

0
charley