# Table types
[TOC]
---
**Целочисленные:**
| Название типа | В стандарте, не хуже чем | По факту (бит) | Комментарий |
|:---:|:---:|:---:|:---:|
| `int` | `(-32767 ... 32767)` | 32 | |
| `short` | не шире `int` | 32 | |
| `long` | не уже `int` | 32/64 | под win размер зависит от битности, в Linux - 64 |
| `long long` | не уже `long` | 64 | |
| `char` | ровно `-128..127 / 0..255` | 8 | может быть как знаковым по автомату так и беззнаковым |
| `_Bool` или `bool` | ровно `0-1` | 8 | занимает 1 байт всегда |
---
**С плавающей точкой:**
| Название типа | Значения | Размер | Соответствует (в IEEE 754-2008)
|:-------:|:-------:|:-------:|:-------:|
| `float` | `~10^(± 38)` | 32 | single precision |
| `double` | `~10^(± 308)` | 64 | double precision |
|`long double`| >= `double` | 64/80/128 | 80 - extended precision, 128 - quad precision |
---
**Специальные:**
| Название типа | Размер | Описание
|:-------:|:-------:|:-------:|
| `size_t` | 32/64 | Беззнаковый, размер совпадает с размером указателя |
---
# Fixed width integer types
[C++11 Fixed width integer types](https://en.cppreference.com/w/cpp/types/integer)
[C99 Fixed width integer types](https://en.cppreference.com/w/c/types/integer)
---
## Целочисленные простые типы
- В стандарте `int` определен как не хуже чем - `(-32767 ... 32767)` (`2^16-1`), именно в десятичной системе счисления, такой диапазон, не важно сколько битов в одном байте\
В реальности `int` соответвует диапазону - `-2^32 ... 2^32-1`
- Модификатор (типа) `short int` по стандарту не шире `int` (32 бита)\
по факту - 16 бит
- Модификатор (типа) `long int` по стандарту не меньше `int` (32/64 бита)\
по факту - 32/64 бита (Козлы тут Microsoft, под win при компиляции под 32-64битную программу `long int` соответсвует 32 битам, в Linux - при компиляции под 32 - 32, под 64 - 64)
- Модификатор (типа) `long long int` по стандарту не меньше `long int` (64 бита)\
по факту - 64 бита
> "long long long" is too long for gcc
---
- Модификатор (типa) `unsigned int`, беззнаковое `int`, может применятся с любыми другими\
(по факту (для `int`) - `0 ... 2^32 - 1`)
> `int` можно опустить в любых модификаторах для `int`
---
- `char`, целочисленный тип, может быть знаковым или нет (`-128..127 / 0..255`, 1 байт или 8 бит)\
`unsigned char` -> `0..255`\
`signed char` -> `-128..127` (ключивое слово `signed` в си имеет смысл только тут)
* Значения от 0 до 127 полностью кодируют ASCII, вторую часть бита занимает текущая кодовая страница системы.
* `signed` можно применять к любым целочисленным переменным (но все кроме `char` по умолчанию - `signed`)
---
- `_Bool` занимает **1 БАЙТ** (минимально адресуемая ячейка памяти), можно написать `bool` подключив заголовочный файл `#include <stdbool.h>` (также получите `true` и `false`)
* В си изначально не было bool, true и false - из-за ненадобности
> В стандарте Си нет ничего про `true` и `false`, только про (`1` и `0`)
## Типы данных с плавующей точкой:
[IEEE 754-2008](https://ru.wikipedia.org/wiki/IEEE_754-2008) - как представляются числа с плавающей точкой в современном компьютере (=> в C/C++)\
[Вольный пересказ](https://www.softelectro.ru/ieee754.html)\
(стандарт IEEE-754 (не стандарт языка, стандарт железа, некоторые моменты перенял си))
Их всего 3 типа
1. `float` = (32 бита) соответствует single precision IEEE 754-2008 10^(+- 38)
2. `double` = (64 бита) соответствует double precision IEEE 754-2008 10^(+- 308)
3. `long double`: (не договорились, про совместимость между компиляторами можно не думать)
* может совпадать с `double`
* может быть (128 бит) quad precision IEEE 754-2008, есть GCC, в x86 реализованно программно (очень медленно)
---
* может быть (80 бит) extended precision (не входит в стандарт IEEE 754-2008, аппаратно реализован в x86, (быстрее любой программной реализации))
Диапазон в 10^(+- 38) НЕ означает что будут храниться 308 десятичных знаков - означает, что максимальное значение по экспоненте будет 308 и оно будет неточным (будут храниться первые цифры)
> Обычно мы не хотим использовать `long double`
`double` как минимум вдвое медленнее чем `float` (может быть сильно медленнее)
## Создание своих типов
(создание синонимов типов)
```c
typedef unsigned int uint; //задать тип с названием uint, и смыслом unsigned int
uint a, b; //можно использовать как полный синоним unsigned int
```
> отличается от `define` тем, что это не простая текстовая замена, а создание нового типа, например:
```c=
#define X int // X заменяет на int
unsigned X a; //скомпилируется
//-------------------------------------//
typedef int y;
//unsigned y b; //не скомпилируется
```
> К `typedef` новому типу (синониму) нельзя применить никакие модификаторы (`unsigned`, `long` и др.)