Почему были короткие, инт, и длинные изобрели в C?


16

У меня трудности с пониманием, каковы были точные цели создания short, intи longтипы данных в C?

Причина, по которой я спрашиваю, заключается в том, что не похоже, что их размеры ограничены - они могут быть любого размера, если, например short, они меньше, чем int.

Тогда в каких ситуациях следует использовать unsigned intили unsigned long, например, вместо a size_t, если это не дает надежды на двоичную совместимость?

(Если вы не знаете размер, то как вы узнаете, когда выбрать какой?)


2
Выезд<stdint.h>
Блэкджек

1
@BlackJack: Ха-ха, да, на самом деле, но я думаю, мой вопрос: почему все эти типы не определены изначально? Это проблема «задним числом - 20/20», или была конкретная причина?
user541686 20.10.11

2
C должен был быть как портативным, так и близким к базовому оборудованию. Существовали платформы, в которых длина байта не была 8-битной, но вы все равно могли использовать C. Никакого фиксированного набора типов данных никогда не будет достаточно, ни одно целое число фиксированного размера не может быть переносимым.
SK-logic

@ SK-логика: нет, даже если они сказали sizeof(short) == 2 * sizeof(char)или похожие?
user541686 20.10.11

1
Есть платформы, где sizeof(char) == sizeof(short)есть смысл. К сожалению, невозможно указать целочисленные типы чисел таким образом, чтобы они подходили для всех возможных и существующих платформ.
SK-logic

Ответы:


12

Это будет определяться архитектурой, которую вы использовали. На чипе Zilog z80 (обычная встроенная микросхема) они будут одного размера, а на чипсете x86 они могут быть совершенно другого размера. Однако сами размеры являются фиксированными отношениями друг к другу. По существу, short и long не являются типами, но соответствуют типу int. Короткие целые будут на порядок меньше, чем (обычные) int, а длинные целые будут на порядок выше. Допустим, ваш Int ограничен 4 байтами, короткий спецификатор ограничивает его 4 байтами, хотя 2 байта также очень распространены, и длинный классификатор потенциально увеличивает его до 8 байтов, хотя он может быть меньше до 4 байтов. Имейте в виду, что это также зависит от длины слова, поэтому в 32-битной системе вы в любом случае получите максимум 4 байта на целое, делая длину такой же, как и для обычного целого. Таким образом, Short ≤ Int ≤ Long.

Однако, если вы снова увеличите его, вы можете вставить int в следующую ячейку, предоставив вам 8 целых байтов памяти. Это размер слова для 64-битных машин, поэтому им не нужно беспокоиться о таких вещах, а просто использовать одну ячейку для длинных целых, что позволяет им быть на порядок выше стандартных, в то время как длинные длинные целые становятся действительно битовыми.

Что касается выбора, он сводится к тому, о чем, например, Java-программистам не нужно беспокоиться. "Какова ваша архитектура?" Поскольку все зависит от размера слова памяти рассматриваемой машины, вы должны понять это заранее, прежде чем решить, какой использовать. Затем вы выбираете наименьший разумный размер, чтобы сэкономить как можно больше памяти, поскольку эта память будет выделена независимо от того, используете ли вы все биты в ней или нет. Таким образом, вы экономите, где можете, и выбираете шорты, когда можете, и целые, когда не можете, и если вам нужно что-то большее, чем те, которые вы даете обычными; Вы будете удлиняться по мере необходимости, пока не достигнете потолка слова. Тогда вам нужно будет предоставить подпрограммы с большим числом или получить их из библиотеки.

C вполне может быть «портативной сборкой», но вы все равно должны знать ваше оборудование.


11
это не совсем правильно, шорты не должны быть меньше целых, они не могут быть больше целых
jk.

Я исправлю это.
Мировой инженер

2
Точно так же longs не может быть меньше, чем int.
Donal Fellows

1
на самом деле я верю, что были машины с коротким, длинным и длинным точками зрения.
JK.

6

Хотя сегодня «байт» означает «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-разрядное число.


4

/programming/589575/size-of-int-long-etc

Таким образом, в наиболее часто используемых архитектурах char - это 1 байт, short и int - как минимум 2 байта, а long - как минимум 4 байта.

Предполагается, что int должно быть наиболее естественным / нормальным / эффективным представлением для текущего процессора.

Таким образом, общее правило - использовать int, если ваши значения не превышают +/- 32K, что заставляет вас (на старых процессорах) использовать long. ... или если вы не создаете большие массивы с малыми (<32 КБ) значениями, и память является проблемой - поэтому вы должны использовать «short» для экономии памяти (или, возможно, «char» или «byte»).


2
Но с 64-битным, intвряд ли когда-нибудь будет хорошим выбором, верно? Я почти всегда в конечном итоге использую size_t(или даже ptrdiff_t!) В любом случае, чтобы избежать проблем с переносом кода.
user541686 20.10.11

@Merhdad - int, используемый для лучшего выбора, он был определен как «стандартная единица» HW и, как правило, размером с указатель. В настоящее время для безопасности используем size_t.
Мартин Беккет

1

C был разработан для активной работы с памятью на разных уровнях. Есть случаи, когда разница между short, int и long, а также между float и double имеет значение из-за ограничений памяти, архитектуры и т. Д. Хотя сейчас это не имеет значения, все же существуют среды, в которых оно имеет значение (например, встроенное и случаи, когда данные огромны), и переход от 32-битной архитектуры в основном к 64-битной снова делает это проблемой. (Через десять или двадцать лет, когда мы перейдем на 128-битную архитектуру, а C / C ++ все еще популярен, это снова станет проблемой). Вы правы, хотя эта двоичная совместимость страдает, поэтому вы не хотите использовать эти типы переменных размеров там, где это имеет значение.

Вы спросили, как вы будете знать, какой из них использовать, если не знаете размер, но вы знаете размер для данной комбинации архитектуры / компилятора, и если вам нужно оптимизировать память на этом уровне, вам лучше об этом знать. Вы не можете оптимизировать это просто для разных платформ, потому что не можете знать их размеры, поэтому вы не захотите использовать эти функции для этой цели. Но многие вещи, написанные на C, зависят от платформы, что, несмотря на моду на кроссплатформенность, допускает некоторые полезные оптимизации.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.