Яка різниця між "довгим", "довгим довгим", "довгим int" та "long long int" в C ++?


209

Я переходжу з Java на C ++ і маю деякі запитання щодо longтипу даних. У Java, щоб утримувати ціле число, більше 2 32 , ви просто запишете long x;. Однак у C ++, схоже, longце і тип даних, і модифікатор.

Здається, існує кілька способів використання long:

long x;
long long x;
long int x;
long long int x;

Також, здається, є такі речі, як:

long double x;

і так далі.

У чому різниця між усіма цими різними типами даних і чи всі вони мають однакове призначення?



2
@ user2612743 - щоб бути безпечним, подумайте, які ваші вимоги, і використовуйте відповідний тип. long longможе бути повільніше long, що може бути повільніше, ніж int.
Піт Бекер


1
Ні, "щоб бути в безпеці, використовуйте довго", це те саме, що говорити "бути в безпеці, просто дайте всім один земний СНІД, так що нам не потрібно турбуватися про безпечний секс, ми все це все одно отримали!" Дурний, ні? Подумайте про дані та можливі значення, які вони можуть мати, та використовуйте найкращий тип. Це також допомагає компілятору здійснити додаткові оптимізації, не порушуючи наміру вихідного коду, наприклад, якщо він повинен завантажувати додаткові бібліотеки для обробки чисел, більших за природну бітову ширину цільової платформи.
CM

Використовуючи довгі довгі вікна списків win32 тощо, не можна грати з вашою пам'яттю та іншими змінними, навіть якщо обмеження не порушені. Навіть з невинно виглядаючими застереженнями C4244 це виявити непросто.
Лорі Стерн

Відповіді:


182

longі long intоднакові. Так є long longі long long int. В обох випадках intопція є необов’язковою.

Що стосується різниці між двома наборами, стандарт C ++ передбачає мінімальні діапазони для кожного, і long longце як мінімум настільки ж широке, як long.

Контролюючі частини стандарту (C ++ 11, але це існує вже давно) - це 3.9.1 Fundamental typesрозділ 2 (пізній розділ містить подібні правила для непідписаних цілісних типів):

Існує п'ять стандартних цілих цілих типів: підписаний char, короткий int, int, long int і long long int. У цьому списку кожен тип забезпечує принаймні стільки пам’яті, скільки й попередній у списку.

Також є таблиця 9 в 7.1.6.2 Simple type specifiers, де показано "відображення" специфікаторів на фактичні типи (показує, що intопція є необов'язковою), розділ якої показано нижче:

Specifier(s)         Type
-------------    -------------
long long int    long long int
long long        long long int
long int         long int
long             long int

Зверніть увагу на різницю між специфікатором і типом. Специфікатор - це те, як ви повідомляєте компілятору, що це за тип, але ви можете використовувати різні специфікатори, щоб опинитися в одному типі.

Отже, само longпо собі не є типом, ані модифікатором, як задано ваше питання, це просто специфікатор для long intтипу. Дітто для long longтого, щоб бути специфікатором для long long intтипу.

Хоча сам стандарт C ++ не вказує мінімальних діапазонів інтегральних типів, він цитує C99 в 1.2 Normative referencesякості прикладу. Отже, застосовані мінімальні діапазони, визначені в C99 5.2.4.2.1 Sizes of integer types <limits.h>.


З точки зору long double, це насправді значення з плаваючою комою, а не ціле число. Аналогічно інтегральним типам, потрібно мати принаймні таку точність, як doubleі забезпечити надмножину значень над цим типом ( маючи на увазі принаймні ці значення, не обов'язково більше значень).


4
те саме unsignedі зunsigned int
Кал

2
Я впевнений, що longпринаймні 32 біта (2 ^ 31-1 з обох боків від нуля) і long longпринаймні 64 (2 ^ 63-1 з обох боків).
chris

2
І long doubleгарантовано матиме хоча б діапазон double, але це може бути те саме. Це залежить від комп'ютера. Деякі FPU мають більш високу точність; чіпи x87 мали 32-бітну одноточність, 64-бітну подвійну точність і 80-бітну розширену точність.
Ерік Яблов

Що стосується вимог до діапазону, то стандарт C ++ 11 посилається на стандарт C11, який має фактичні діапазони.
chris

Частина "int" просто розмежовує цілий тип і плаваючу точку, символ чи інший не цілий тип. У багатьох випадках це може зробити висновок компілятора, тому його можна скинути - Ось чому "unsigned" - це те саме, що "unsigned int", наприклад. Частина "int" просто передбачається, якщо програміст не вказав щось інше, наприклад "char" або "double". Що стосується фактично використовуваних розмірів .. залежно від того, який стандарт ви читаєте, кожен розмір може мати мінімальну кількість біт, але всі вони визначені таким чином, що кожен принаймні такий же великий, як попередній тип.
CM


17

longеквівалентно так long intсамо, як shortрівнозначно short int. A long int- це підписаний інтегральний тип, який становить щонайменше 32 біта, тоді як а long longабо long long intє підписаний інтегральний тип - принаймні 64 біт.

Це не означає, що a long longширше, ніж a long. Багато платформ / ABI використовують цю LP64модель - де long(і вказівники) ширина 64 біт. Win64 використовує LLP64туди, де longще 32 біти, а long long(і покажчики) - 64 біт шириною.

Там хороший огляд моделей 64-розрядних даних тут .

long doubleне гарантує багато іншого, ніж воно буде принаймні таким широким, як double.


7

Це виглядає заплутано, оскільки ви приймаєте longза себе тип даних.

longце не що інше, як лише скорочення, long intколи ви використовуєте його поодинці.

longє модифікатором, ви можете використовувати його з doubleтакож як long double.

long== long int.

Вони обидва беруть по 4 байти.



1
Так, очевидно ... не тільки довго ... int займає 4 байти, і 2 байти залежать від платформи, без сумніву.
Сірай Алам

3

Історично в ранні часи С, коли процесори мали 8 або 16 бітову довжину слова, intбула ідентичною сьогоднішньому short(16 біт). У певному сенсі, внутр є більш абстрактним типом даних , ніж char, short, longабоlong long , як ви не можете бути впевнені в бітової.

Визначаючи, int n;ви могли б перекласти це за допомогою "дайте мені найкращий компроміс з шириною та швидкістю на цій машині для n". Можливо, в майбутньому слід очікувати, що компілятори для перекладу intстановлять 64 біт. Тож, коли ви хочете, щоб ваша змінна мала 32 біти і не більше, краще використовуйте явний longяк тип даних.

[Редагувати: #include <stdint.h>здається, це правильний спосіб забезпечення бітової ширини за допомогою типів int ## _ t, хоча це ще не є частиною стандарту.]


2
Остання частина, використовуючи "довгу", щоб отримати 32-бітові, коли int - 64-біт, невірно. Якщо int 64-бітний, то довгий також буде принаймні 64-бітним. Лонг гарантовано буде принаймні таким же великим, як int, хоча він може бути більшим, але ніколи не меншим. Більшість компіляторів мають різні методи, які дозволяють програмісту бути більш конкретним, наприклад (непереносний) тип __int32, що становить точно 32-бітні тощо.
CM

1
Як визначено у стандарті C, a longгарантується щонайменше 32 біта. (Стандарти можуть змінюватися жорстко.) Поточний проект C ++ 14 просто говорить: @CM "Прості вставки мають натуральний розмір, запропонований архітектурою середовища виконання. Для підписання спеціальних потреб надаються інші підписані цілі типи" (розділ 3.9.1 ). Я не знайшов жодного слова про довжинні відносини різних інт в ньому. __int32 насправді не є частиною стандарту, але оскільки в C ++ 11 є доступні typedefs, такі як int_fast32_t або int_least32_t, щоб отримати саме те, що ви хочете.
thomiel

Я б сказав, що для впровадження двадцятого століття для перепрограмованих мікрокомп'ютерів загального призначення charмайже одностайно було 8 біт, shortбуло 16 і longбуло 32; intможе бути або 16, або 32. Примітка, для деяких платформ (наприклад, 68000) і 16-бітні, і 32-розрядні intбули досить поширеними, і справді деякі компілятори мали можливість підтримувати будь-яку. Таким чином, очікувалося, що код або портативний код будуть використовуватися shortабо longвіддавати перевагу int.
supercat

0

Якщо в Java a longзавжди 64 біта, у C ++ це залежить від архітектури комп'ютера та операційної системи . Наприклад, along - 64 біт для Linux і 32 біт для Windows (це було зроблено для збереження зворотної сумісності, дозволяючи 32-бітним програмам збиратись у 64-бітних Windows без будь-яких змін).

Вважається хорошим стилем C ++, щоб уникати short int long ... і замість цього використовувати:

std::int8_t   # exactly  8 bits
std::int16_t  # exactly 16 bits
std::int32_t  # exactly 32 bits
std::int64_t  # exactly 64 bits

std::size_t   # can hold all possible object sizes, used for indexing

Ці ( int*_t) можна використовувати після включення <cstdint>заголовка. size_tзнаходиться в <stdlib.h>.

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