® Препроцессор просто заменяет один текст – другим
Ему вообще наплевать на синтаксис и всякие условности. Он просматривает текст, и заменяет одни его кусочки другими.
Что и на что заменяется, вы уже должны знать, но я на всякий случай напомню.
В случае директивы #include <stdio.h> сама эта строка будет заменена препроцессором на содержимое файла stdio.h.
В случае директивы #define FJ 11 все вхождения FJ заменяются на11. Кстати, это тоже не единственный вариант использования директивы #define. Но мы пока что коснемся только этого варианта.
Стоит отметить, что если FJ встретиться внутри имени какой-нибудь переменной или в названии оператора, то она естественно ни на что не заменится. Например, если есть переменная с именем kFJ, то она так и останется kFJ а не станет после обработки препроцессоромk11.
Теперь разберем пример, который был в тесте в нашей группе во Вконтакте.
Сразу же скажу правильный ответ. Да, эта программа скомпилируется и будет работать.
Теперь разберемся, почему же она будет скомпилирована.
Как я понял, большинство смутило то, что переменная s89 не объявлена, что и должно было бы привести к ошибке компиляции. Но, теперь вооружившись знаниями о работе препроцессора, разберемся, что же, на самом деле, получает компилятор для обработки. Итак, сначала запускается препроцессор, который получает для обработки следующий код:
#include <stdio.h>
#define G s89
int main (){
char G =10;
s89=12;
// комментарий
printf("%d %d\n", s89, G);
return 0;
}
Препроцессор начинает обрабатывать этот код и буквально сразу же встречает директиву #include <stdio.h>. Для него, как мы уже знаем, это команда на то, чтобы вставить вместо этой строчки содержимое файла stdio.h. Вставляем. Получившийся код я сюда выписывать не буду, иначе это займет очень много места.
Препроцессор продолжает обработку файла и встречает команду#define G s89. Это как мы знаем, команда на то, чтобы заменить G наs89.
После замены получим следующий код. (ниже приведен код только для функции main)
int main (){
char s89 =10;
s89=12;
printf("%d %d\n", s89, s89);
return 0;
}
Ну и походу дела, препроцессор удалит комментарий из программы, а точнее заменит его пустой строчкой.
Вот, в принципе, мы и ответили на вопрос: «Почему программа компилируется?»
Хоть многих и смутило, что в ней отсутствует переменная s89, разобравшись обстоятельно, видим, что она-то как раз есть, а вот переменной G нет. Именно такой код поступит на компиляцию. Нетрудно видеть, что он корректный.