Deklarieren einer 32-Bit-Ganzzahl in C.

75

Was ist der beste Weg, um einen Integer-Typ zu deklarieren, der auf allen Plattformen immer 4 Byte beträgt? Ich mache mir keine Sorgen um bestimmte Geräte oder alte Maschinen mit 16-Bit int.

ZZ Coder
quelle
6
In C muss ein Byte nicht aus 8 Bit bestehen, daher können 32 Bit und 4 Byte unterschiedliche Bedeutungen haben.
KTC
1
@KTC: Gibt es Plattformen, die Bytes unterschiedlich definieren?
Mr. Shiny und New
Ich bin auch neugierig zu wissen, wo char! = 8bits und ein Byte! = 8bits. char! = 8bits scheint in Ordnung zu sein, da ich char == 4bits in meinem eigenen nicht entworfenen System oder einem alten System haben kann, aber wo kommt Byte! = 8bits?
seg.server.fault
2
Nicht wenige DSPs und dergleichen haben 16-Bit-Zeichen (und C hat kein anderes Konzept für ein "Byte" als char - es ist praktisch die kleinste adressierbare Speichereinheit).
Steve Jessop
1
Eine der Honeyboxen, die wir noch haben, hat 6-Bit- und 9-Bit-Bytes, basierend auf dem Adressierungsmodus, in dem Sie sich befinden.
user7116

Antworten:

111
#include <stdint.h>

int32_t my_32bit_int;
Corey D.
quelle
3
Nur zu beachten, dass intN_t (und uintN_t) standardmäßig optional sind. Es muss genau dann definiert werden, wenn das System über Typen verfügt, die die Anforderungen erfüllen.
KTC
30
Das ist es aber was du willst. Wenn der Code wirklich ein 32-Bit-Int erfordert und Sie versuchen, ihn auf einer Plattform zu kompilieren, die sie nicht unterstützt, möchten Sie, dass der Compiler zum Entwickler zurückkehrt. Es wäre schrecklich, wenn man sich eine andere Größe aussuchen und weitermachen würde.
TED
12
Beachten Sie, dass der Header <inttypes.h>explizit so dokumentiert ist, dass er den Header enthält <stdint.h>(dies ist bei C-Headern nicht üblich). <inttypes.h>Der Header ist jedoch möglicherweise verfügbar, wenn dies <stdint.h>nicht der Fall ist, und ist möglicherweise eine bessere Wahl für die Portabilität. Der <stdint.h>Header ist eine Erfindung des Normungsausschusses und wurde so erstellt, dass freistehende Implementierungen von C (im Gegensatz zu gehosteten Implementierungen - normale) nur <stdint.h>"und nicht unbedingt auch" unterstützen müssen <inttypes.h>(dies würde auch bedeuten) Unterstützung ' <stdio.h>', was sonst nicht notwendig ist).
Jonathan Leffler
2
Gibt es eine Möglichkeit, int32_t als vorzeichenlos zu definieren?
Matthew Herbst
5
@MatthewHerbst , uint32_t.
user545424
12

C kümmert sich nicht sehr um die exakten Größen von Ganzzahltypen. C99 führt den Header stdint.h ein , der wahrscheinlich die beste Wahl ist. Schließen Sie das ein und Sie können z int32_t. Natürlich unterstützen dies möglicherweise nicht alle Plattformen.

nr
quelle
11

Coreys Antwort ist meiner Meinung nach richtig für "best", aber ein einfaches "int" funktioniert auch in der Praxis (vorausgesetzt, Sie ignorieren Systeme mit 16-Bit-int). Zu diesem Zeitpunkt hängt so viel Code davon ab, dass int 32-Bit ist, dass Systemanbieter ihn nicht ändern werden.

(Siehe auch, warum long auf vielen 64-Bit-Systemen 32-Bit ist und warum wir "long long" haben.)

Einer der Vorteile der Verwendung von int32_t ist jedoch, dass Sie dieses Problem nicht aufrechterhalten!

Brooks Moses
quelle
Es ist nicht erforderlich, Systeme mit 16-Bit-Int zu ignorieren. Long ist garantiert überall mindestens 32-Bit breit.
Bastien Léonard
3
Richtig, aber die Verwendung von "long" adressiert nicht die ursprüngliche Anforderung, die genau 32 Bit beträgt. Unter (zumindest einigen Varianten von) 64-Bit-Linux beispielsweise ist ein Long 64-Bit - und das ist etwas, das in der Praxis wahrscheinlich auftaucht.
Brooks Moses
5

Sie könnten eine Kopie von Brian Gladman suchen, brg_types.hwenn Sie keine haben stdint.h.

brg_types.h Ermittelt die Größe der verschiedenen Ganzzahlen auf Ihrer Plattform und erstellt Typedefs für die gängigen Größen: 8, 16, 32 und 64 Bit.

cfrantz
quelle
Bei der Betrachtung einiger "brg_types.h", die ich gefunden habe, definiert diese Datei nur vorzeichenlose Ganzzahlen (z. B. "uint_8t", "uint_16t", "uint_32t" und "uint_64t"). Das OP benötigte eine vorzeichenbehaftete Ganzzahl.
Swdev
5

Sie müssen einschließen, inttypes.hanstatt, stdint.hweil stdint.hes auf einigen Plattformen wie Solaris nicht verfügbar ist und auf Systemen wie Linux für Sie inttypes.heinschließt stdint.h. Wenn Sie einschließen, inttypes.hist Ihr Code zwischen Linux und Solaris portabler.

Dieser Link erklärt, was ich sage: HP Link zu inttypes.h

Und dieser Link enthält eine Tabelle, die zeigt, warum Sie nicht verwenden möchten longoder intob Sie beabsichtigen, dass eine bestimmte Anzahl von Bits in Ihrem Datentyp vorhanden ist. IBM Link zu tragbaren Datentypen

Cutlasj
quelle
1

Wenn stdint.h für Ihr System nicht verfügbar ist, erstellen Sie Ihre eigene. Ich habe immer eine Datei namens "types.h", die typedefs für alle vorzeichenbehafteten / vorzeichenlosen 8-, 16- und 32-Bit-Werte enthält.

Robert
quelle
0

Abhängig von Ihren Zielplattformen können Sie auch Autotools für Ihr Build-System verwenden

Es wird angezeigt, ob stdint.h / inttypes.h vorhanden ist und ob keine geeigneten typedefs in einer "config.h" erstellt werden.

Spudd86
quelle
0

stdint.h ist die offensichtliche Wahl, aber nicht unbedingt verfügbar.

Wenn Sie eine tragbare Bibliothek verwenden, sind möglicherweise bereits tragbare Ganzzahlen mit fester Breite verfügbar. Zum Beispiel hat SDL Sint32(S steht für "signiert") und GLib hat gint32.

Bastien Léonard
quelle
0

C99 oder höher

Verwenden Sie <stdint.h>.

Wenn Ihre Implementierung 2-Komplement-32-Bit-Ganzzahlen unterstützt, muss sie definiert werden int32_t.

Wenn nicht, ist das nächstbeste int_least32_tein ganzzahliger Typ, der von der Implementierung unterstützt wird und unabhängig von der Darstellung (Zweierkomplement, Einerkomplement usw.) mindestens 32 Bit beträgt.

Es gibt auch int_fast32_teinen Integer-Typ mit einer Breite von mindestens 32 Bit, der mit der Absicht ausgewählt wurde, die schnellsten Operationen für diese Größenanforderung zu ermöglichen.

ANSI C.

Sie können verwenden long, die aufgrund der im Standard festgelegten Mindestbereichsanforderungen garantiert eine Breite von mindestens 32 Bit hat.

Wenn Sie lieber den kleinsten Ganzzahltyp verwenden möchten, um eine 32-Bit-Zahl anzupassen, können Sie Präprozessoranweisungen wie die folgenden mit den in definierten Makros verwenden <limits.h>:

#define TARGET_MAX 2147483647L

#if   SCHAR_MAX >= TARGET_MAX
  typedef signed char int32;
#elif SHORT_MAX >= TARGET_MAX
  typedef short int32;
#elif INT_MAX   >= TARGET_MAX
  typedef int int32;
#else
  typedef long int32;
#endif

#undef TARGET_MAX
Veltas
quelle