3

一部の種類のプログラムでは、一定の高い値を使用して、一部の変数の一部のプロパティを示す必要があります。つまり、ツリー内のノードが未調査のcolor[i] = 1000000;場合は放置します。iしかし、末尾の 0 の数を書き間違えることがよくあるので、次のようにした方がよいかどうか疑問に思いました。

#define UNEXPLORED 1000000;
color[i] = UNEXPLORED;

#define の使用を避ける方がはるかに良いとどこかで読んだことを覚えています。そうですか?この問題にどのように取り組みますか?

4

3 に答える 3

5

単純な定数の場合、constまたは new のいずれかを使用できconstexprます。

constexpr unsigned int UNEXPLORED = 1000000;

constこのような場合、 と を使用しても違いはありませんconstexpr。ただし、マークされた「変数」はconstexpr、実行時ではなくコンパイル時に評価され、リテラルのみを受け入れる場所で使用される場合があります。

于 2013-03-05T08:13:51.940 に答える
4

たとえば、定数を使用します。

const unsigned int UNEXPLORED = 1000000;

または列挙型

enum { UNEXPLORED = 1000000 };
于 2013-03-05T08:13:04.510 に答える
0

定数の使用では、上記の 2 つの答えは正しいですが、#defineその使用だけに限定されません。の使用の別の例は、#defineマクロです。

マクロ

#defineマクロはプリプロセッサが利用するコードの断片であり、その点では他の宣言とまったく同じように機能します。プリプロセッサは、定義されたシンボルの発生をマクロのコードと文字通り交換します。例:

#define HELLO_MAC do{ std::cout << "Hello World" << std::endl; }while(false)

int main(int argc, char** argv)
{
     HELLO_MAC;
}

HELLO_MACこれにより、宣言したコードでシンボルが文字通り置き換えられます。定数の場合は、まったく同じことを行います。#defineしたがって、定数の s は特定の種類のマクロと考えることができます。

マクロを使用すると、パラメーターを渡すこともできます。これは、コードにログ記録/例外ポリシーを適用する場合に特に便利です。例えば

#define THROW_EXCEPT( ex_type, ex_msg ) /
    do{ throw ex_type( buildExString( (ex_msg), __LINE__, __FILE__ ) ); }while(false)

... 
// somewhere else
THROW_EXCEPT( std::runtime_error, "Unsupported operation in current state" );

このコードにより、例外をスローしたファイルの行を全員がログに記録できるようになります。

多くの場合、マクロよりもテンプレートの方が適していますが、この例ではテンプレート関数を使用できません。これは、テンプレート関数の場所からではなく、throw の場所から関数__LINE__と関数を使用する必要があるためです。__FILE__

マクロを使用してはいけない場所はどこですか? どこでも他のものを使用できます。マクロは、他のものと同様#defineに前処理されるため、コンパイラはそれらをまったく認識しません。HELLO_MACこれは、またはに対して作成されたシンボルが存在しないことを意味するTHROW_EXCEPTため、デバッガーには表示されません。また、コンパイル エラーが発生した場合、特にマクロが長い場合は混乱を招く可能性があります。

于 2013-03-05T09:42:31.353 に答える