Try   HackMD

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