Магічне число (програмування)Поняття «Магічне число» в програмуванні має три значення:
Сигнатура данихМагічне число, або сигнатура, — цілочисельна або текстова константа, яка використовується для однозначної ідентифікації ресурсу або даних. Таке число саме по собі не має ніякого сенсу і може викликати здивування, зустрівшись у коді програми без відповідного контексту або коментаря, при цьому спроба змінити його на інше, навіть близьке за значенням, може спричинити абсолютно непередбачувані наслідки. З цієї причини такі числа іронічно називають магічними. В цей час ця назва міцно закріпилася як термін. Наприклад, будь-який відкомпільований клас мови Java починається з шістнадцятирічного «магічного числа» В UNIX-подібних операційних системах тип файлу зазвичай визначається за сигнатурою файлу, незалежно від розширення його назви. Для інтерпретації сигнатури файлу в них призначена стандартна утиліта Погана практика програмуванняТакож «магічними числами» називають погану практику програмування, коли у тексті програми зустрічається числове значення, сенс якого не очевидний. Наприклад, такий фрагмент, написаний на Java, буде поганим: drawSprite(53, 320, 240);
Людині, яка не є автором програми, важко зрозуміти, що таке 53, 320 або 240. Але якщо цей код переписати, все стає на свої місця: 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);
Тепер зрозуміло: ця інструкція виводить у центр екрана спрайт — перехрестя прицілу. В більшості мов програмування всі значення, які використовуються для таких констант, будуть пораховані ще на етапі компіляції й підставлені в місця їх використання. Тому така зміна вихідного тексту не погіршує швидкодії програми. Крім того, магічні числа — потенційне джерело помилок у програмі:
Магічні числа і кросплатформністьІноді магічні числа шкодять кросплатформності коду[1]. Річ у тому, що в Сі в 32- і 64-бітних ОС гарантується розмір типів Наприклад: const size_t NUMBER_OF_ELEMENTS = 10;
long a[NUMBER_OF_ELEMENTS];
memset(a, 0, 10 * 4); // неправильно — йдеться про те, що long дорівнює 4 байтам, використовується магічне число елементів
memset(a, 0, NUMBER_OF_ELEMENTS * 4); // неправильно — йдеться про те, що long дорівнює 4 байтам
memset(a, 0, NUMBER_OF_ELEMENTS * sizeof(long)); // не зовсім правильно — дублювання назви типу (якщо зміниться тип, то доведеться змінити й тут)
memset(a, 0, NUMBER_OF_ELEMENTS * sizeof(a[0])); // правильно, оптимально для динамічних масивів ненульового розміру
memset(a, 0, sizeof(a)); // правильно, оптимально для статичних масивів
Числа, які не є магічнимиНе всі числа потрібно переносити в константи. Наприклад, у такому коді на Delphi: for i:=0 to Count-1 do ...
сенс чисел 0 і 1 цілком зрозумілий. Див. такожПримітки
|
Portal di Ensiklopedia Dunia