Як оголосити 32-розрядне ціле число у C


75

Який найкращий спосіб оголосити цілочисельний тип, який завжди становить 4 байти на будь-яких платформах? Мене не турбує певний пристрій чи старі машини, які мають 16-розрядну версію int.


6
У C байт не повинен бути 8 бітами, тому 32 біти та 4 байти можуть означати різні речі.
KTC

1
@KTC: чи існують платформи, які по-різному визначають байт?
Містер Блискучий та Новий 安 宇

Мені також цікаво дізнатися, де char! = 8 біт, а байт! = 8 біт. char! = 8 біт здається нормальним, оскільки я можу мати char == 4 біта у власній непроектованій системі чи якійсь старій системі, але де байт! = 8 біт ??
seg.server.fault

2
Досить багато ЦСП і подібні мають 16-бітові символи (і С не має поняття "байт", крім символу - це фактично найменша адресована одиниця пам'яті).
Steve Jessop

1
Один із Honeyboxen, який ми досі маємо, має 6-бітові та 9-бітові байти на основі режиму адресації, в якому ви перебуваєте.
user7116

Відповіді:


112

3
Просто зазначити, що intN_t (і uintN_t) є необов’язковим з точки зору стандарту. Це потрібно визначити тоді і лише тоді, коли система має типи, які відповідають вимогам.
KTC

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

12
Зверніть увагу, що заголовок ` <inttypes.h>` чітко задокументовано, щоб включати заголовок ' <stdint.h>' (це незвично для заголовків C), але <inttypes.h>заголовок ` ` може бути доступний там, де ' <stdint.h>' немає, і може бути кращим вибором для перенесення. <stdint.h>Заголовок ' ' є винаходом комітету зі стандартів і створений таким чином, що окремі реалізації C (на відміну від розміщених реалізацій - звичайних) також повинні підтримувати лише ` <stdint.h>` і не обов'язково ' <inttypes.h>' (це також означало б підтримка ' <stdio.h>', що в іншому випадку не є необхідним).
Джонатан Леффлер,

2
Чи є спосіб визначити int32_t як непідписаний?
Метью Гербст,

5
@MatthewHerbst, uint32_t.
user545424

13

C не дуже стосується точних розмірів цілочисельних типів, C99 вводить заголовок stdint.h , який, мабуть, найкращий вибір. Включіть це, і ви можете використовувати, наприклад int32_t. Звичайно, не всі платформи можуть це підтримувати.


11

На мою думку, відповідь Корі є правильною для "найкращого", але простий "int" також спрацює на практиці (враховуючи те, що ви ігноруєте системи з 16-бітовим int). На даний момент стільки коду залежить від того, чи є 32-розрядний, що постачальники системи не збираються його змінювати.

(Дивіться також, чому long - це 32-розрядна версія для багатьох 64-розрядних систем і чому ми маємо "long long".)

Однак однією з переваг використання int32_t є те, що ви не продовжуєте цю проблему!


Немає необхідності «ігнорувати системи з 16-бітовим int», гарантовано, що long буде скрізь принаймні 32-бітовим.
Бастієн Леонар,

3
Правильно, але використання "long" не стосується початкового запиту, а це рівно 32 біти. Наприклад, у (принаймні деяких варіантах) 64-розрядної Linux, long - це 64 біти - і це те, що, ймовірно, з’явиться на практиці.
Брукс Мойсей

5

Ви можете вишукати копію Брайана Гладмана, brg_types.hякщо у вас її немаєstdint.h .

brg_types.h виявить розміри різних цілих чисел на вашій платформі та створить typedefs для загальних розмірів: 8, 16, 32 та 64 біта.


Насправді, переглянувши кілька "brg_types.h", які я знайшов, цей файл визначає лише цілі числа без підпису (наприклад, "uint_8t", "uint_16t", "uint_32t" та "uint_64t"). ОП потребував підписаного цілого числа.
swdev

5

Вам потрібно включити inttypes.hзамість цього, stdint.hоскільки stdint.hвін недоступний на деяких платформах, таких як Solaris, і inttypes.hвключить stdint.hдля вас у таких системах, як Linux. Якщо ви включите, inttypes.hто ваш код є більш портативним між Linux і Solaris.

Це посилання пояснює, що я кажу: посилання HP про inttypes.h

І це посилання має таблицю, яка показує, чому ви не хочете використовувати longабо intякщо у вас є намір певна кількість бітів бути присутнім у вашому типі даних. Посилання IBM про портативні типи даних


1

Якщо stdint.h недоступний для вашої системи, створіть свій власний. У мене завжди є файл із назвою "types.h", який має typedefs для всіх підписаних / непідписаних 8, 16 та 32 бітових значень.


0

також залежно від цільових платформ ви можете використовувати автоінструменти для вашої системи збірки

він побачить, чи існують stdint.h / inttypes.h, і якщо вони не створять відповідні typedefs у "config.h"


0

stdint.h - очевидний вибір, але він не обов'язково доступний.

Якщо ви використовуєте портативну бібліотеку, можливо, вона вже надає портативні цілі числа фіксованої ширини. Наприклад, SDL має Sint32(S означає "підписано"), а GLib має gint32.


0

C99 або пізнішої версії

Використовуйте <stdint.h> .

Якщо ваша реалізація підтримує доповнення 32-розрядних цілих чисел 2, тоді вона повинна визначити int32_t .

Якщо ні, то наступне найкраще - це int_least32_t - це цілочисельний тип, що підтримується реалізацією, принаймні 32 біти, незалежно від представлення (доповнення двох, доповнення одного тощо).

Існує також int_fast32_tцілочисельний тип шириною не менше 32 біт, обраний з метою дозволити найшвидші операції відповідно до цього розміру.

ANSI C

Ви можете використовувати long, що гарантовано має принаймні 32-бітну ширину в результаті мінімальних вимог до діапазону, визначених стандартом.

Якщо ви віддаєте перевагу використанню найменшого цілочисельного типу для розміщення 32-розрядного числа, тоді ви можете використовувати оператори препроцесора, як показано нижче, з макросами, визначеними в <limits.h>:

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