static double m = 30000;
double foo(double x, double y) {
return x/m + y;
}
Это ничего тебе не даст. Для выполнения вычислений необходимо создать копию m. Также, если вы делаете:
double bar( double x, double y) {
m += x + y;
return m;
}
Тогда все вызовы bar изменят m. Статические переменные вне функций (или классов) на самом деле являются глобальными переменными с файловой областью. Другие файлы не могут получить к ним доступ через extern
Статические переменные внутри функции по-прежнему похожи на глобальные переменные, за исключением того, что даже другие функции в том же файле не могут видеть их напрямую.
const double m = 30000;
Это лучше и во многих случаях лучше. Если компилятор видит эту глобальную константу, а затем видит ссылку на m, то он знает, что вместо того, чтобы генерировать код для загрузки значения из того места, где оно когда-либо было (что, вероятно, сначала требует загрузки буквального адреса в регистр) в регистр или позицию стека для выполнения вычислений он может просто сделать регистр равным 30000 или иногда генерировать инструкцию с закодированным 30000 прямо там.
Недостатком этого является то, что компилятор должен предположить, что другие исходные файлы захотят прочитать m, и должен фактически сохранить копию как переменную (но постоянную переменную) в объектном файле.
Я не уверен, что это стандарт, но иногда вы можете сделать extern const double m = 30000;
, и компилятор будет использовать 30000 для оптимизации и предположить, что в другом файле действительно есть копия m, которая будет храниться в исполняемом файле. Вы также можете сделать static const double m = 30000;
, и компилятор может предположить, что никто другой не будет ожидать, что копия m будет сохранена в объектном коде, сгенерированном из этого исходного файла.
Делает
#define m 30000
является более рискованным. Вы не получите предупреждение или ошибку, если ранее был объявлен другой m как переменная, константа или функция. Кроме того, для макросов препроцессора, подобных этому, легко испортить. Например:
#define BASE_ADDRESS 48
#define MY_OFFSET 9
#define MY_ADDRESS BASE_ADDRESS+MY_OFFSET
...
return MY_ADDRESS*4;
Да, это глупый пример, но как это выглядит после того, как препроцессор закончит с ним
...
return 48+9*4;
Который
return 48+(9*4);
И это не то, что вы, вероятно, хотели.
Еще одно место, где макросы плохи, — это когда у вас есть большие константы, такие как строки. Строки требуют, чтобы к ним можно было обращаться по указателю, и их труднее оптимизировать, чем целые числа и литералы с плавающей запятой или постоянные числа. Вы могли бы легко создать очень большую программу, если бы у вас было много таких вещей, как:
#define JIM "Jim"
#define JOHN "John"
а затем использовали JIM и JOHN во всех ваших программах, потому что компилятор может не увидеть, что вам действительно нужны строки «Джом» и «Джон» только один раз в программе.
При этом нередко можно увидеть, как константы объявляются таким образом, и часто они правильно делаются людьми, которые знают, что делают.
person
nategoose
schedule
09.04.2010