Ответ довольно прост.Препроцессор работает с текстом в качестве входных данных и имеет текст в качестве выходных данных.Примерами этого являются старые unix-команды m4, cpp (предварительный процессор C), а также unix-программы, такие как roff и nroff и troff, которые использовались (и остаются) для форматирования man-страниц (unix-команда «man») или форматирования текста.для печати или набора текста.Препроцессоры очень просты, они ничего не знают о «языке текста», который они обрабатывают.Другими словами, они обычно обрабатывают естественные языки.Препроцессор C помимо своего имени, например, распознает только #define, #include, #ifdef, #ifndef, #else и т. Д., И если вы используете #define MACRO, он пытается «развернуть» этот макрос везде, где он его находит.Но это не обязательно должен быть программный текст на C или C ++, это также может быть роман, написанный на итальянском или греческом.Компиляторы, которые пересекают компиляцию на другой язык, обычно называют переводчиками.Таким образом, старый «компилятор» cfront для C ++, который генерировал код C, был переводчиком C ++.Препроцессоры и более поздние переводчики использовались исторически, потому что старым машинам просто не хватало памяти, чтобы сделать все в одной программе, а вместо этого это делали специализированные программы и с диска на диск.Типичная программа на С будет составлена из различных источников.И процесс сборки будет управляться с помощью make .В наши дни препроцессор C обычно встроен непосредственно в компилятор C / C ++.Типичный запуск make вызывает CPP для файлов * .c и записывает вывод в другой каталог, откуда либо компилятор C C компилирует его прямо в машинный код, либо чаще выводит код ассемблера в виде текста.Примечание: компилятор c проверяет только синтаксис, на самом деле он не заботится о безопасности типов и т. Д. Затем ассемблер берет этот код ассемблера и выводит файл * .o, который позже может быть связан с другими файлами * .o и * .lib.файлы в исполняемую программу.OTOH, скорее всего, у вас есть правило make, которое не вызывает компилятор C, а команду lint, анализатор языка C, которая ищет типичные ошибки и ошибки (которые игнорируются компилятором c).Довольно интересно посмотреть на lint, nroff, troff, m4 и т. Д. В Википедии (или на терминале вашей машины, использующем man); D