У меня трудности с пониманием, каковы были точные цели создания short
, int
и long
типы данных в C?
Причина, по которой я спрашиваю, заключается в том, что не похоже, что их размеры ограничены - они могут быть любого размера, если, например short
, они меньше, чем int
.
Тогда в каких ситуациях следует использовать unsigned int
или unsigned long
, например, вместо a size_t
, если это не дает надежды на двоичную совместимость?
(Если вы не знаете размер, то как вы узнаете, когда выбрать какой?)
c
data-types
user541686
источник
источник
<stdint.h>
sizeof(short) == 2 * sizeof(char)
или похожие?sizeof(char) == sizeof(short)
есть смысл. К сожалению, невозможно указать целочисленные типы чисел таким образом, чтобы они подходили для всех возможных и существующих платформ.Ответы:
Это будет определяться архитектурой, которую вы использовали. На чипе Zilog z80 (обычная встроенная микросхема) они будут одного размера, а на чипсете x86 они могут быть совершенно другого размера. Однако сами размеры являются фиксированными отношениями друг к другу. По существу, short и long не являются типами, но соответствуют типу int. Короткие целые будут на порядок меньше, чем (обычные) int, а длинные целые будут на порядок выше. Допустим, ваш Int ограничен 4 байтами, короткий спецификатор ограничивает его 4 байтами, хотя 2 байта также очень распространены, и длинный классификатор потенциально увеличивает его до 8 байтов, хотя он может быть меньше до 4 байтов. Имейте в виду, что это также зависит от длины слова, поэтому в 32-битной системе вы в любом случае получите максимум 4 байта на целое, делая длину такой же, как и для обычного целого. Таким образом, Short ≤ Int ≤ Long.
Однако, если вы снова увеличите его, вы можете вставить int в следующую ячейку, предоставив вам 8 целых байтов памяти. Это размер слова для 64-битных машин, поэтому им не нужно беспокоиться о таких вещах, а просто использовать одну ячейку для длинных целых, что позволяет им быть на порядок выше стандартных, в то время как длинные длинные целые становятся действительно битовыми.
Что касается выбора, он сводится к тому, о чем, например, Java-программистам не нужно беспокоиться. "Какова ваша архитектура?" Поскольку все зависит от размера слова памяти рассматриваемой машины, вы должны понять это заранее, прежде чем решить, какой использовать. Затем вы выбираете наименьший разумный размер, чтобы сэкономить как можно больше памяти, поскольку эта память будет выделена независимо от того, используете ли вы все биты в ней или нет. Таким образом, вы экономите, где можете, и выбираете шорты, когда можете, и целые, когда не можете, и если вам нужно что-то большее, чем те, которые вы даете обычными; Вы будете удлиняться по мере необходимости, пока не достигнете потолка слова. Тогда вам нужно будет предоставить подпрограммы с большим числом или получить их из библиотеки.
C вполне может быть «портативной сборкой», но вы все равно должны знать ваше оборудование.
источник
Хотя сегодня «байт» означает «8 бит», это не всегда было правдой. Машины использовали адресуемые фрагменты из 4 битов, 8 битов, 12 битов, 16 битов, 32 битов и 36 битов (и, возможно, также некоторых других размеров). Одной из целей разработки C было использование на машинах с различными размерами памяти и конфигурациями.
Я думаю, изначально задумывалось, что каждый тип, кроме
int
самого маленького, может обрабатывать числа разных размеров, и этоint
самый практичный размер «общего назначения», который может обрабатывать +/- 32767. Я не думаю, что было какое-либо желание или намерение создать язык, который все еще использовался бы, когда компьютеры стали настолько мощными, что операции с 64-разрядными числами стоили столько же, сколько операции с более мелкими.Самая большая проблема с семантикой целочисленного типа в C состоит в том, что в некоторых контекстах они представляют кардинальные числа или математические целые числа, в то время как в других контекстах они используются для представления членов обертывающего абстрактного алгебраического кольца целых чисел congruent mod 2 ^ n [так, например, вычитая максимальное представимое значение от 0 определяется как результат 1], но поведение определяется в большей степени на основе того, что компиляторы, по-видимому, делали в те дни, когда размеры компьютерных слов составляли около 16 бит (а 36-битный размер слова был бы огромным ), а не на основе того, что имело бы смысл на 64-битной машине. Следовательно, результатом вычитания 32-разрядного значения без знака из меньшего 32-разрядного значения без знака может быть либо большое 32-разрядное значение без знака, либо отрицательное 64-разрядное число.
источник
/programming/589575/size-of-int-long-etc
Таким образом, в наиболее часто используемых архитектурах char - это 1 байт, short и int - как минимум 2 байта, а long - как минимум 4 байта.
Предполагается, что int должно быть наиболее естественным / нормальным / эффективным представлением для текущего процессора.
Таким образом, общее правило - использовать int, если ваши значения не превышают +/- 32K, что заставляет вас (на старых процессорах) использовать long. ... или если вы не создаете большие массивы с малыми (<32 КБ) значениями, и память является проблемой - поэтому вы должны использовать «short» для экономии памяти (или, возможно, «char» или «byte»).
источник
int
вряд ли когда-нибудь будет хорошим выбором, верно? Я почти всегда в конечном итоге используюsize_t
(или дажеptrdiff_t
!) В любом случае, чтобы избежать проблем с переносом кода.C был разработан для активной работы с памятью на разных уровнях. Есть случаи, когда разница между short, int и long, а также между float и double имеет значение из-за ограничений памяти, архитектуры и т. Д. Хотя сейчас это не имеет значения, все же существуют среды, в которых оно имеет значение (например, встроенное и случаи, когда данные огромны), и переход от 32-битной архитектуры в основном к 64-битной снова делает это проблемой. (Через десять или двадцать лет, когда мы перейдем на 128-битную архитектуру, а C / C ++ все еще популярен, это снова станет проблемой). Вы правы, хотя эта двоичная совместимость страдает, поэтому вы не хотите использовать эти типы переменных размеров там, где это имеет значение.
Вы спросили, как вы будете знать, какой из них использовать, если не знаете размер, но вы знаете размер для данной комбинации архитектуры / компилятора, и если вам нужно оптимизировать память на этом уровне, вам лучше об этом знать. Вы не можете оптимизировать это просто для разных платформ, потому что не можете знать их размеры, поэтому вы не захотите использовать эти функции для этой цели. Но многие вещи, написанные на C, зависят от платформы, что, несмотря на моду на кроссплатформенность, допускает некоторые полезные оптимизации.
источник