23


2

コンピュータプログラミングの「マジックナンバー」とは何ですか?

コンピュータプログラミングで「マジックナンバー」を使用することについて人々が話すとき、それらはどういう意味ですか?

11 回答


38


マジックナンバーは、コード内の任意の数字で、知識がほとんどない人にはすぐにはわかりません。

たとえば、次のコードは次のとおりです。

sz = sz + 729;

マジックナンバーがあり、次のように書く方がはるかに良いでしょう:

sz = sz + CAPACITY_INCREMENT;

一部の極端なビューでは、コードに-1、0、1以外の数字を含めることはできませんが、24、1440、86400、3.1415、2.71828、1.414を即座に認識するため、ややドグマチックなビューを好むと述べています-それはすべてに依存しますあなたの知識。

ただし、1日は1440分であることがわかっていても、検索をはるかに容易にするため、おそらく `MINS_PER_DAY`識別子を使用します。 上記の容量の増分も1440ではなく、間違った値を変更することになります。 これは、数値が低い場合に特に当てはまります。37197を2回使用する可能性は比較的低く、複数のものに5を使用する可能性はかなり高くなります。

識別子を使用すると、容量の増分が変更されたときに700個のソースファイルをすべて調べて、「729」を「730」に変更する必要がなくなります。 1行だけを変更できます。

#define CAPACITY_INCREMENT 729

to:

#define CAPACITY_INCREMENT 730

ロットを再コンパイルします。

'' '' '

これと比較して、コードから実際の数値を削除したからといって、変更できると考えている素朴な人々の結果である魔法の定数とは対照的です。

x = x + 4;

to:

#define FOUR 4
x = x + FOUR;

これはコードに絶対に_zero_余分な情報を追加するため、時間の無駄です。


6


「マジックナンバー」は、次のような文に現れる数字です

if days == 365

1年に365日あることを知らなかったと仮定すると、この文は無意味であることがわかります。 したがって、すべての「マジック」番号(プログラムで何らかの意味を持つ番号)を定数に割り当てることをお勧めします。

DAYS_IN_A_YEAR = 365

それから、代わりにそれと比較してください。 読みやすく、地球が整列から外れた場合、余分な日が増えます…​ 簡単に変更できます(他の数値は変更される可能性が高くなります)。


5


複数の意味があります。 ほとんどの回答ですでに与えられているもの(任意の名前のない番号)は非常に一般的なものであり、それについて私が言う唯一のことは、一部の人々が定義の極端に行くことです…​

#define ZERO 0
#define ONE 1

あなたがこれをするならば、私はあなたを追い詰めて、慈悲を示さないでしょう。

ただし、別の種類のマジックナンバーがファイル形式で使用されます。 これは、通常、ファイル形式、ファイル形式のバージョン、および/または特定のファイルのエンディアンネスを識別するのに役立つファイルの最初のものとして含まれている値です。

たとえば、0x12345678のマジックナンバーがあります。 そのマジックナンバーが表示されている場合、正しい形式のファイルが表示されていると推測できます。 一方、0x78563412が表示される場合、同じファイル形式のエンディアンスワップバージョンが表示されていることはかなり推測に値します。

「マジックナンバー」という用語は少し乱用されますが、ファイル形式を識別するほとんどすべてのことを指します-ヘッダーに非常に長いASCII文字列を含みます。


4


ウィキペディアはあなたの友達です(http://en.wikipedia.org/wiki/Magic_number_%28programming%29[Magic Number]の記事)


3


これまでの答えのほとんどは、マジックナンバーを自己記述ではない定数として説明してきました。 私は「昔ながらの」プログラマであり、コードの動作に影響を与える特別な目的が割り当てられている定数としてマジックナンバーを説明していました。 たとえば、999999やMAX_INTなどの完全に任意の数字。

マジックナンバーの大きな問題は、その目的が簡単に忘れられること、または値が別の完全に合理的なコンテキストで使用されることです。

粗雑でひどく不自然な例として:

while (int i != 99999)
{
  DoSomeCleverCalculationBasedOnTheValueOf(i);

  if (escapeConditionReached)
  {
    i = 99999;
  }
}

定数が使用されているか、名前が付けられていないという事実は、実際には問題ではありません。 私のひどい例の場合、値は振る舞いに影響しますが、ループ中に「i」の値を変更する必要がある場合はどうでしょうか?

上記の例では明らかに、ループを抜けるためにマジックナンバーは必要ありません。 これをbreakステートメントに置き換えることができますが、これはマジックナンバーの本当の問題です。これはコーディングに対する怠approachなアプローチであり、必ず失敗することも、時間の経過とともに意味を失うことも少ないものに必ず置き換えることができます。


2


アプリケーション自体以外の誰にも容易に明らかな意味を持たないもの。

if (foo == 3) {
    // do something
} else if (foo == 4) {
    // delete all users
}


2


マジックナンバーは、特定の変数の特別な値であり、プログラムが特別な方法で動作するようにします。

たとえば、通信ライブラリはタイムアウトパラメータを使用し、無限のタイムアウトを示すマジック番号「-1」を定義できます。


1


通常、マジックナンバーという用語は、コードで数値定数を表すために使用されます。 番号は詳細な説明なしで表示されるため、その意味は難解です。

名前付き定数を使用すると、マジックナンバーの使用を回避できます。


0


ある識別子または変数によって定義されていない0または1以外の計算で数値を使用します(1か所で変更することで数箇所で数を変更しやすくするだけでなく、読者に数を明確にしますのためです)。


0


単純で真の言葉では、マジックナンバーは3桁の数字であり、最初の2桁の平方和は3番目の数字に等しくなります。 Ex-202、as、2 * 2 + 0 * 0 = 2 * 2 これで、javaのWAPは整数を受け入れ、マジックナンバーかどうかを出力します。