Add some preprocessor learning
This commit is contained in:
parent
f4401884b8
commit
e8806547bb
3 changed files with 77 additions and 0 deletions
66
c_modern_approach/Preprocessor/DESCRIPTION.md
Normal file
66
c_modern_approach/Preprocessor/DESCRIPTION.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# ellipsis operator
|
||||
Ellipsis оператором в макросах называется: `...`
|
||||
Что он делает (пример в `ellipsis.c`):
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#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__
|
||||
11
c_modern_approach/Preprocessor/ellipsis.c
Normal file
11
c_modern_approach/Preprocessor/ellipsis.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
||||
Loading…
Reference in a new issue