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