# 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, зависит от системы