Фундаментальные типы
(См. также тип для обзора системы типов и список утилит, связанных с типами, предоставляемых библиотекой C++)
Следующие типы в совокупности называются фундаментальными типами :
- (возможно, с квалификаторами cv)
void
| (начиная с C++11) |
void
void — тип с пустым множеством значений. Это неполный тип, который нельзя завершить (следовательно, объекты типа void запрещены). Не существует массивов void и ссылок на void. Однако допускаются указатели на void и функции, возвращающие тип void (процедуры в других языках). | (начиная с C++11) |
| (начиная с C++26) |
Целочисленные типы
Стандартные целочисленные типы
int — базовый целочисленный тип. Ключевое слово int можно опустить, если используются любые из перечисленных ниже модификаторов. Если модификаторы длины отсутствуют, гарантируется ширина не менее 16 бит. Однако в 32- и 64-разрядных системах почти всегда гарантируется ширина не менее 32 бит (см. ниже). Модификаторы
Модифицируют базовый целочисленный тип. Их можно комбинировать в любом порядке. В имени типа может присутствовать не более одного модификатора из каждой группы.
- Знаковость:
-
signed— целевой тип будет иметь знаковое представление (это значение по умолчанию, если модификатор опущен) -
unsigned— целевой тип будет иметь беззнаковое представление
- Размер:
-
short— целевой тип будет оптимизирован по занимаемому пространству и будет иметь ширину не менее 16 бит. -
long— целевой тип будет иметь ширину не менее 32 бит.
| | (начиная с C++11) |
Примечание: как и для всех спецификаторов типов, допустим любой порядок: unsignedlonglongint и longintunsignedlong обозначают один и тот же тип.
Свойства
В следующей таблице приведены все доступные стандартные целочисленные типы и их свойства в различных распространённых моделях данных:
| Спецификатор типа | Эквивалентный тип | Ширина в битах в зависимости от модели данных | ||||
|---|---|---|---|---|---|---|
| Стандарт C++ | LP32 | ILP32 | LLP64 | LP64 | ||
| signedchar | signedchar | не менее 8 | 8 | 8 | 8 | 8 |
| unsignedchar | unsignedchar | |||||
| short | shortint | не менее 16 | 16 | 16 | 16 | 16 |
| shortint | ||||||
| signedshort | ||||||
| signedshortint | ||||||
| unsignedshort | unsignedshortint | |||||
| unsignedshortint | ||||||
| int | int | не менее 16 | 16 | 32 | 32 | 32 |
| signed | ||||||
| signedint | ||||||
| unsigned | unsignedint | |||||
| unsignedint | ||||||
| long | longint | не менее 32 | 32 | 32 | 32 | 64 |
| longint | ||||||
| signedlong | ||||||
| signedlongint | ||||||
| unsignedlong | unsignedlongint | |||||
| unsignedlongint | ||||||
| longlong |
longlongint (C++11) | не менее 64 | 64 | 64 | 64 | 64 |
| longlongint | ||||||
| signedlonglong | ||||||
| signedlonglongint | ||||||
| unsignedlonglong |
unsignedlonglongint (C++11) |
|||||
| unsignedlonglongint | ||||||
Примечание: правила целочисленной арифметики для знаковых и беззнаковых целочисленных типов различаются. См. арифметические операторы, в частности переполнения целых чисел.
std::size_t — беззнаковый целочисленный тип результата оператора sizeof, а также оператора sizeof... и оператора alignof(начиная с C++11).
Расширенные целочисленные типыРасширенные целочисленные типы определяются реализацией. Обратите внимание, что целочисленные типы фиксированной ширины обычно являются псевдонимами стандартных целочисленных типов. | (начиная с C++11) |
Логический тип
bool — целочисленный тип, способный хранить одно из двух значений: true или false. Значение sizeof(bool) определяется реализацией и может отличаться от 1. Символьные типы
Символьные типы — это целочисленные типы, используемые для представления символов.
-
signed char— тип для знакового представления символов. -
unsigned char— тип для беззнакового представления символов. Также используется для просмотра представления объектов (необработанной памяти). -
char— тип для представления символов, который наиболее эффективно обрабатывается целевой системой (имеет то же представление и выравнивание, что иsigned charилиunsigned char, но всегда является отдельным типом). Строки с многобайтовыми символами используют этот тип для представления кодовых единиц. Для любого значения типаunsigned charв диапазоне[0,255]преобразование значения вcharи обратно вunsigned charдаёт исходное значение.(начиная с C++11) Знаковостьcharзависит от компилятора и целевой платформы: по умолчанию для ARM и PowerPC тип обычно беззнаковый, а для x86 и x64 — знаковый. -
wchar_t— тип для представления широких символов (см. широкие строки). Он имеет такой же размер, знаковость и выравнивание, как один из целочисленных типов, но является отдельным типом. На практике он имеет ширину 32 бита и хранит UTF-32 в Linux и многих других системах, не относящихся к Windows, но 16 бит и хранит кодовые единицы UTF-16 в Windows. Ранее стандарт требовал, чтобыwchar_tбыл достаточно велик для представления любой поддерживаемой кодовой точки символа. Однако это требование невыполнимо в Windows, поэтому оно считается дефектом и было удалено.
| | (начиная с C++11) |
| | (начиная с C++20) |
Помимо минимального количества битов, стандарт C++ гарантирует, что 1 == sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long).
Примечание: это допускает крайний случай, когда байты имеют размер 64 бита, все типы (включая char) имеют ширину 64 бита, а sizeof возвращает 1 для каждого типа.
Типы с плавающей запятой
Стандартные типы с плавающей запятой
Следующие три типа и их версии с квалификаторами cv в совокупности называются стандартными типами с плавающей запятой.
-
float— тип с плавающей запятой одинарной точности. Обычно используется формат IEEE-754 binary32. -
double— тип с плавающей запятой двойной точности. Обычно используется формат IEEE-754 binary64. -
long double— тип с плавающей запятой расширенной точности. Не обязательно соответствует типам, предписанным IEEE-754.- Формат IEEE-754 binary128 используется в некоторых реализациях для HP-UX, SPARC, MIPS, ARM64 и z/OS.
- Наиболее известный расширенный формат IEEE-754 binary64 — это формат расширенной точности x87 с 80-битной разрядностью. Он используется во многих реализациях для x86 и x86-64 (заметное исключение — MSVC, в котором
long doubleреализован в том же формате, что иdouble, то есть binary64). - В PowerPC может использоваться формат double-double.
Расширенные типы с плавающей запятойРасширенные типы с плавающей запятой определяются реализацией. Они могут включать типы с плавающей запятой фиксированной ширины. | (начиная с C++23) |
Свойства
Типы с плавающей запятой могут поддерживать специальные значения:
-
бесконечность (положительную и отрицательную), см.
INFINITY - отрицательный ноль,
-0.0. Он сравнивается как равный положительному нулю, но имеет значение в некоторых арифметических операциях, например1.0 / 0.0 == INFINITY, но1.0 / -0.0 == -INFINITY), и в некоторых математических функциях, напримерsqrt(std::complex) -
не число (NaN), которое не сравнивается как равное ничему (включая само себя). NaN представляются несколькими битовыми шаблонами; см.
std::nan,NAN. Обратите внимание, что C++ не обрабатывает сигнальные NaN особым образом, кроме проверки их поддержки с помощьюstd::numeric_limits::has_signaling_NaN, и рассматривает все NaN как тихие.
Для чисел с плавающей запятой можно использовать арифметические операторы +, -, / и *, а также различные математические функции из <cmath>. Как встроенные операторы, так и библиотечные функции могут возбуждать исключения с плавающей запятой и устанавливать errno, как описано в math errhandling.
Диапазон и точность выражений с плавающей запятой могут превышать значения, указанные для их типов; см. FLT_EVAL_METHOD. Выражения с плавающей запятой также могут быть сокращены, то есть вычислены так, как если бы все промежуточные значения имели бесконечный диапазон и точность; см. #pragma STDC FP_CONTRACT. Стандарт C++ не ограничивает точность операций с плавающей запятой.
На некоторые операции с числами с плавающей запятой влияет состояние среды плавающей запятой (в первую очередь направление округления), и они изменяют его.
Между типами с плавающей запятой и целочисленными типами определены неявные преобразования.
Дополнительные сведения, ограничения и свойства типов с плавающей запятой см. в разделе ограничения типов с плавающей запятой и в std::numeric_limits.
Диапазон значений
В следующей таблице приведены справочные ограничения для распространённых числовых представлений.
До C++20 стандарт C++ допускал любое представление знаковых целых чисел, а минимальный гарантированный диапазон N-разрядных знаковых целых чисел составлял от \(\scriptsize -(2^{N-1}-1)\)-(2N-1-1) до \(\scriptsize +2^{N-1}-1\)+2N-1-1 (например, от −127 до 127 для знакового 8-разрядного типа), что соответствует ограничениям представлений обратного кода или знака и величины.
Однако все компиляторы C++ используют представление дополнительного кода, и начиная с C++20 это единственное представление, разрешённое стандартом; гарантированный диапазон — от \(\scriptsize -2^{N-1}\)-2N-1 до \(\scriptsize +2^{N-1}-1\)+2N-1-1 (например, от −128 до 127 для знакового 8-разрядного типа).
8-разрядные представления обратного кода и знака и величины для char запрещены начиная с C++11 (в соответствии с решением проблемы CWG 1759), поскольку кодовая единица UTF-8 со значением 0x80, используемая в литерале строкового типа UTF-8, должна помещаться в объект типа char.
Диапазон типа с плавающей запятой T определяется следующим образом:
- Минимальный гарантированный диапазон — от наименьшего отрицательного конечного числа с плавающей запятой, представимого в
T, до наибольшего положительного конечного числа с плавающей запятой, представимого вT. - Если в
Tпредставима отрицательная бесконечность, диапазонTрасширяется до всех отрицательных вещественных чисел. - Если в
Tпредставима положительная бесконечность, диапазонTрасширяется до всех положительных вещественных чисел.
Поскольку в форматах ISO/IEC/IEEE 60559 представимы отрицательная и положительная бесконечности, все вещественные числа входят в диапазон представимых значений типа с плавающей запятой, соответствующего ISO/IEC/IEEE 60559.
| Тип | Размер в битах | Формат | Диапазон значений | |
|---|---|---|---|---|
| Приблизительный | Точный | |||
| символьный | 8 | знаковый | −128 до 127 | |
| беззнаковый | 0 до 255 | |||
| 16 | UTF-16 | 0 до 65535 | ||
| 32 | UTF-32 | 0 до 1114111 (0x10ffff) | ||
| целочисленный | 16 | знаковый | ± 3.27 · 104 | −32768 до 32767 |
| беззнаковый | 0 до 6.55 · 104 | 0 до 65535 | ||
| 32 | знаковый | ± 2.14 · 109 | −2,147,483,648 до 2,147,483,647 | |
| беззнаковый | 0 до 4.29 · 109 | 0 до 4,294,967,295 | ||
| 64 | знаковый | ± 9.22 · 1018 | −9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 | |
| беззнаковый | 0 до 1.84 · 1019 | 0 до 18,446,744,073,709,551,615 | ||
| двоичная плавающая запятая | 32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
|
|
| 80[примечание 1] | x86 |
|
|
|
| 128 | IEEE-754 |
|
|
|
- На 32- и 64-разрядных платформах представление объекта обычно занимает соответственно 96 и 128 бит.
Примечание: фактические (в отличие от гарантированно минимальных) ограничения на значения, представимые этими типами, приведены в интерфейсе пределов числовых типов C и std::numeric_limits.
Модели данных
Выбор размеров фундаментальных типов в каждой реализации в совокупности называется моделью данных. Широкое распространение получили четыре модели данных:
32-разрядные системы:
-
LP32 или 2/4/4 (
intимеет ширину 16 бит,longи указатель — 32 бита) - Win16 API
-
ILP32 или 4/4/4 (
int,longи указатель имеют ширину 32 бита); - Win32 API
- Unix и Unix-подобные системы (Linux, macOS)
64-разрядные системы:
-
LLP64 или 4/4/8 (
intиlongимеют ширину 32 бита, указатель — 64 бита) - Win32 API (также называемый Windows API) при целевой компиляции для 64-разрядной ARM (AArch64) или x86-64 (также x64)
-
LP64 или 4/8/8 (
intимеет ширину 32 бита,longи указатель — 64 бита) - Unix и Unix-подобные системы (Linux, macOS)
Другие модели встречаются очень редко. Например, ILP64 (8/8/8: int, long и указатель имеют ширину 64 бита) встречалась только в некоторых ранних 64-разрядных системах Unix (например, UNICOS на Cray).
Примечания
| Макрос проверки поддержки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_unicode_characters | 200704L | (C++11) | Новые символьные типы (char16_t и char32_t) |
__cpp_char8_t | 201811L | (C++20) |
char8_t |
202207L | (C++23) |
char8_t исправление совместимости и переносимости (разрешена инициализация массивов (unsigned) char из литералов строк UTF-8) |
Ключевые слова
void, bool, true, false, char, char8_t, char16_t, char32_t, wchar_t, int, short, long, signed, unsigned, float, double
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были ретроактивно применены к ранее опубликованным стандартам C++.
| DR | Применяется к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| CWG 238 | C++98 | ограничения, накладываемые на реализацию типов с плавающей точкой, не были определены | определено как отсутствие ограничений |
| CWG 1759 | C++11 |
char не гарантированно способен представлять кодовую единицу UTF-8 0x80 | гарантированно |
| CWG 2689 | C++11 | тип std::nullptr_t с cv-квалификаторами не являлся фундаментальным типом | является |
| CWG 2723 | C++98 | диапазоны представимых значений типов с плавающей точкой не были определены | определены |
| P2460R2 | C++98 |
wchar_t требовалось уметь представлять различные коды для всех элементовнаибольшего расширенного набора символов, заданного среди поддерживаемых локалей | не требуется |
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
- 6.8.2 Фундаментальные типы [basic.fundamental]
- Стандарт C++20 (ISO/IEC 14882:2020):
- 6.8.1 Фундаментальные типы [basic.fundamental]
- Стандарт C++17 (ISO/IEC 14882:2017):
- 6.9.1 Фундаментальные типы [basic.fundamental]
- Стандарт C++14 (ISO/IEC 14882:2014):
- 3.9.1 Фундаментальные типы [basic.fundamental]
- Стандарт C++11 (ISO/IEC 14882:2011):
- 3.9.1 Фундаментальные типы [basic.fundamental]
- Стандарт C++03 (ISO/IEC 14882:2003):
- 3.9.1 Фундаментальные типы [basic.fundamental]
- Стандарт C++98 (ISO/IEC 14882:1998):
- 3.9.1 Фундаментальные типы [basic.fundamental]
См. также
- Обзор системы типов C++
- Спецификаторы и квалификаторы константности и изменчивости (cv)
- Спецификаторы длительности хранения
| Документация по C для арифметических типов |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/types