Ich bin ein ziemlich neuer Programmierer, und ich entschuldige mich, wenn diese Information dort draußen leicht verfügbar ist, ich konnte sie nur noch nicht finden.
Hier ist meine Frage:
Werden magische Zahlen verwendet, wenn Sie eine Literalnummer für den Zugriff auf ein bestimmtes Element eines Arrays verwenden?
Zum Beispiel:
%Vor%Ich stelle diese Frage, weil einer meiner Professoren darauf besteht, dass alle wörtlichen Zahlen in einem Programm magische Zahlen sind. Es wäre schön für mich, nur auf ein Element eines Arrays mit einer reellen Zahl zuzugreifen, anstatt für jedes Element eine benannte Konstante zu verwenden.
Danke!
Das hängt wirklich vom Kontext ab. Wenn Sie Code wie folgt haben:
%Vor%... dann 0.3 werden nicht als magische Zahlen betrachtet. Wenn Sie jedoch:
%Vor%... dann ist 6 definitiv eine magische Zahl.
Es ist ziemlich magisch.
Ich meine, warum greifen Sie auf das sechste Element zu? Wie lautet die Semantik, die auf diese Zahl angewendet werden sollte? So wie es aussieht, ist alles, was wir wissen, "die sechste (nullbasierte) Nummer". Wenn wir die Deklaration von arrayOfNumbers
kennen würden, würden wir ihren Typ besser kennen (z. B. ein int
oder ein double
).
Aber wenn du gesagt hast:
%Vor%... jetzt hat es viel mehr Bedeutung für jemanden, der den Code liest.
Im Allgemeinen wird über ein Array iteriert, wobei für jedes Element eine Operation ausgeführt wird, da man nicht weiß, wie lange das Array ist und man nicht nur hartcodiert darauf zugreifen kann.
Manchmal haben Array-Elemente jedoch bestimmte Bedeutungen, z. B. bei der Grafikprogrammierung. Manchmal hat ein Array immer die gleiche Größe, weil die Daten es erfordern (z. B. bestimmte Transformationsmatrizen). In diesen Fällen ist es möglich oder nicht in Ordnung, auf das spezifische Element per Nummer zuzugreifen: Domain-Experten wissen, was Sie tun, aber Generalisten wahrscheinlich nicht. Wenn Sie der magischen Indexnummer einen Namen geben, ist dies für diejenigen, die Ihren Code pflegen müssen, offensichtlicher, und Sie können verhindern, dass versehentlich die falsche eingegeben wird.
In meinem obigen Beispiel ging ich davon aus, dass Ihr Array Entfernungen von der Sonne zu einem Planeten enthält. Die Sonne wäre das nullte Element, also arrayOfNumbers [kDistanceToSun] = 0. Dann enthält jedes Element beim Inkrementieren die Entfernung zum nächsten am weitesten entfernten Planeten: Quecksilber, Venus, usw. Dies ist viel besser lesbar als nur die Zahl der Planet, den du willst. In diesem Fall hat das Array eine feste Größe, da es eine feste Anzahl von Planeten gibt (nun, außer dem ganzen Pluto-Debakel).
Das andere Problem ist, dass "arrayOfNumbers" nichts über den Inhalt des Arrays sagt. Wir kennen bereits eine Reihe von Zahlen, weil wir die Deklaration irgendwo gesehen haben, wo Sie int arrayOfNumers[12345];
gesagt haben oder wie Sie es auch deklariert haben. Stattdessen etwas wie:
... gibt uns eine viel bessere Vorstellung davon, was die Daten tatsächlich sind und was ihre Semantik ist. Eines Ihrer Ziele als Programmierer sollte es sein, Code zu schreiben, der auf diese Weise selbstdokumentiert.
Und dann können wir anderswo argumentieren, wenn kNumberOfPlanets
8 oder 9 sein sollte.:
Sie sollten sich fragen, warum Sie auf diese bestimmte Position zugreifen. In diesem Fall nehme ich an, dass, wenn Sie arrayOfNumbers[6]
machen, die sechste Position eine besondere Bedeutung hat. Wenn du denkst, was diese Bedeutung ist, merkst du wahrscheinlich, dass es eine magische Zahl ist, die das versteckt.
Eine andere Art, es anzuschauen:
Was passiert, wenn das Programm nach einiger Zeit auf das siebte Element statt auf das sechste zugreifen muss? Würdest du oder ein Maintainer das wissen? Wenn zum Beispiel der 6. Eintrag die Anzahl der Bäume in CA ist, wäre es eine gute Sache,
zu setzen %Vor%Wenn nun die Tabelle neu angeordnet wird, kann jemand sehen, dass sie dies auf 9 (sagen wir) ändern müssen. Übrigens sage ich nicht, dass dies der beste Weg ist, um ein Array für Baumzählungen nach Zustand zu pflegen - es ist wahrscheinlich nicht.
Ebenso, wenn später Leute das Programm ändern wollen, um sich mit Bäumen in Oregon zu befassen, dann wissen sie,
zu ersetzen %Vor%mit
%Vor%Der Punkt ist
%Vor%ist nicht selbstdokumentierend
Natürlich sollte es für c ++ eine enum sein, nicht eine #define
Sie müssten mehr Kontext für eine sinnvolle Antwort bereitstellen. Nicht alle wörtlichen Zahlen sind magisch, aber viele sind es. In einem solchen Fall gibt es keine Möglichkeit, dies sicher zu sagen, obwohl die meisten Fälle, die ich mir mit einem expliziten Array-Index vorstellen kann & gt; & gt; 1 wahrscheinlich als Magie gelten.
Nicht alle Literale in einem Programm gelten wirklich als "magische Zahlen" - aber diese scheint es zu sein. Der 6
gibt uns keine Ahnung, warum Sie auf dieses bestimmte Element des Arrays zugreifen.
Um nicht eine magische Zahl zu sein, muss ihre Bedeutung selbst bei der ersten Prüfung (oder zumindest bei einer minimalen Prüfung) ziemlich klar sein, warum dieser Wert verwendet wird. Zum Beispiel, eine Menge Code wird Dinge tun wie: &x[0]
. In diesem Fall ist es normalerweise ziemlich klar, dass die '0' wirklich nur "den Anfang des Arrays" bedeutet.
Es ist nur keine magische Zahl, wenn Ihr Programm etwas ganz Besonderes macht, insbesondere die Nummer sechs. Könnten Sie einen Kontext bereitstellen?
Das ist das Problem mit Professoren, sie sind oft zu akademisch. Theoretisch hat er Recht, aber normalerweise werden magische Zahlen in einem strengeren Kontext verwendet, wenn die Zahl in einen Daten -Stream eingebettet ist, so dass Sie bestimmte Eigenschaften des Streams erkennen können (wie der Signaturheader) eines Dateityps für Beispiel). Siehe auch diesen Wikipedia-Eintrag .
Normalerweise werden nicht alle konstanten Werte in der Software magische Zahlen genannt. Eine Java-Klasse beginnt immer mit dem Hexadezimalwert 0xcafebabe einer Windows-Datei .exe Datei mit MZ 0x4d, 0x5a, dies erlaubt Ihnen schnell (aber nicht sicher) zu identifizieren der Inhalt einer Binärdatei.
In einem MISRA-kompatiblen System werden alle Werte außer 0 und 1 als magische Zahlen betrachtet. Meine Meinung war immer, wenn der konstante Wert offensichtlich ist oder sich wahrscheinlich nicht ändern wird, dann lass es als Zahl stehen. Wenn Sie Zweifel haben, erstellen Sie eine eindeutige Konstante, da die langfristige Wartung einfacher ist.
Tags und Links c++ magic-numbers