# 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__