Переменная Integer в C занимает 2 байта или 4 байта?
Это зависит от платформы, которую вы используете, а также от конфигурации вашего компилятора. Единственный надежный ответ - использовать sizeof
оператор, чтобы увидеть, насколько велико целое число в вашей конкретной ситуации.
От каких факторов это зависит?
Лучше всего рассмотреть диапазон , а не размер . И то, и другое будет отличаться на практике, хотя гораздо более надежно выбирать типы переменных по диапазону, чем по размеру, как мы увидим. Также важно отметить, что стандарт побуждает нас рассмотреть возможность выбора целочисленных типов на основе диапазона, а не размера , но сейчас давайте проигнорируем стандартную практику и позволим нашему любопытству исследовать sizeof
байты CHAR_BIT
и целочисленное представление ... кроличью нору и сами все увидим ...
sizeof
, байтов и CHAR_BIT
Следующее утверждение, взятое из стандарта C (ссылка на которое приведена выше), описывает это словами, которые, я думаю, не могут быть улучшены.
sizeof
Оператор дает размер (в байтах) своего операнда, который может быть выражение в скобках или имя типа. Размер определяется по типу операнда.
При условии четкого понимания мы приведем к обсуждению байтов . Обычно предполагается, что байт составляет восемь битов, когда фактически CHAR_BIT
говорит вам, сколько битов в байте . Это просто еще один из тех нюансов, который не учитывается при разговоре об общих двух (или четырех) байтовых целых числах .
Давайте подведем итоги:
sizeof
=> размер в байтах и
CHAR_BIT
=> количество бит в байте
Таким образом, в зависимости от вашей системы, sizeof (unsigned int)
может быть любое значение больше нуля (а не только 2 или 4), как если бы CHAR_BIT
это было 16, то один (шестнадцатиразрядный) байт содержит достаточно битов, чтобы представить шестнадцатибитовое целое число, описываемое стандарты (цитируется ниже). Это не обязательно полезная информация, не так ли? Давайте углубляться глубже ...
Целочисленное представление
В C стандарт устанавливает минимальные точности / дальность для всех стандартных целочисленных типов (и CHAR_BIT
, тоже, FWIW) здесь . Из этого мы можем получить минимум для того, сколько бит требуется для хранения значения , но мы можем также просто выбрать наши переменные на основе диапазонов . Тем не менее, огромная часть деталей, необходимых для этого ответа, находится здесь. Например, следующее, что стандарт unsigned int
требует (по крайней мере) шестнадцать бит хранения:
UINT_MAX 65535 // 2¹⁶ - 1
Таким образом, мы можем видеть, что unsigned int
требуется ( как минимум ) 16 битов , и именно здесь вы получаете два байта (предполагая, что CHAR_BIT
это 8) ... и позже, когда этот предел увеличился до 2³² - 1
, люди указали вместо этого 4 байта. Это объясняет явления, которые вы наблюдали:
В большинстве учебников говорится, что целочисленные переменные занимают 2 байта. Но когда я запускаю программу, печатающую последовательные адреса массива целых чисел, это показывает разницу 4.
Вы используете древний учебник и компилятор, который учит вас непереносимым Си; автор, написавший ваш учебник, может даже не знать об этом CHAR_BIT
. Вы должны обновить свой учебник (и компилятор) и стремиться помнить, что информационные технологии - это постоянно развивающаяся область, в которой вам нужно быть впереди, чтобы конкурировать ... Впрочем, хватит об этом; давайте посмотрим, какие еще непереносимые секреты хранятся в этих целочисленных байтах ...
Биты значений - это то, что, по-видимому, считают обычными заблуждениями. В приведенном выше примере используется unsigned
целочисленный тип, который обычно содержит только биты значений, поэтому в деталях легко пропустить дьявола.
Подписывать биты ... В приведенном выше примере я указал UINT_MAX
верхний предел, unsigned int
потому что это тривиальный пример извлечения значения 16
из комментария. Для типов со знаком, чтобы различать положительные и отрицательные значения (это знак), мы также должны включить бит знака.
INT_MIN -32768 // -(2¹⁵)
INT_MAX +32767 // 2¹⁵ - 1
Биты заполнения ... Хотя встречаться с компьютерами, у которых биты заполнения являются целыми числами, нечасто, стандарт C допускает это; некоторые машины (т.е. этот ) реализуют большие целочисленные типы, комбинируя два меньших (знаковых) целочисленных значения вместе ... и когда вы объединяете целые числа со знаком, вы получаете потерянный знаковый бит. Этот потерянный бит считается заполнением в C. Другие примеры битов заполнения могут включать биты четности и биты прерывания .
Как вы можете видеть, стандарт, кажется, поощряет учитывать диапазоны, такие как INT_MIN
... INT_MAX
и другие минимальные / максимальные значения из стандарта, при выборе целочисленных типов, и не рекомендует полагаться на размеры, так как есть другие тонкие факторы, которые могут быть забыты, такие как CHAR_BIT
биты заполнения, которые может повлиять на значение sizeof (int)
(то есть распространенные заблуждения о двухбайтовых и четырехбайтовых целых числах игнорируют эти детали).