Я ищу подробную информацию о размере основных типов C ++. Я знаю, что это зависит от архитектуры (16 бит, 32 бита, 64 бита) и компилятора.
Но есть ли стандарты для C ++?
Я использую Visual Studio 2008 на 32-битной архитектуре. Вот что я получаю:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double: 8 bytes
Я пытался найти, без особого успеха, достоверную информацию о том , размеры char
, short
, int
, long
, double
, float
(и другие типы я не думал) в различных архитектурах и компиляторов.
int16_t
,int32_t
иint64_t
(нужноiostream
включают , что , если я правильно помню). Что приятно в этом, что int64_t не должно иметь проблем в 32-битной системе (хотя это повлияет на производительность).<cstdint>
, а не<iostream>
.Ответы:
Стандарт C ++ не определяет размер целочисленных типов в байтах, но определяет минимальные диапазоны, которые они должны поддерживать. Вы можете вывести минимальный размер в битах из необходимого диапазона. Из этого вы можете определить минимальный размер в байтах и значение
CHAR_BIT
макроса, который определяет количество бит в байте . На всех платформах, кроме самых непонятных, это 8, и оно не может быть меньше 8. Это потому, что он должен быть достаточно большим, чтобы вместить «восьмибитные кодовые единицы формы кодировки Unicode UTF-8».Дополнительным ограничением
char
является то, что его размер всегда равен 1 байту илиCHAR_BIT
битам (отсюда и название). Это прямо указано в стандарте.Стандарт C является нормативной ссылкой для стандарта C ++, поэтому, хотя он и не устанавливает эти требования в явном виде, для C ++ требуются минимальные диапазоны, требуемые стандартом C (стр. 22), которые такие же, как в диапазонах типов данных на MSDN :
signed char
: От -127 до 127 (примечание, не от -128 до 127; в нем предусмотрены платформы "1-дополнение" и "знак и величина")unsigned char
: От 0 до 255char
: тот же диапазон, чтоsigned char
иunsigned char
, определенный реализациейsigned short
: От -32767 до 32767unsigned short
: От 0 до 65535signed int
: От -32767 до 32767unsigned int
: От 0 до 65535signed long
: От -2147483647 до 2147483647unsigned long
: От 0 до 4294967295signed long long
: От -9223372036854775807 до 9223372036854775807unsigned long long
: От 0 до 18446744073709551615Реализация C ++ (или C) может определять размер типа в байтах
sizeof(type)
для любого значения, еслиsizeof(type) * CHAR_BIT
вычисляется до количества битов, достаточно высоких, чтобы содержать требуемые диапазоны, иsizeof(int) <= sizeof(long)
).Собрав все это вместе, мы гарантируем, что:
char
,signed char
Иunsigned char
, по меньшей мере 8 битsigned short
,unsigned short
,signed int
, Иunsigned int
, по крайней мере , 16 битsigned long
иunsigned long
не менее 32 битsigned long long
иunsigned long long
не менее 64 битМы не даем никаких гарантий относительно размера
float
илиdouble
за исключением того, чтоdouble
обеспечивает как минимум такую же точность, какfloat
.Фактические специфичные для реализации диапазоны можно найти в
<limits.h>
заголовке в C или<climits>
в C ++ (или даже лучше, в шаблонеstd::numeric_limits
в<limits>
заголовке).Например, вот как вы найдете максимальный диапазон для
int
:C:
C ++ :
источник
char
», а не для обычного значения.Для 32-битных систем, то де - факто "стандарт ILP32 - то есть
int
,long
и указатель все 32-битные величины.Для 64-битных систем основным стандартом де-факто Unix является LP64,
long
а указатель - 64-битный (ноint
32-битный). 64-разрядный стандарт Windows - LLP64,long long
а указатель - 64-разрядный (ноlong
иint
32-битный).Одно время некоторые системы Unix использовали организацию ILP64.
Ни один из этих стандартов де-факто не регламентирован стандартом C (ISO / IEC 9899: 1999), но все это разрешено.
И, по определению,
sizeof(char)
это1
, несмотря на испытания в конфигурационном скрипте Perl.Обратите внимание, что были машины (Crays), которые
CHAR_BIT
были намного больше, чем 8. Это означало, что IIRC, этоsizeof(int)
было также 1, потому чтоchar
иint
были 32-битными.источник
[u]int32_t
или аналогичную, если вы хотите использовать 64-разрядную[u]int64_t
версию ... если у вас нет для них заголовка, загрузите или создайте его, желательно с выбором времени компиляции: такие типы или статические утверждения для проверки размера. pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html Если точные размеры не так важны и вам важно только то, что они хотя бы настолько велики, то ваш совет подходит для распространенных современных ПК / серверных платформ.int get_char(FILE *fp, char *c)
которая возвращает EOF или 0 и устанавливает*c
.uint32_t x=1,y=2;
что значениеx-y
должно быть 4294967295 на платформах, где "int" равно 32 битам или меньше, и -1 на платформах, где "int" равно 33 битам или больше. Кроме того, требуется,x*y
чтобы он оценивался с использованием модульной арифметики для всех значений x и y, если «int» равно 32 битам или меньше, и обычной арифметики, если 65 бит или больше, но не предъявляет никаких требований к тому, что может случиться с большими значениями. из х и у, если "int" составляет от 33 до 64 бит.На практике такого нет. Часто можно ожидать, что
std::size_t
в текущей архитектуре будет представлен размер целого числа без знака. т.е. 16-битный, 32-битный или 64-битный, но это не всегда так, как указано в комментариях к этому ответу.Что касается всех остальных встроенных типов, то это действительно зависит от компилятора. Вот две выдержки из текущего рабочего проекта последнего стандарта C ++:
Если вы хотите, вы можете статически (во время компиляции) утверждать размер этих основных типов. Он предупредит людей подумать о переносе вашего кода, если размер предположений изменится.
источник
Есть стандарт.
Стандарт C90 требует, чтобы
Стандарт C99 требует, чтобы
Вот спецификации C99 . На странице 22 приведены размеры различных интегральных типов.
Вот типоразмеры int (биты) для платформ Windows:
Если вас беспокоит переносимость или вы хотите, чтобы имя типа отражало размер, вы можете посмотреть на заголовок
<inttypes.h>
, где доступны следующие макросы:int8_t
гарантированно будет 8 бит, иint16_t
гарантированно будет 16 бит и т. д.источник
sizeof(long) < sizeof(long long)
а не симметричноsizeof(long) <= sizeof(long long)
?Если вам нужны типы фиксированного размера, используйте такие типы, как uint32_t (32-разрядное целое число без знака), определенное в stdint.h . Они указаны в С99 .
источник
CHAR_BIT == 16
, например, не будет иметьint8_t
. Любая платформа, не использующая дополнение до двух, не будет иметь ни одного из них (так как стандарт требует дополнения до двух).Обновлено: C ++ 11 официально ввел типы из TR1 в стандарт:
И "размерные" типы из
<cstdint>
Плюс вы получаете:
Эти типы представляют наименьшие целочисленные типы с по меньшей мере указанным количеством битов. Аналогично, существуют "самые быстрые" целочисленные типы, по крайней мере, с указанным количеством битов:
Что означает «быстрый», если что, зависит от реализации. Это не должно быть самым быстрым для всех целей.
источник
Стандарт C ++ говорит это так:
3.9.1, §2:
Вывод: это зависит от того, над какой архитектурой вы работаете. Любое другое предположение неверно.
источник
Нет, не существует стандарта для размеров шрифта. Стандарт требует только, чтобы:
Лучшее, что вы можете сделать, если вам нужны переменные фиксированного размера, - это использовать такие макросы:
Затем вы можете использовать WORD для определения ваших переменных. Это не то, что мне нравится, но это самый портативный способ.
источник
#include <boost/cstdint.hpp>
Нам разрешено определять синоним для типа, чтобы мы могли создать свой собственный «стандарт».
На машине, в которой sizeof (int) == 4, мы можем определить:
Поэтому, когда мы переносим код на другую машину, где на самом деле размер long int равен 4, мы можем просто переопределить единственное вхождение int.
источник
<stdint.h>
(C99 и более поздние версии, и какой бы стандарт C ++ ни принимал версию C99 библиотеки C).Для чисел с плавающей запятой существует стандарт (IEEE754) : числа с плавающей запятой 32-разрядные, а числа с двойными числами - 64. Это аппаратный стандарт, а не стандарт C ++, поэтому компиляторы могут теоретически определить число с плавающей запятой и удвоить его до некоторого другого размера, но на практике я Мы никогда не видели архитектуры, которая бы использовала что-то другое.
источник
double
имеет одинаковый размерfloat
(иint
тот же самыйchar
, что и 16-битные). Но у них есть 64 битlong double
.Существует стандарт, и он указан в различных документах стандартов (ISO, ANSI и еще много чего).
В Википедии есть отличная страница, объясняющая различные типы и максимум, который они могут хранить: Integer in Computer Science.
Однако даже со стандартным компилятором C ++ вы можете сравнительно легко это выяснить, используя следующий фрагмент кода:
Документацию для std :: numeric_limits можно найти в Roguewave . Он включает в себя множество других команд, которые вы можете вызвать, чтобы узнать различные ограничения. Это может быть использовано с любым произвольным типом, который передает размер, например, std :: streamsize.
Ответ Джона содержит лучшее описание, так как оно гарантированно будет выполнено. Независимо от того, на какой платформе вы находитесь, есть еще одна хорошая страница, которая более подробно описывает, сколько битов ДОЛЖНО содержать каждый тип: типы int , которые определены в стандарте.
Надеюсь, это поможет!
источник
1) Таблица №1 в статье « Забытые проблемы разработки 64-битных программ »
2) « Модель данных »
источник
Ты можешь использовать:
datatype = int
иlong int
т. д. Вы сможете увидеть размер для любого типа данных, который вы вводите.источник
Когда дело доходит до встроенных типов для разных архитектур и разных компиляторов, просто запустите следующий код в своей архитектуре вместе со своим компилятором, чтобы увидеть, что он выводит. Ниже показан мой Ubuntu 13.04 (Raring Ringtail) 64 бит g ++ 4.7.3. Также обратите внимание на ответ ниже, поэтому выходные данные упорядочены так:
«Существует пять стандартных целочисленных типов со знаком: char со знаком, short int, int, long int и long long int. В этом списке каждый тип обеспечивает как минимум столько же памяти, сколько предшествует ему в списке».
источник
sizeof(char)
не должны быть включены.Как уже упоминалось, размер должен отражать текущую архитектуру.
limits.h
Если вы хотите увидеть, как ваш текущий компилятор справляется с какой-либо задачей, вы можете получить максимальную оценку.источник
Как ответили другие, все «стандарты» оставляют большинство деталей как «определенные реализацией», и только утверждают, что тип «char» имеет ширину leat «char_bis» и что «char <= short <= int <= long < = long long "(float и double в значительной степени соответствуют стандартам IEEE с плавающей запятой, а long double обычно такой же, как double - но может быть больше в более современных реализациях).
Одна из причин отсутствия точных и точных значений заключается в том, что такие языки, как C / C ++, были разработаны для переноса на большое количество аппаратных платформ - включая компьютерные системы, в которых размер слова «char» может быть 4-разрядным или 7-битные, или даже некоторые значения, отличные от «8- / 16- / 32- / 64-битных» компьютеров, с которыми сталкивается средний пользователь домашнего компьютера. (Размер слова здесь означает, сколько битов в ширину система обычно использует. Опять же, это не всегда 8 бит, как могут ожидать пользователи домашнего компьютера.)
Если вам действительно нужен объект (в смысле последовательности битов, представляющих целое значение) определенного количества бит, у большинства компиляторов есть какой-то метод указания этого; Но, как правило, он не переносим даже между компиляторами, выпущенными компанией Ame, но для разных платформ. Некоторые стандарты и практики (особенно limit.h и т. П.) Достаточно распространены, так что большинство компиляторов будут иметь поддержку для определения наиболее подходящего типа для определенного диапазона значений, но не количества используемых битов. (То есть, если вы знаете, что вам нужно хранить значения от 0 до 127, вы можете определить, что ваш компилятор поддерживает 8-битный тип "int8", который будет достаточно большим, чтобы содержать полный требуемый диапазон, но не как Тип "int7", который будет точным совпадением для 7-бит.)
Примечание. Многие исходные пакеты Un * x использовали скрипт "./configure", который проверяет возможности компилятора / системы и выводит подходящий Makefile и config.h. Вы можете изучить некоторые из этих сценариев, чтобы увидеть, как они работают и как они проверяют возможности компилятора / системы, и следовать их примеру.
источник
Если вы заинтересованы в чистом решении C ++, я использовал шаблоны и только стандартный код C ++ для определения типов во время компиляции на основе их размера в битах. Это делает решение переносимым между компиляторами.
Идея очень проста: создать список, содержащий типы char, int, short, long, long long (версии со знаком и без знака), отсканировать список и с помощью шаблона numeric_limits выбрать тип с заданным размером.
Включая этот заголовок, вы получили 8 типов stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.
Если какой-либо тип не может быть представлен, он будет оценен как stdtype :: null_type, также объявленный в этом заголовке.
Код, указанный ниже, предоставляется без гарантии, пожалуйста, проверьте его.
Я новичок в METAPROGRAMMING TOO, не стесняйтесь редактировать и исправлять этот код.
Протестировано с DevC ++ (так что версия gcc около 3.5)
источник
где
X
являетсяchar
,int
, иlong
т.д .. даст вам размерX
в битах.источник
sizeof(type)*CHAR_BIT
держитCHAR_BIT
было гарантировано 8 бит,<< 3
это просто запутанный способ записи* 8
или* CHAR_BIT
.От Алекса Б. Стандарт C ++ не определяет размер целочисленных типов в байтах, но он определяет минимальные диапазоны, которые они должны иметь. Вы можете вывести минимальный размер в битах из необходимого диапазона. Из этого можно определить минимальный размер в байтах и значение макроса CHAR_BIT, который определяет количество бит в байте (во всех, кроме самых непонятных платформ, это 8, и оно не может быть меньше 8).
Еще одно ограничение для char состоит в том, что его размер всегда равен 1 байту или битам CHAR_BIT (отсюда и название).
Минимальные диапазоны, требуемые стандартом (стр. 22):
и диапазоны типов данных в MSDN:
char со знаком: от -127 до 127 (примечание, не от -128 до 127; в нем могут использоваться платформы с дополнениями 1) short: от -32767 до 32767 unsigned short: от 0 до 65535 подписано int: от -32767 до 32767 unsigned int: от 0 до 65535 long подписано: от -2147483647 до 2147483647 long без знака: от 0 до 4294967295 long long подписано: от -9223372036854775807 до 9223372036854775807 unsigned От 0 до 18446744073709551615 Реализация C ++ (или C) может определять размер типа в байтах sizeof (type) для любого значения, если
выражение sizeof (type) * CHAR_BIT оценивает количество битов, достаточное для того, чтобы содержать требуемые диапазоны, и порядок типов все еще действителен (например, sizeof (int) <= sizeof (long)). Фактические специфичные для реализации диапазоны могут быть найдены в заголовке в C или в C ++ (или даже лучше, в шаблоне std :: numeric_limits в заголовке).
Например, вот как вы найдете максимальный диапазон для int:
C:
C ++:
Это правильно, однако вы также правы, говоря: char: 1 байт короткий: 2 байта int: 4 байта длиной: 4 байта с плавающей запятой: 4 байта double: 8 байтов
Поскольку 32-разрядные архитектуры по-прежнему используются по умолчанию и используются наиболее часто, и они сохранили эти стандартные размеры со времен до 32-разрядных дней, когда память была менее доступной, а для обратной совместимости и стандартизации она оставалась прежней. Даже 64-битные системы, как правило, используют их и имеют расширения / модификации. Пожалуйста, обратитесь к этому для получения дополнительной информации:
http://en.cppreference.com/w/cpp/language/types
источник
Я заметил, что все остальные ответы здесь были сосредоточены почти исключительно на целочисленных типах, в то время как спрашивающий также спрашивал о числах с плавающей точкой.
Я не думаю, что стандарт C ++ требует этого, но компиляторы для самых распространенных платформ в наши дни, как правило, следуют стандарту IEEE754 для их чисел с плавающей запятой. Этот стандарт определяет четыре типа двоичных чисел с плавающей точкой (а также некоторые форматы BCD, которые я никогда не видел в компиляторах C ++):
Как это соотносится с типами C ++? Обычно
float
используется одинарная точность; Таким образом,sizeof(float) = 4
. Затемdouble
используется двойная точность (я полагаю, это источник названияdouble
), иlong double
может быть двойной или четырехкратной точности (в моей системе она в четыре раза, но в 32-битных системах она может быть двойной). Я не знаю ни одного компилятора, который предлагал бы с плавающей точкой половинной точности.Подводя итог, это обычно:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 или 16источник
Как вы упомянули - это во многом зависит от компилятора и платформы. Для этого проверьте стандарт ANSI, http://home.att.net/~jackklein/c/inttypes.html.
Вот пример для компилятора Microsoft: Диапазоны типов данных .
источник
Вы можете использовать переменные, предоставляемые библиотеками, такими как OpenGL , Qt и т. Д.
Например, Qt предоставляет qint8 (гарантированно 8-битный на всех платформах, поддерживаемых Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64 и т. Д.
источник
На 64-битной машине:
источник
int
это 8 байтов, но другой не гарантируется. Там нет ничего, что говорит, чтоchar
должно быть только 8 бит. Это разрешено иметь,sizeof(void*)==4
хотя это 64 бит.Существует четыре типа целых чисел в зависимости от размера:
источник
short
,int
иlong
все 32-битные целые числа.int
, а не слово «целое число».