# 06 лекция - C (19.03.2022) ## Про размеры Тип для размера массивов или чего либо другого - `size_t` - модификатор `%z` (`%zu` - стандарт `C99`) `ptrdiff_t` - для разницы двух указателей (size_t со значком) - модификатор `%t` (`%ti` или `%td` стандарт `C99`) (Данный тип описан в заголовочном файле `stddef.h` для языка `C` и в файле `cstddef` для языка `C++`) Обратный цикл для `size_t`: ``` for(size_t x=N; x--; ) { ... } //цикл от [N-1, ... , 0] ``` Для знаковых чисел гарантируется модулярная арифметика (то есть можно вычитать из unsigned 0 и получить работающюю программу) ## Про модификаторы типа Костанты можно инициализировать, но нельзя присваивать. ``` const int x = 2; //x = 0; //нельзя ``` Если не инициализовать глобальную или статическую переменную - они инициализируются нулем. Глобальная переменная - видна во всей программе, живет всю программу, расположена в секции данных Статические переменные - видны как локальные, но время жизни глобальное `static` вне функции (в глобальной области) - означает видимость внутри файла (работает и для функций) ``` int a; const int b=2; const int *p = &b; p=&b; p=&a; //*p=0 //нельзя int *const q=&a; //q= //нельзя *q = 3; ``` `const int *p = &b;` - указатель на `const int` (можно присвоить адрес изменяемого обьекта, но сквозь p изменить нельзя будет) (очень осмысленный, например для функций, которые по указателю ничего не меняют) `int *const q = &a;` - `const` указатель на `int` (нельзя присвоить адрес `const int`) Можно и оба использовать Если привести тип указателя к не `const`, и записать через него - `undefined behavior` ## Про библиотеки 1. Просто дополнительные файлики исходников 2. Уже скомпилированна 2.1. Статическая (вкомпилируется в `.exe`) 2.2. Динамическая, всё равно будет `.lib` файл, только маленький, в нем будет обращение к дин библ (.dll для win) (динамическая не вкомпиливается в `.exe`) По умолчаюнию стандартные библиотеки - динамические `.h` файлы - описание функций `.dll` - это как `.exe` только без `main` ## Про преобразование типов ``` const int x = 2; float y = x; ``` Неявное преобразование int во float (потеря информатии при больших значениях не кратных 2м) ``` const int x = 2; float y = (float)x; ``` Явное преобразование int во float (без `warning`, потеря информатии при больших значениях не кратных 2м) ## Строки символов В си нет типа строка символов - это просто массив символов Два подхода определения длинны: * Храниться длина строки * Есть символ конца строки (в си) `"abc"` - 0x61 0x62 0x63 0x00 ('\0'), в конце строки стоит нуль терминатор, нет внешнего представления. (код '0' = 0x30) Символ - `char a;` Строка - `char str[10];` Подсчет количества символов ``` size_t my_str_size (const char *str) { size_t res = 0; while(str[res++]); // '\0' == 0 (целочисленному) return res-1; } ``` `%с` - считывает символ, выводит символ `%s` - считает строку до пробела, выводит до '\0' ``` char x[20]; x[0]='a'; x[1]='b'; x[2]='c'; x[4]=0; ``` Как делать печатать нельзя!! - `printf(x);` Как надо - `printf("%s", x);` Как считать строку (до пробела) -`scanf("%19s", x);` (считать максимум 19 символов) Как считать строку - `fgets(x, 20, stdin);` (считать максимум 19 символов), либо вариация scanf (ДОБАВИТЬ) `gets` и `scanf %s` не использовать! (buffer overflow) Как перевести строку в int (например) - sscanf(x, "%i", &a) (перенасыщение по максимуму, не по модулю!!) (не выдает ошибки при преобразовании) `sprintf(x, "%i", a);` - печатает в строку ## Про аргументы main (коммандной строки) `int main(int argc, char **argv)` `int main(int argc, char *argv[])` - тоже самое, очевидно Стандартное принятие аргументов, отличное (изменение на не эквивалентные типы алгументов) - не приведет к желаемому результату `argc` - количество параметров + 1 `argv` - массив массивов, первый агрумент - название `.exe` (можно поменять, в завис как запускаем (может быть путь)) prog.exe 1 "abc ef" ``` argc == 1 argv: "prog.exe" "1" "abc ef" ``` ## Про кодировки ASCII - таблица символов, половина байта (7ми битная таблица) Кодовые страницы для русского: * `КОИ-8 `- почта раньше * `CP-866` - DOS * `CP-1251` - WIN * `CP-65001`- WIN (utf-8) BOM - Byte order mark (неразмерный пробел нулевой толщины) (Маркер последовательности байтов) UTF-8 - многобайтовая байтовая кодировка (от 1 до 4х) UTF-16 - 2х байтовая кодировка (на каждый символ 2 байта) UTF-32 - 4х байтовая кодировка (на каждый символ 4 байта) `wchar_t` - для utf-16, зависит от системы