Käsitteellä " Maaginen numero " ohjelmoinnissa on kolme merkitystä:
Maaginen luku tai allekirjoitus on kokonaisluku- tai tekstivakio , jota käytetään yksilöimään resurssi tai data . Tällaisella numerolla ei sinänsä ole mitään merkitystä ja se voi aiheuttaa hämmennystä, jos se esiintyy ohjelmakoodissa ilman asianmukaista kontekstia tai kommenttia , kun taas yritys muuttaa se toiseksi, jopa lähellä arvoa, voi johtaa täysin arvaamattomiin seurauksiin. Tästä syystä tällaisia numeroita on ironisesti kutsuttu maagisiksi numeroiksi . Tällä hetkellä tämä nimi on lujasti juurtunut termiksi . Esimerkiksi mikä tahansa käännetty Java -kieliluokka alkaa heksadesimaaliluvulla "magic number" 0xCAFEBABE. Toinen hyvin tunnettu esimerkki on, että mikä tahansa Microsoft Windows -suoritettava tiedosto, jonka laajennus on .exe, alkaa tavujonolla 0x4D5A(joka vastaa ASCII - merkkejä MZ - Mark Zbikowskin , yhden MS-DOS :n luojista, nimikirjaimet ). Vähemmän tunnettu esimerkki on alustamaton osoitin Microsoft Visual C++:ssa (vuodesta 2005 lähtien Microsoft Visual Studion versio), joka virheenkorjaustilassa on 0xDEADBEEF.
UNIX-tyyppisissä käyttöjärjestelmissä tiedoston tyyppi määräytyy yleensä tiedoston allekirjoituksen mukaan, riippumatta sen nimitunnisteesta. Ne tarjoavat tavallisen apuohjelman tiedoston allekirjoituksen tulkitsemiseen file.
Myös "maagiset numerot" on huono ohjelmointikäytäntö, kun lähdetekstissä esiintyy numeerinen arvo ja sen merkitys ei ole ilmeinen. Esimerkiksi tällainen Java -kielellä kirjoitettu katkelma olisi huono:
drawSprite ( 53 , 320 , 240 );Sen, joka ei ole kirjoittanut ohjelmaa, on vaikea ymmärtää, mikä on 53, 320 tai 240. Mutta jos tämä koodi kirjoitetaan uudelleen, kaikki loksahtaa paikoilleen.
lopullinen int SCREEN_WIDTH = 640 ; lopullinen int SCREEN_HEIGHT = 480 ; lopullinen int SCREEN_X_CENTER = SCREEN_WIDTH / 2 ; lopullinen int SCREEN_Y_CENTER = SCREEN_HEIGHT / 2 ; lopullinen int SPRITE_CROSSHAIR = 53 ; ... drawSprite ( SPRITE_CROSSHAIR , SCREEN_X_CENTER , SCREEN_Y_CENTER );Nyt se on selvää: tämä koodi näyttää spriten näytön keskellä - tähtäimen hiusristikon. Useimmissa ohjelmointikielissä kaikki tällaisille vakioille käytetyt arvot lasketaan käännöshetkellä ja korvataan paikkoihin, joissa arvoja käytetään ( vakiokerta ). Siksi tällainen muutos lähdetekstissä ei heikennä ohjelman suorituskykyä.
Lisäksi maagiset numerot ovat mahdollinen virhelähde ohjelmassa:
Joskus maagiset numerot vahingoittavat alustojen välistä koodia [1] . Asia on siinä, että C :ssä 32- ja 64-bittisissä käyttöjärjestelmissä , ja -tyyppien koko charon shorttaattu long long, kun taas int, long, size_tja koko ptrdiff_tvoi vaihdella (kahdelle ensimmäiselle kääntäjien kehittäjien mieltymyksistä riippuen kaksi viimeistä kohdejärjestelmän bittisyvyydestä riippuen). Vanhassa tai huonosti kirjoitetussa koodissa voi olla "maagisia numeroita", jotka osoittavat tyypin koon - siirryttäessä koneisiin, joilla on eri bittisyvyys, ne voivat johtaa hienovaraisiin virheisiin.
Esimerkiksi:
const size_t NUMBER_OF_ELEMENTS = 10 ; pitkä a [ NUMBER_OF_ELEMENTS ]; memset ( a , 0 , 10 * 4 ); // väärin - pitkän oletetaan olevan 4 tavua, käyttää maagista elementtien lukumäärää memset ( a , 0 , NUMBER_OF_ELEMENTS * 4 ); // väärin - pitkän oletetaan olevan 4 tavua memset ( a , 0 , NUMBER_OF_ELEMENTS * sizeof ( long )); // ei täysin oikein - tyypin nimen kopio (jos tyyppi muuttuu, joudut muuttamaan myös täällä) memset ( a , 0 , NUMBER_OF_ELEMENTS * sizeof ( a [ 0 ])); // oikea, optimaalinen nollasta poikkeaville dynaamisille taulukoille ( a , 0 , sizeof ( a ) ); // oikein, optimaalinen staattisille taulukoilleKaikkia lukuja ei tarvitse muuntaa vakioiksi. Esimerkiksi koodi Delphissä :
for i := 0 to Count - 1 do ...Numeroiden 0 ja 1 merkitys on selvä, eikä sen enempää selittelyä tarvita.