7

私はかなり新しいプログラマーです。この情報が簡単に入手できる場合は、まだ見つけられていないことをお詫びします。

これが私の質問です:

リテラル番号を使用して配列の特定の要素にアクセスする場合、マジックナンバーと見なされますか?

例えば:

arrayOfNumbers[6] // Is six a magic number in this case?

私の教授の一人がプログラムのすべてのリテラル数はマジックナンバーであると断固として主張しているので、私はこの質問をします。要素ごとに名前付き定数を使用するのではなく、実数を使用して配列の要素にアクセスするだけでよいと思います。

ありがとう!

4

11 に答える 11

22

それは本当に文脈に依存します。このようなコードがある場合:

arr[0] = "Long";
arr[1] = "sentence";
arr[2] = "as";
arr[3] = "array.";

...その場合、0..3はマジックナンバーとは見なされません。ただし、次の場合:

int doStuff() 
{
   return my_global_array[6];
}

...そして6は間違いなくマジックナンバーです。

于 2010-01-18T21:48:21.710 に答える
6

それはかなり魔法です。

つまり、なぜ6番目の要素にアクセスしているのですか?その数に適用されるべきセマンティクスは何ですか?現状では、私たちが知っているのは「6番目の(ゼロベースの)数値」だけです。の宣言を知っていれば、arrayOfNumbersそのタイプ(たとえば、intまたはdouble)もさらにわかります。

しかし、あなたが言った場合:

arrayOfNumbers[kDistanceToSaturn]; 

...今では、コードを読んでいる人にとってははるかに意味があります。

一般に、配列の長さがわからず、ハードコードされた方法で配列にアクセスすることはできないため、配列を反復処理して、各要素に対して何らかの操作を実行します。

ただし、グラフィックプログラミングなどでは、配列要素に特定の意味がある場合があります。データが要求するため、配列が常に同じサイズになる場合があります(特定の変換行列など)。このような場合、特定の要素に番号でアクセスできる場合とできない場合があります。ドメインの専門家はあなたが何をしているのかを知っていますが、ジェネラリストはおそらく知らないでしょう。マジックインデックス番号に名前を付けると、コードを管理しなければならない人にとってわかりやすくなり、誤って間違ったコードを入力するのを防ぐことができます。

上記の例では、配列が太陽から惑星までの距離を保持していると仮定しました。太陽は0番目の要素であるため、arrayOfNumbers [kDistanceToSun] = 0です。次に、増分すると、各要素には、水星、金星など、次に遠い惑星までの距離が含まれます。これは、単に数字を入力するよりもはるかに読みやすくなります。あなたが望む惑星。この場合、惑星の数が固定されているため、配列のサイズは固定されています(冥王星の大失敗全体を除いて)。

もう1つの問題は、「arrayOfNumbers」が配列の内容について何も教えてくれないことです。あなたが言った場所、またはあなたがそれを宣言した場所のどこかで宣言を見たので、私たちはすでにその数字の配列を知っていますint arrayOfNumers[12345];。代わりに、次のようなものです。

int distanceToPlanetsFromSol[kNumberOfPlanets];

...データが実際に何であるか、およびそのセマンティクスが何であるかについて、はるかに優れたアイデアを提供します。プログラマーとしての目標の1つは、この方法で自己文書化するコードを作成することです。

そして、kNumberOfPlanets8か9かは他の場所で議論することができます:)

于 2010-01-18T21:47:09.183 に答える
5

なぜその特定の位置にアクセスしているのかを自問する必要があります。この場合、6番目のポジションをやっarrayOfNumbers[6]ていると特別な意味があると思います。その意味を考えれば、それを隠しているマジックナンバーだと気付くでしょう。

于 2010-01-18T21:46:26.953 に答える
2

それを見る別の方法:

たまたまプログラムが6番目ではなく7番目の要素にアクセスする必要がある場合はどうなりますか?あなたやメンテナはそれをどのように知っていますか?たとえば、6番目のエントリがCAの樹木の数である場合、

 #define CA_STATE_ENTRY 6

次に、テーブルが並べ替えられた場合、誰かがこれを9に変更する必要があることがわかります(たとえば)。ところで、これが州ごとのツリーカウントの配列を維持するための最良の方法であると言っているわけではありません-おそらくそうではありません。

同様に、後で人々がオレゴンの木を扱うようにプログラムを変更したい場合、彼らは置き換えることを知っています

 trees[CA_STATE_ENTRY]

 trees[OR_STATE_ENTRY]

ポイントは

 trees[6]

自己文書化ではありません

もちろん、C ++の場合は、#defineではなく列挙型である必要があります

于 2010-01-18T22:02:15.610 に答える
1

意味のある答えを得るには、より多くのコンテキストを提供する必要があります。すべてのリテラル数が魔法であるわけではありませんが、多くは魔法です。そのような場合、確実に言う方法はまったくありませんが、ほとんどの場合、明示的な配列インデックス>> 1を使用すると、手に負えないと考えることができますが、おそらく魔法と見なされます。

于 2010-01-18T21:47:25.827 に答える
1

プログラム内のすべてのリテラルが実際に「マジックナンバー」として適格であるとは限りませんが、これは確かにそうであるようです。は6、配列の特定の要素にアクセスしている理由がわかりません。

マジックナンバーにならないためには、最初の検査(または少なくとも最小限の検査)でも、その値が使用されている理由を明確にする必要があります。たとえば、多くのコードは次のようなことを行います&x[0]。この場合、通常、「0」は実際には「配列の始まり」を意味するだけであることは明らかです。

于 2010-01-18T21:50:24.603 に答える
0

配列の特定の要素にアクセスする必要がある場合は、間違っている可能性があります。

ほとんどの場合、配列全体を反復処理する必要があります。

于 2010-01-18T21:47:01.230 に答える
0

あなたのプログラムが特に6番を含む非常に特別なことをしているなら、それは魔法の数ではありません。コンテキストを教えていただけますか?

于 2010-01-18T21:47:15.007 に答える
0

それは教授の問題です、彼らはしばしばあまりにも学術的です。理論的にはいつものように彼は正しいですが、通常、魔法数はデータストリームに埋め込まれている場合、より厳密なコンテキストで使用され、ストリームの特定のプロパティ(たとえば、ファイルタイプの署名ヘッダーなど)を検出できます。 。このウィキペディアのエントリも参照してください。

于 2010-01-18T21:47:55.077 に答える
0

通常、ソフトウェアのすべての定数値がマジックナンバーと呼ばれるわけではありません。Javaクラスファイルは常に16進値0xcafebabeで始まります。Windows.exeファイルはMZ0x4d、0x5aです。これにより、バイナリファイルの内容をすばやく(確実ではありませんが)識別できます。

于 2010-01-18T21:56:01.677 に答える
0

MISRA準拠のシステムでは、0と1を除くすべての値がマジックナンバーと見なされます。私の意見では、定数値が明らかであるか、おそらく変わらない場合は、数値のままにしておきます。長期的なメンテナンスが容易になるため、疑わしい場合は一意の定数を作成してください。

于 2010-01-18T22:49:52.413 に答える