О выборе размера типа
Как известно, память компьютера - множество ячеек размера один байт, каждая из которых имеет свой адрес. Стоит сразу отметить, что переменная может занимать больше 1 байта в памяти: 2, 4, 8 и больше ячеек. Сколько памяти занимает переменная зависит от её типа данных. Также стоит упомянуть, из комбинаторики:
Из заметки про встроенные типы данных стало понятно что размер определенного типа зависит от арихитектуры и компилятора, а С++ гарантирует только минимальный размер типа. Чтобы узнать фактический размер на текущей машине используют оператор sizeof (Забавно, что sizeof это один из трех операторов, который является словом, а не символом. Остальные два: new и delete).
Конкретных правил по выбору размера типа несуществует, однако каждый раз при объявлении новой переменной стоит задумываться о её возможных значениях: хватит ли текущего размера, не будет ли она когда-то больше чем размер типа. В большинстве ситуаций лучше использовать обычный int, который зачастую представлен 32-битами (точно не больше чем 32), если не хватает обычного 32-битного int, лучше использовать int64_t.
Целочисленные типы данных с фиксированным размером
Когда создавали яп Си производительность стояла на первом месте, поэтому размеры типов намеренно не стали фиксировать в стандарте. Компилятор сам должен подобрать оптимальный размер для определенного типа в зависимости от архитектуры.
Однако, как оказалось, такая система не всегда удобная. Чтобы решить вопрос кроссплатформенности в яп С++ добавили целочисленные типы фиксированного размера - с одним и тем же размером на любой архитектуре.
Файл заголовков:
- Старые компиляторы:
#include <stdint.h>
- Начиная с С++11:
#include <cstdint>
Тип | Размер | |
---|---|---|
signed | ||
int8_t | 1 байт | |
int16_t | 2 байта | |
int32_t | 4 байта | |
int64_t | 8 байт | |
intptr_t | размером с указатель | |
unsigned | ||
uint8_t | 1 байт | |
uint16_t | 2 байта | |
uint32_t | 4 байта | |
uint64_t | 8 байт | |
uintptr_t | размером с указатель |
ВНИМАНИЕ! На многих платформах int8_t и uint8_t определены как unsigned char и соответственно обрабатываются так же. Лучше вместо них использовать int16_t и uint16_t либо быть очень внимательным:
std::int8_t a = 65;
std::cout << a << std::endl; \\ выведет A, хотя ожидали 65
От чего зависит размер указателя\ссылки
Размер указателя, как и многое в С++, не имеет фиксированного стандартом размера. В большинстве современных ОС используются модели данных, в которых размер указателя соответствует разрядности адресной шины.
Ширина шины адреса определяет максимально возможный размер адреса. В середине 1970-х годов типовая ширина шины данных составляла 8 бит. В наше время это обычно 32,64 или 128 бит. Элемент данных, задействующий всю ширину шины, принято называть словом.
Адресная шина
Соответственно, размер указателя чаще всего:
- на 32-битной машине - 32 бит
- на 64-битной машине - 64 бит
Главное что нужно помнить: типы данных, размер которых больше чем размер указателя, нужно передавать (например, в функции) по указателю\ссылке, чтобы избежать лишнего копирования.