С Константы - PullRequest
       3

С Константы

4 голосов
/ 29 июня 2009

Если я объявлю константу, скажем

"# определить МЕСЯЦЫ = 12" в C Я знаю, что директива препроцессора заменит все используемые МЕСЯЦЫ, но я хочу знать, выделена ли память для хранения 12 ??, если да, какой будет метка и какой будет тип данных.

Ответы [ 9 ]

20 голосов
/ 29 июня 2009

Скорее всего, вы хотите, чтобы ваше определение было таким:

#define MONTHS 12

/* some code here... */

int payAnnual = payMonthly * MONTHS;

Для ответа на ваш вопрос память не будет использоваться. Препроцессор не знает о таких понятиях, как переменные и память. По сути, это автоматический текстовый редактор. Он заменяет любое вхождение символа МЕСЯЦЕВ на 12.

Поскольку препроцессор настолько глуп, как правило, предпочтительно использовать переменную const. Это дает вам преимущество проверки типов и может облегчить чтение ошибок компилятора. И пока вы объявляете его статическим, переменная будет оптимизирована. (Если вы не объявляете глобальную переменную static в C, по умолчанию она будет экспортирована, поэтому компилятор не сможет полностью ее оптимизировать.)

static const int MONTHS = 12;
9 голосов
/ 29 июня 2009

Синтаксис на самом деле:

#define MONTHS 12

Нет = знак разрешен. И никакая память не выделяется в скомпилированном коде для MONTHS, и у него нет типа данных.

6 голосов
/ 29 июня 2009

Препроцессор просто вносит символические изменения в исходный код. Следовательно, код будет вести себя так же, как если бы вы просто заменили все вхождения МЕСЯЦЕВ на 12 самостоятельно. И, следовательно, при его использовании память не влияет.

Использование предкомпиляционных определений - отличный способ повысить уровень абстракции вашего кода без влияния на производительность памяти.

С уважением

3 голосов
/ 29 июня 2009

Весь смысл препроцессора C в том, что он заменяет его перед компиляцией любого кода. поэтому # -определяемые константы не сохраняются в той точке, в которой они определены, только при их использовании.

3 голосов
/ 29 июня 2009

Is not #define - просто найдите n replace препроцессором до того, как он попадет на стадию компиляции. Он заменяет все вхождения символа значением в источнике. Затем компилятор вступает во владение.
Так что не думайте, что память выделена.

3 голосов
/ 29 июня 2009

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

Например:

char something[1024*MONTHS];// 1024*12 bytes

в противном случае константа никогда не переживает время компиляции. И у него нет типа данных.

2 голосов
/ 29 июня 2009

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

Так же, как если бы вы должны были объявить

#define FOO "bar"

Тогда вхождения FOO будут заменены типичным использованием «bar», являющегося указателем на некоторое местоположение строковой константы в объектном файле программы, отображенном в памяти.

Разницы на самом деле нет.

0 голосов
/ 29 июня 2009

если 12 выделено, зависит от использования и вообще не имеет никакого отношения к препроцессору

Somefunction(MONTH);

расширится до

Somefunction(12);

12 здесь должно быть где-то сохранено, в в этом случае оно будет статически сохранено в исполняемом файле. Тип, скорее всего, будет зависеть от того, что Somefunction принимает в качестве аргумента (или от того, что компилятор решит, лучше всего подходит для этого использования). Нет метки «12».

Предварительная обработка выполняется перед фактической компиляцией, как кто-то уже писал, она похожа на автоматический текстовый редактор. Таким образом, этап компиляции полностью не знает, что сделал препроцессор.

0 голосов
/ 29 июня 2009

Нет,

weeks = 12 * 4;

Точно так же, как:

weeks = MONTHS * 4;

Занимает ли 12 память? Нет, следовательно, и 1009 * МЕСЯЦЕВ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...