0Pricing
C Academy · Урок

Условная компиляция

ifdef и макросы

«Условная компиляция» — бесплатный урок C Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C Academy содержит 4 уроков всего.

Препроцессор

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

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

Определение макросов

#define создаёт макрос. Без значения это просто флаг, наличие которого можно проверить позже.

Макросы, похожие на объекты, заменяют имя текстом; флаги лишь отмечают, что нечто установлено.

#define MAX_USERS 100   /* value macro */
#define DEBUG          /* flag macro */

ifdef и ifndef

#ifdef NAME оставляет блок только в том случае, если NAME определён. #ifndef оставляет его только в том случае, если NAME не определён.

Здесь отладочная печать существует только в отладочных сборках. Если DEBUG не определён, компилятор вообще не увидит эту строку.

#include <stdio.h>
#define DEBUG

int main(void) {
#ifdef DEBUG
    printf("debug: starting\n");
#endif
    printf("running\n");
    return 0;
}

if, elif, else

#if вычисляет константное целочисленное выражение. Объединяйте его с #elif и #else для многостороннего выбора.

Так код выбирается на основе макроса с номером версии.

#include <stdio.h>
#define VERSION 2

int main(void) {
#if VERSION >= 2
    printf("new feature on\n");
#else
    printf("legacy mode\n");
#endif
    return 0;
}

Оператор defined

Внутри #if можно проверить, определено ли имя, с помощью defined(NAME), а также объединить проверки операторами && и ||.

Это гибче, чем #ifdef, который может проверять только одно имя.

#if defined(LINUX) && !defined(EMBEDDED)
    /* desktop Linux code */
#endif

Определение во время компиляции

Необязательно жёстко задавать макросы в исходном коде. Флаг -D определяет их в командной строке.

Так системы сборки переключают возможности без изменения исходного кода. -DDEBUG эквивалентен #define DEBUG в начале каждого файла.

gcc -DDEBUG -DVERSION=3 -o app app.c

Определение платформы

Компиляторы заранее определяют макросы, описывающие целевую платформу. Используйте их для написания переносимого кода.

  • _WIN32 — Windows (32- или 64-разрядная)
  • __linux__ — Linux
  • __APPLE__ — macOS / iOS

Используйте эти условия, чтобы вызывать правильный программный интерфейс платформы.

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

Защита от повторного подключения заголовка

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

При первом подключении определяется макрос защиты; последующие подключения пропускают тело, поскольку макрос уже определён.

#ifndef UTILS_H
#define UTILS_H

int add(int a, int b);

#endif /* UTILS_H */

Закомментирование кода

#if 0 ... #endif надёжно отключает блок, даже если он уже содержит комментарии.

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

#if 0
    legacy_function();   /* disabled for now */
    /* with internal comments too */
#endif

Проверка результата препроцессора

Чтобы точно увидеть, что будет компилировать компилятор, запустите только препроцессор с параметром -E.

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

gcc -E app.c | less

Переключатели возможностей на практике

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

Измените один #define, и каждый защищённый блок во всех файлах отреагирует на это. Так дополнительные возможности остаются чётко отделены от основного кода.

#include <stdio.h>
#define FEATURE_LOGGING 1

int main(void) {
#if FEATURE_LOGGING
    printf("logging enabled\n");
#endif
    printf("app ready\n");
    return 0;
}

Быстрая проверка

Предскажите поведение определения из командной строки.

Итоги

Теперь Вы управляете условной компиляцией:

  • #ifdef/#ifndef проверяют, определён ли макрос
  • #if/#elif/#else вычисляют константные выражения с помощью defined()
  • -DNAME определяет макросы из командной строки для переключения возможностей
  • Предопределённые макросы платформы обеспечивают переносимость кода, а защита заголовков предотвращает повторное подключение

Далее: организация кода в нескольких файлах.

Часто задаваемые вопросы

Урок «Условная компиляция» бесплатный?

Да — полный текст урока «Условная компиляция» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C Academy, подпишись на CoddyKit PRO. Курс C Academy содержит 4 уроков всего.

Чему я научусь в уроке «Условная компиляция»?

ifdef и макросы Ты практикуешь C Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C Academy?

Предыдущий опыт не требуется. C Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Условная компиляция»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C Academy?

Да. Каждый урок C Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Условная компиляция
  2. Многофайловые проекты
  3. Makefile
  4. Статические и разделяемые библиотеки
← Назад к C Academy