Подтвердить что ты не робот

Объем макросов в C?

Как оцениваются эти макросы?

# define i 20
void fun();

int main(){
  printf("%d",i);
  fun();
  printf("%d",i);
  return 0;
}

void fun(){
  #undef i
  #define i 30
}

дает результат как 2020, но в то время как

# define i 20
void fun(){
  #undef i
  #define i 30
}

int main(){
  printf("%d",i);
  fun();
  printf("%d",i);
  return 0;
}

дает результат как 3030. Пожалуйста, объясни. Спасибо.

4b9b3361

Ответ 1

C Препроцессор работает сверху вниз, независимо от вызовов функций. Он эффективен с этой точки (строки) в любом файле, который определяется макросом, до соответствующего undef или до конца единицы перевода.

Итак, ваш код станет,

# define i 20
               // from now on, all token i should become 20
void fun();
int main()
{
  printf("%d",i);   // printf("%d",20);
  fun();
  printf("%d",i);   // printf("%d",20);
  return 0;
}
void fun()
{
#undef i
              // from now on, forget token i
#define i 30
              // from now on, all token i should become 30
}

Ваш второй код станет,

# define i 20
               // from now on, all token i should become 20
void fun()
{
#undef i
               // from now on, forget i
#define i 30
               // from now on, all token i should become 30
}
int main()
{
  printf("%d",i);    //  printf("%d",30);
  fun();
  printf("%d",i);    // printf("%d",30);
  return 0;
}

Ответ 2

Там вообще не задействован. Макросы обрабатываются на этапе предварительной обработки отдельно и независимо от этапа компиляции и не имеют понятия области С. Ваши примеры могут быть такими же легко:

#define i 20

void fun();

int main()
{
  printf("%d",i);
  fun();
  printf("%d",i);
  return 0;
}

void fun()
{
}

#undef i
#define i 30

и

#define i 20
#undef i
#define i 30

void fun()
{
}

int main()
{
  printf("%d",i);
  fun();
  printf("%d",i);
  return 0;
}

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

Ответ 3

Просто нет области.

Макросы заменяются препроцессором. Таким образом, их расширение определяется их положением в источнике, сверху вниз.

Ответ 4

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

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

Ответ 5

Макросы вступают в силу с текстом источника, на отдельном этапе перед компиляцией. Макросы больше не существуют в любой форме в скомпилированном коде, и они не оцениваются во время выполнения.

Независимо от того, какое определение макроса действует при вызове макроса (во время текстового сканирования источника), будет заменено исходным текстом.

Ответ 6

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

Объем символа препроцессора ограничен одной единицей перевода. A #define в одном блоке перевода не имеет отношения к другой единицы перевода.

Объем символа препроцессора - это область токенов, следующая за директивой, которая #defines обозначает ее символ. После этого события макросов распознаются и расширяются в соответствии с правилами управления. Макросы макропроцессора не являются рекурсивными. Если последовательность замещающего токена содержит то, что выглядит как вызовы символа, который определяется, они не распознаются как таковые. Вот почему область действия начинается после директивы. Однако это все еще верно, когда макрос переопределяется; переопределение является особенным и должно соответствовать правилу, что оно совпадает с исходным определением. (Точные правила одинаковости находятся в стандарте).

Объем символа препроцессора заканчивается концом единицы перевода или раньше, если он подчиняется директиве #undef.

Таким образом, объем символа препроцессора является по существу областью текста единицы перевода, рассматриваемой как поток токенов препроцессора, в котором этот символ имеет право на распознавание и подстановку.

Ответ 7

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

В вашем первом примере кода он выдает 2020, несмотря на то, что вызывает функцию fun() в основной функции, которая предположительно должна изменить значение я до 30, но поскольку функция fun появляется ниже, где она была вызвана, значение не изменяется поскольку препроцессор еще не достиг этой точки.

В вашем втором примере кода он выдает 3030, потому что функция fun находится выше основной функции. Поэтому обратное происходит, когда препроцессор уже прошел через функцию fun и изменил значение я на 30