- Статистическая — типы известны до компиляции. Позволяет компилятору производить хитрые оптимизации; пример: С++.
- Динамическая — типы не известны до компиляции; пример: Питон.
- Сильная — нельзя неявно преобразовывать в другой тип; пример: Java.
- Слабая — можно неявно преобразовывать типы данных; пример: JavaScript (1 + ‘1’ = 2).
-
void— не хранит ничего, можно использовать как тип данных для функций, которые ничего не возвращают; -
bool— 2 литерала,true,false;- К
boolнеявно приводятся и целочисленные значения(0, 1); - Занимает не 1 бит, а как минимум 1 байт;
- К
-
char— в одинарных кавычках, написать в них несколько символов нельзя;- Имеет размер 1 байта;
- Стандарт не гарантирует, знаковый он или нет (зависит от платформы реализации);
- Явно беззнаковый:
unsigned char(от 0 до 255 бит) и явно знаковый:signed char(от -128 до 127);
1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) // по стандарту- Численные типы данных:
-
int— целые числа, по умолчанию знаковый;- По стандарту не имеет явного размера;
- Стандарт говорит, что размер
intбудет ≥ 16 бит;
-
short (int)— размер меньше int, ≥ 16 бит; -
long (int)— размер ≥ 32 бита; -
long long (int)— размер ≥ 64 бит - Если напишем ключевое слово unsigned — будет беззнаковый тип;
- Знаковые и беззнаковые типы — разные (не модификация одного и того же);
- Размер беззнакового типа всегда равен размеру соответствующему ему знаковому типу;
-
floatиdouble— формат и диапазон значений не специфицирован стандартом, числа с плавающей запятой;- Не вещественное число, а дробное, которое аппроксимирует вещественное, так как оно должно быть конечным в памяти (нельзя закодировать произвольное);
- Экспоненциальная форма записи числа:
-
$0.123 \cdot 2^{456}$ — мантисса и экспонента; - В памяти выделяется несколько бит под мантиссу и несколько под экспоненту;
- В
doubleсуществует два значения 0; - Например, число 10 не представляется как аппроксимация 9,9... — самое близкое число, которое можно записать с помощью степени 2;
- У
doubleнеравномерная точность, так как при превышении мантиссы начинает расти экспонента, а она уже существенно увеличивает число; - Два
doubleс друг с другом нельзя сравнивать через=, так как это аппроксимации и может возникать разная ошибка округления;- Надо сравнивать по модулю маленькой
$\varepsilon$ их разность;
- Надо сравнивать по модулю маленькой
-
-
-
Диапазон значений чисел можно выяснить так:
std::cout << std::numeric_limits<unsigned int>::max << std::endl;
-
Размер объекта:
sizeof(object) // настоящий оператор, выдаёт ответ в битах
-
Хранение знаковых / беззнаковых типов данных в памяти — с помощью дополнения до 2 (инвертирование значения всех бит);
-
0 кодируется единственным способом;
-
unsigned— используется, когда значение физически не будет отрицательным (размер выделенной памяти); -
Сравнение знаковых и беззнаковых типов:
- Надо привести к одному типу;
- Так как в памяти
signedвыглядит какunsigned, то никакого реального преобразования не происходит;
-
%— взятие остатка по модулю; -
+=/-=/*=//=/%=— инкрементные операции; -
±— унарные операции (положительные/отрицательные); -
Логические операции:
- Побитовые:
- Проводят операции с
int |— побитовое „или“;&— побитовое „и“;^— побитовый „xor“ (исключающее или);
- Проводят операции с
- Логические:
&&— логическое „и“ (типы данных приводятся кbool— ненулевые значения приводятся кtrue, нулевые —false)||— логическое „или“;- К
boolможно применять и арифметические операторы, но лучше писать логические операторы, чтобы было понятно, что мы имеем ввиду логическую семантику;
- Побитовые:
- У беззнаковых типов при переполнении числа будут выдавать значения по модулю 2;
for (unsigned int i = 10, i >= 0, --i) {
std:: cout << i << std:endl; // выдаст большие значения, так как происходит переполнение
} // это происходит, так как unsigned не может быть меньше нуля- Если мы не напишем по стандарту, то программа может начать вести себя „странно“, однако любое такое нестандартное поведение будет валидно по стандарту;
- Можно писать в двоичном или шестнадцетиричном формате;
int a = 1u; // u в конце гарантирует unsigned тип
double d = 0.1e1000; // можно написать числа с помощью экспоненциального формата- Синтаксис C++ разрешает писать несколько переменных в одной строке, но этим лучше не пользоваться, так как приводит к ошибкам:
int a, b = 0; // здесь лишь b будет равно нулю