2012-06-18 2 views
6

Я не могу понять, в чем разница между:#define VS Variable

#define WIDTH 10 

и

int width = 10; 

Каковы преимущества использования первой или второй?

+0

Прочитано [this] (http://stackoverflow.com/questions/1674032/static-const-vs-define-in-c) вопрос тоже – gahcep

ответ

4

Ну, есть большая разница. Вы можете изменить значение width, вы можете принять его адрес, вы можете запросить его размер и так далее. С WIDTH он будет просто заменен константой 10 везде, поэтому выражение ++WIDTH не имеет никакого смысла. Ono с другой стороны, вы можете объявить массив с WIDTH элементами, тогда как вы не можете объявить массив с width элементами.

Подведение итогов: значение WIDTH известно во время компиляции и не может быть изменено. Компилятор не выделяет память для WIDTH. Наоборот, width является переменной с начальным значением 10, его дальнейшие значения не известны во время компиляции; переменная получает свою память от компилятора.

+0

так что макрос WIDTH нельзя изменить, и он используется, чтобы указать что-то «классическое» в программе? Как #define AUTHOR «Myself» ?? – Rrjrjtlokrthjji

+1

@Nick: макросы могут использоваться тысячами разных способов. Вы можете определить макрос, чтобы содержать кусок кода: '#define CHECKSUCCESS (n), если (n) возвращает n; else {} '. То, как вы предлагаете, также является допустимым использованием. – Vlad

+0

@ Ник: Кстати, с помощью макросов вы можете делать странные вещи, например '#define sin (x) cos (x)'! Используйте с осторожностью. – Vlad

2

WIDTH - это макрос, который будет заменен значением (10) на preprocessor, тогда как width является переменной.

Когда вы # определите макрос (например, WIDTH здесь), препроцессор просто выполнит замену текста до того, как программа будет передана компилятору. т. е. где бы вы не использовали WIDTH в своем коде, он просто будет заменен на 10.

Но когда вы делаете int width=10, переменная жива

+0

все еще не получает его. Не могли бы вы объяснить это лучше? – Rrjrjtlokrthjji

+0

@Nick обновлено сейчас .. –

+1

@Nick Я надеюсь, что вы новичок в программировании на С, я бы предпочел вам обратиться к книге. – Viswesn

0

Сначала краткая справка: перед тем, как скомпилированными, C файла предварительно обрабатываются. Предварительный процессор проверяет на #include и #define заявления.

В вашем случае, что #define оператор сообщает препроцессор изменить каждую строку WIDTH в исходном коде со строкой 10. Когда файл получает , скомпилированный на следующем шаге, каждое событие WIDTH будет фактически 10. Теперь, разница между

#define WIDTH 10 

и

int width = 10; 

является то, что первое можно рассматривать как значение constant, в то время как второй является нормальной переменной, значение которого может быть изменено.

+0

'const', похоже, был с C89. – nhahtdh

7

В чем разница между двумя?

Первый является Macro, а второй представляет собой Объявление переменной.

#define WIDTH 10 является preprocessor directive, который позволяет указать имя (WIDTH) и его замещающий текст (10). Препроцессор анализирует исходный файл, и каждое вхождение имени заменяется связанным с ним текстом. Компилятор вообще никогда не видит имя макроса, то, что он видит, является замененным текстом.

Объявление переменной оценивается самим компилятором. Он сообщает компилятору объявить переменную с именем width и типа int, а также инициализирует ее значением 10.
Компилятор знает эту переменную своим именем width.

Кому хотелось бы? И почему?

Обычно рекомендуется использовать постоянные переменные времени компиляции по сравнению с #define. Так Ваша переменная декларация должна быть:

const int width = 10; 

Есть целый ряд причин для выбора компиляции констант времени над #define, а именно:

Scope Based Механизм:

Объем #define ограничен файлом, в котором он определен. Итак, #defines, которые создаются в одном исходном файле, являются NOT доступны в другом исходном файле. Короче говоря, #define s не уважают области. Обратите внимание, что переменные const могут быть ограничены. Они подчиняются всем правилам определения области.


избежать Weird магических чисел во время ошибки компиляции:

Если вы используете #define те заменяется препроцессор во время прекомпиляции Так что, если вы получите сообщение об ошибке во время компиляции, то будет запутывать, потому что сообщение об ошибке не будет ссылаться на имя макроса, а на значение, и оно появится внезапно, и можно было бы потратить много времени на его отслеживание в коде.


Удобство отладки:

Также по тем же причинам, указанным в # 2, при отладке #define не будет оказывать никакой помощи на самом деле.

+0

Это символ, а не макрос. – Joey

+0

Вопрос отмечен 'c', вы уверены в пространствах имен и классах? – Vlad

+0

Одним из преимуществ DEFINE при программировании в встроенных системах является то, что DEFINE никогда не будет использовать память, где переменная должна быть где-то сохранена. – RedX

0

Один #define обрабатывается препроцессором, если находит WIDTH в исходном коде и заменяет его 10, все это делает основной подмена среди прочего, другой int width = 10; обрабатывается компилятором, это будет создавать записи в таблицу поиска, генерировать двоичные файлы, чтобы выделить достаточное количество памяти в стеке, в зависимости от того, где его определить, и скопировать значение 10 в эту ячейку памяти.

Итак, это не что иное, как метка для константы, а другая - переменная во время выполнения.

Вы можете использовать препроцессоры для более быстрого выполнения, поскольку переменные должны быть выделены в стеке, за счет того, что они не изменяются во время выполнения.

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