Pojem „ magické číslo “ v programování má tři významy:
Magické číslo nebo podpis je celé číslo nebo textová konstanta používaná k jedinečné identifikaci zdroje nebo dat . Takové číslo samo o sobě nenese žádný význam a může způsobit zmatek, pokud se objeví v programovém kódu bez příslušného kontextu nebo komentáře , zatímco pokus o jeho změnu na jiné, byť hodnotou blízkou, může vést k naprosto nepředvídatelným následkům. Z tohoto důvodu byla taková čísla ironicky nazývána magická čísla . V současnosti je toto jméno pevně zakořeněno jako pojem . Například jakákoli kompilovaná třída jazyka Java začíná hexadecimálním „magickým číslem“ 0xCAFEBABE. Druhým známým příkladem je, že jakýkoli spustitelný soubor Microsoft Windows s příponou .exe začíná posloupností bajtů 0x4D5A(což odpovídá ASCII znakům MZ – iniciálám Marka Zbikowského , jednoho z tvůrců MS-DOSu ). Méně známým příkladem je neinicializovaný ukazatel v Microsoft Visual C++ (od verze 2005 Microsoft Visual Studio), který je v režimu ladění 0xDEADBEEF.
V operačních systémech podobných UNIX je typ souboru obvykle určen podpisem souboru, bez ohledu na jeho příponu. Poskytují standardní nástroj pro interpretaci podpisu souboru file.
Také „magická čísla“ jsou špatnou programátorskou praxí, když se ve zdrojovém textu vyskytuje číselná hodnota a její význam není zřejmý. Například takový úryvek napsaný v Javě by byl špatný:
drawSprite ( 53 , 320 , 240 );Pro někoho, kdo nenapsal program, je těžké pochopit, co je 53, 320 nebo 240. Ale pokud je tento kód přepsán, vše zapadne na své místo.
final int SCREEN_WIDTH = 640 ; final int SCREEN_HEIGHT = 480 ; final int SCREEN_X_CENTER = SCREEN_WIDTH / 2 ; final int SCREEN_Y_CENTER = SCREEN_HEIGHT / 2 ; final int SPRITE_CROSSHAIR = 53 ; ... drawSprite ( SPRITE_CROSSHAIR , SCREEN_X_CENTER , SCREEN_Y_CENTER );Nyní je to jasné: tento kód zobrazuje sprite ve středu obrazovky - zaměřovací kříž zaměřovače. Ve většině programovacích jazyků budou všechny hodnoty použité pro takové konstanty vypočteny v době kompilace a nahrazeny místy, kde jsou hodnoty použity ( konstanta fold ). Taková změna ve zdrojovém textu tedy nezhorší výkon programu.
Magická čísla jsou navíc potenciálním zdrojem chyb v programu:
Někdy magická čísla poškozují multiplatformní kód [1] . Jde o to, že v C v 32bitových a 64bitových operačních systémech je zaručena velikost typů char, shorta long long, zatímco velikost int, long, size_ta ptrdiff_tse může lišit (u prvních dvou, v závislosti na preferencích vývojářů kompilátorů, např. poslední dva, v závislosti na bitové hloubce cílového systému). Ve starém nebo špatně napsaném kódu se mohou vyskytovat „magická čísla“, která označují velikost typu – při přechodu na stroje s jinou bitovou hloubkou mohou vést k jemným chybám.
Například:
const size_t NUMBER_OF_ELEMENTS = 10 ; dlouhé a [ NUMBER_OF_ELEMENTS ]; memset ( a , 0 , 10 * 4 ); // špatně - předpokládá se, že délka je 4 bajty, používá magický počet prvků memset ( a , 0 , NUMBER_OF_ELEMENTS * 4 ); // špatně - předpokládá se, že long je 4 byte memset ( a , 0 , NUMBER_OF_ELEMENTS * sizeof ( long )); // ne zcela správně - duplikace názvu typu (pokud se typ změní, budete muset změnit i zde) memset ( a , 0 , NUMBER_OF_ELEMENTS * sizeof ( a [ 0 ])); // správné, optimální pro dynamická pole s nenulovou velikostí memset ( a , 0 , sizeof ( a )); // správné, optimální pro statická poleNe všechna čísla je nutné převádět na konstanty. Například kód v Delphi :
for i := 0 to Count - 1 do ...Význam čísel 0 a 1 je jasný a není třeba dalšího vysvětlování.