Магическое число (программирование)Понятие «Магическое число» в программировании имеет три значения:
Сигнатура данныхМагическое число, или сигнатура, — целочисленная или текстовая константа, используемая для однозначной идентификации ресурса или данных. Такое число само по себе не несёт никакого смысла и может вызвать недоумение, встретившись в коде программы без соответствующего контекста или комментария, при этом попытка изменить его на другое, даже близкое по значению, может привести к абсолютно непредсказуемым последствиям. По этой причине подобные числа были иронично названы магическими. В настоящее время это название прочно закрепилось как термин. Например, любой откомпилированный класс языка 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