Чому були короткими, int і давно винайденими в C?


16

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

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

Тоді в яких ситуаціях слід використовувати unsigned intабоunsigned long , наприклад, замість size_t, коли це робите, не сподівайтеся на бінарну сумісність?

(Якщо ви не знаєте розміру, то як би ви дізналися, коли вибрати який?)


2
Виїзд<stdint.h>
BlackJack

1
@BlackJack: Так, насправді є, але я думаю, що моє питання полягає в тому, чому не всі ці типи визначені на самоті? Це питання "заднім числом 20/20", чи була конкретна причина?
користувач541686

2
C повинен був бути як портативним, так і близьким до основного обладнання. Були платформи, де байт не був 8 біт, але ви все одно можете використовувати C. Жодного фіксованого набору типів даних ніколи не буде достатньо, жодна фіксована величина не може бути портативною.
SK-логіка

@ SK-логіка: Навіть якщо вони сказали sizeof(short) == 2 * sizeof(char)чи подібне?
користувач541686

1
Є платформи, де sizeof(char) == sizeof(short)і це має сенс. На жаль, немає способу вказати цілісні типи чисел таким чином, щоб вони відповідали всім можливим і існуючим платформам.
SK-логіка

Відповіді:


12

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

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

Щодо того, що вибрати, це зводиться до того, про що, наприклад, програмістам Java не потрібно турбуватися. "Яка ваша архітектура?" Оскільки все залежить від розміру слова пам'яті відповідної машини, ви повинні зрозуміти це наперед, перш ніж вирішити, який використовувати. Потім ви вибираєте найменший розумний розмір, щоб зберегти стільки пам’яті, скільки зможете, оскільки ця пам’ять буде виділена, використовуєте ви всі біти в ній чи ні. Таким чином, ви економите, де можете, і вибираєте шорти, коли можете, і ints, коли не можете, і якщо вам потрібно щось більше, ніж те, що ви регулярно надаєте; ви б подовжувались у міру необхідності, поки не потрапили на стелю слова. Тоді вам потрібно буде надати підпрограми великої кількості або отримати їх з бібліотеки.

Це може бути "портативною збіркою", але ви все одно повинні знати ваше обладнання.


11
це не зовсім правильно, шорти не повинні бути меншими за ints, вони не можуть бути більшими за ints
jk.

Я це виправлю.
Всесвітній інженер

2
Аналогічно, довжини не можуть бути меншими за вставки.
Дональні стипендіати

1
Дійсно, я вважаю, були машини, де короткі, int і довгі, де саме такі.
jk.

6

Хоча сьогодні "байт" означає "8 біт", це не завжди було правдою. Машини використовували адресні фрагменти з 4 біт, 8 біт, 12 біт, 16 біт, 32 біт і 36 біт (і, мабуть, також деякі інші розміри). Одним із намірів проекту C було бути корисним для машин із різними розмірами та конфігурацією пам'яті.

Я думаю, що проектний задум спочатку мав на увазі, що кожен тип, окрім intяк найменша річ, яка може обробляти номери різних розмірів, і це intнайпрактичніший розмір «загального призначення», який може працювати з +/- 32767. Я не думаю, що було бажання чи намір створити мову, яка все ще використовувалася б, коли комп’ютери стали настільки потужними, що операції з 64-бітовими номерами коштують стільки ж, скільки й операції на менших.

Найбільша проблема семантики цілого типу C полягає в тому, що в деяких контекстах вони представляють собою кардинальні числа або математичні цілі числа, тоді як в інших контекстах вони використовуються для представлення членів обгорткового абстрактного алгебраїчного кільця цілих чисел конгруентного моди 2 ^ n [так, наприклад, віднімання Максимальне представлене значення від 0 визначається для отримання 1], але поведінку визначають більше на основі того, що компілятори, здавалося, робили в ті дні, коли розміри комп'ютерних слів складали приблизно 16 біт (а розмір 36-бітного слова був би величезним ), а не на основі того, що мало б сенс для 64-бітної машини. Отже, результатом віднімання 32-розрядного непідписаного значення з меншого непідписаного 32-бітного значення може бути або велике 32-бітове неподписане значення, або негативне 64-бітове число.


4

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

Так у найбільш часто використовуваних архітектурах char - 1 байт, короткий та int - принаймні 2 байти, а довгий - принаймні 4 байти.

І передбачається, що "int" має бути найбільш природним / нормальним / ефективним представленням для поточного процесора.

Таким чином, загальне правило - використовувати "int", якщо ваші значення не перевищують +/- 32K, змушуючи вас (на старих процесорах) використовувати "long". ... або якщо ви не створюєте великі масиви з малих (<32K) значень, і пам'ять не є проблемою, тому ви використовуєте "short" для збереження пам'яті (або, можливо, "char" або "byte").


2
Але з 64-розрядною intверсією навряд чи вдалий вибір, правда? Я майже завжди в будь-якому разі користуюся size_t(або навіть ptrdiff_t!), Щоб уникнути проблем з переносом коду.
користувач541686

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

1

C був розроблений, щоб активно працювати з пам'яттю на різних рівнях. Бувають випадки, коли різниця між короткими, int і довгими, і між float і double, має значення через обмеження пам'яті, архітектури тощо. Хоча це зараз важливо менше, все ж є середовища, де це відбувається (наприклад, вбудований і в випадки, коли дані є масовими), а перехід від переважно 32-розрядної архітектури до 64-бітної знову стає дещо проблемою. (Через десять-двадцять років, коли ми переходимо на 128-бітну архітектуру, а C / C ++ все ще популярний, це знову буде проблемою). Ви маєте рацію, хоча бірна сумісність страждає, тому ви не хочете використовувати ці змінні типи розмірів там, де це має значення.

Ви запитали, як би ви знали, що використовувати, якщо ви не знаєте розміру, але ви знаєте розмір для заданої комбінації архітектури / компілятора, і якщо вам потрібно оптимізувати пам'ять на цьому рівні, ви краще знаєте це. Ви не можете оптимізувати це просто на платформах, оскільки ви не можете знати їх розміри, тому ви не хочете використовувати ці функції для цієї мети. Але багато речей, написаних на С, є специфічними для платформи, що, незважаючи на моду на «крос-платформу», дає можливість отримати деякі вигідні оптимізації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.