Меняется ли понятие «магического числа» с языка на язык? - PullRequest
1 голос
/ 16 марта 2011

Возьмите следующий код на C / C ++, например:

int foo[] = {0, 0, 0, 0};

Нет магических чисел, верно?
Теперь "эквивалент" Python этого будет:

foo = [0, 0, 0, 0]

Все еще нет магических чисел.
Однако в Python то же самое можно записать так:

foo = [0] * 4

И теперь у нас действительно есть магическое число.Или мы?
Я предполагаю, что эти и другие подобные вещи присутствуют на этих и других языках.

Ответы [ 5 ]

11 голосов
/ 16 марта 2011

Не каждое число является магической константой .Причина 4 и четыре 0 - магические числа (на любом языке) в том, что совершенно неясно , почему это число 4, а не любое другое число.

Например, в контексте игры, в которую играют с хорошо известным шестигранным кубиком

def roll_die():
    return random.randint(1,6)

этот код не имеет магических чисел, потому что очень легко увидеть, где числапришли из.

С другой стороны, может быть трудно угадать, какие числа знают другие программисты.Например, не все могут знать количество карт в колоде, поэтому имеет смысл использовать именованную константу там.

Это полностью зависит от контекста, является ли число «магическим» или нет, ононе имеет ничего общего с языком.Если вы сомневаетесь, назовите свои константы просто для безопасности.

5 голосов
/ 16 марта 2011

Чем это отличается от (в C или C ++):

int foo[4] = {0};

?

Размер массива во всех этих случаях является магическим числом.

0 голосов
/ 16 марта 2011

См. Код ниже. Это особенность языка c.

  int arr[] = { [0 ... 4]=3,[7]=7,[8 ... 12]=12,[15]=0};

совпадает с

int arr [] = {3, 3, 3, 3, 3, 0, 0, 7, 12, 12, 12, 12, 12, 0, 0, 0};

0 голосов
/ 16 марта 2011

Весь ваш вопрос показывает, что концепция «магических чисел» и правила, запрещающие использование «магических чисел» в вашей программе, абсолютно идиотичны. Правила против магических чисел - это плохое приближение людей, которые не понимают, что они делают, более разумного правила против жесткого кодирования в нескольких местах значений, которые должны совпадать или зависеть друг от друга. Например, этот код является вполне разумным, если длина буфера не должна соответствовать чему-либо еще в программе или реальном мире:

char buf[100];
snprintf(buf, sizeof buf, ...);

Но этот код очень плохой:

char buf[100];
snprintf(buf, 100, ...);

Конечно, в реальном мире, вероятно, - это , то, что вы хотите, чтобы размер буфера совпадал, например, максимальное количество цифр, необходимое для печати целого числа определенного размера. В этом случае вы можете захотеть что-то вроде:

char buf[3*sizeof(int)+3];
snprintf(buf, sizeof buf, ...);

И если вы считаете CHAR_BIT переменным, вы можете заменить 3 на формулу в терминах CHAR_BIT. В любом случае константы, фигурирующие в выражении, не являются «злыми магическими числами».

В вашем примере, если размерность массива зависит от какой-то другой переменной, то все три определения массива являются плохой практикой. Но если измерение 4 является фундаментальным для того, что вы делаете, я не вижу в этом ничего плохого.

Конечно, то, что вы делаете, может иногда меняться во время жизни кода, но для этого и нужна документация. Нельзя ожидать, что код справится с возможным возможным изменением цели в будущем без некоторого уровня модификации, и, пока вы задокументировали его первоначальное назначение и контракты, не должно быть трудным для кого-то, кто изменяет их, находить части кода это нужно изменить.

0 голосов
/ 16 марта 2011

Магические числа, насколько я понимаю, являются значениями доменов (используются при расчете, индексы в элементах отображения). Идея их одинакова на любом языке. В вашем примере это зависит от того, для чего предназначены эти массивы.

...