From e8806547bb7d75c075e87b693b8575e75de82414 Mon Sep 17 00:00:00 2001 From: t0xa Date: Tue, 14 Oct 2025 22:43:50 +0300 Subject: [PATCH] Add some preprocessor learning --- c_modern_approach/Preprocessor/DESCRIPTION.md | 66 +++++++++++++++++++ c_modern_approach/Preprocessor/ellipsis.c | 11 ++++ .../{single_hashtag_op.c => main.c} | 0 3 files changed, 77 insertions(+) create mode 100644 c_modern_approach/Preprocessor/DESCRIPTION.md create mode 100644 c_modern_approach/Preprocessor/ellipsis.c rename c_modern_approach/Preprocessor/{single_hashtag_op.c => main.c} (100%) diff --git a/c_modern_approach/Preprocessor/DESCRIPTION.md b/c_modern_approach/Preprocessor/DESCRIPTION.md new file mode 100644 index 0000000..85d5fda --- /dev/null +++ b/c_modern_approach/Preprocessor/DESCRIPTION.md @@ -0,0 +1,66 @@ +# ellipsis operator +Ellipsis оператором в макросах называется: `...` +Что он делает (пример в `ellipsis.c`): +```c +#include +#define TEST(condition, ...) \ + ((condition) ? printf("Passed test: %s\n", #condition) : printf(__VA_ARGS__)) + +int main() { + int voltage = 30; + int max_voltage = 20; + TEST(voltage <= max_voltage, "Voltage %d exceeds %d\n", voltage, max_voltage); + max_voltage = 40; + TEST(voltage <= max_voltage, "Voltage %d exceeds %d\n", voltage, max_voltage); +} +``` +Тут у нас происходит следующее: +1. `...` объединяет в себе параметры, которые идут после обязательных. В нашем случае получается что +туда попадают аргументы, которые идут плсле `condition`. +2. `__VA_ARGS__` - идентификатор, который может появляеться только в случае использования `...` и представляет +из себя аргументы, которые относятся к `...` +3. Дальше внутри программы препроцессор раскроет конструкцию: +```c +TEST(voltage <= max_voltage, "Voltage %d exceeds %d\n", voltage, max_voltage); +``` +в что-то подобное: +```c +((voltage <= max_voltage)? +printf("Passed test: %s\n", "voltage <= max_voltage"): +printf("Voltage %d exceeds %d\n", voltage, max_voltage)); +``` +Где последняя строка это как раз то, что представляет из себя `printf(__VA_ARGS__)` +# static +Зачем нужно ключевое слово `static`. Есть 3 варианта: +1. Статичные глобальные переменные +file1.c +```c +static int counter = 0; +``` +Данная цель - сделать эту переменнюу приватную для файла `file1.c`, т.е. в других файлах данная +переменная доступна не будет +2. Статичные локальные переменные +```c +void count_calls() +{ + static int count = 0; + count++; + printf("Called %d times\n", count); +} +``` +Тут переменная `count` будет доступна между вызовами функции, т.е. каждый вызов функции будет происходить +добавление 1 к `count` +``` +Called 1 times +Called 2 times +Called 3 times +``` +3. Статичные функции +```c +static void helper() +{ + ... +} +``` +Тут делает функцию доступной только в файле, где объявлен +# __func__ diff --git a/c_modern_approach/Preprocessor/ellipsis.c b/c_modern_approach/Preprocessor/ellipsis.c new file mode 100644 index 0000000..6424f5d --- /dev/null +++ b/c_modern_approach/Preprocessor/ellipsis.c @@ -0,0 +1,11 @@ +#include +#define TEST(condition, ...) \ + ((condition) ? printf("Passed test: %s\n", #condition) : printf(__VA_ARGS__)) + +int main() { + int voltage = 30; + int max_voltage = 20; + TEST(voltage <= max_voltage, "Voltage %d exceeds %d\n", voltage, max_voltage); + max_voltage = 40; + TEST(voltage <= max_voltage, "Voltage %d exceeds %d\n", voltage, max_voltage); +} diff --git a/c_modern_approach/Preprocessor/single_hashtag_op.c b/c_modern_approach/Preprocessor/main.c similarity index 100% rename from c_modern_approach/Preprocessor/single_hashtag_op.c rename to c_modern_approach/Preprocessor/main.c