Видео на Youtube: https://youtu.be/-NO8gfHzg4Q
- Каламбур типов
- Типобезопасность
- Параметрический — Перегрузка — Приведение типов — …
- У всех есть — нам тоже надо! https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D0%B8%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
- Меньше думать о типе переменной—аргумента—значения—…
- Больше возможностей неподготовленным пользователям библиотеки
- Использовать традицию узкоспециализированных классов
- Программировать на Си модно-структурно–почти объектно
- Неявное приведение типов
strtol()иstrtod()из<stdlib.h>(ну иitoa()туда же)- Указатель
voidможет указывать на что угодно - Макрос
_Generic(стандарт C11) - Тип данных «структура» (
struct)
struct dollar {
int d;
char * ru;
char * en;
};
struct dollar D = {.d = 100 }
struct dollar R = {.ru = "сто"}
// ? D==R - Тип данных «объединение» (
union)
struct dollar {
char * type;
union {
int d;
char * ru;
char * en;
};
};
struct dollar D = {type = "integer", .d = 100 }
struct dollar R = {type = "по-русски", .ru = "сто"}- (может пригодиться) Не-число
NaNиз модуля<math.h>(компиляция!) printf-подобные функции и__attribute__- Опция
transparent_unionв__attribute__(не стандарт, толькоgcc) - Макросы работают только с литералами — то есть с текстом программы
- Расширение структурных типов через анонимные внутренние структуры
int == charint x = 7; double y = x + 0.0;NULLавтоматом приводится к типизированному указателюintвообще пожирает всё, что можно
printf(”%d\n”, i);— это как-то перебор- Пример: приучаем к программированию на C людей, покусанных JavaScript’ом
- Пока жить без переменных
- Пока спрятать шаблоны вывода
- Начать с печати зашитых в код чисел и слов
- Терпеть отсутствие точки с запятой
- Выводить и данные, и их тип
#define type(x) _Generic((x), \
int: "int", \
char *: "char *" \
)
#define print(x) _Generic((x), \
int: p_int,
char *: p_str,
)(x);- Пример: квадратное уравнение по двум корням
- Выводим подробно всякие разные данные
_Generic— макрос и работает с литералами; это трудно держать в голове- Макросы позволяют конструировать имя конечной функции
_Genericпозволяет разветвлять макрос на типизированные функции- Если зависимость от типа можно конвертнуть в единый код (скажем, строку), то и
_Genericможно использовать прямо в тексте программы - Управляющее выражение в
_Genericне вычисляется!
# _Generic((x)) раскидывает на макросы + вызов
# _Generic((y)) после этого — на имена функцийПродолжение с произвольными наборами аргументов произвольного типа — следует
