Mir ist klar, dass der Titel zuerst albern klingt, aber bitte, ertragen Sie einen Moment. :)
Seitdem ich size_t
und ptrdiff_t
benutzt habe, hatte ich noch keine Verwendung für int
, soweit ich mich erinnern kann.
Die einzigen ganzzahligen Datentypen, an die ich mich vor Kurzem erinnere, fallen in eine dieser Kategorien:
(Vorzeichenlose) Ganzzahlen, die einem Index in einer speicherinternen Datenstruktur zugeordnet sind (z. B. vector
).
Fast immer ist der am besten geeignete Typ dafür size_t
(oder ...::size_type
, wenn Sie die extra Meile gehen).
Auch wenn die Ganzzahl nicht tatsächlich einen Index darstellt, ist sie oft immer noch assoziiert mit einem bestimmten Index, also ist size_t
immer noch passend.
Signierte Versionen von size_t
. In vielen Fällen ist der am besten geeignete Typ ptrdiff_t
, da oft, wenn Sie dies benötigen, Sie mit Iteratoren arbeiten - und daher sind size_t
und ptrdiff_t
beide für sie geeignet.
long
. Ich brauche das gelegentlich für _InterlockedIncrement
(Referenzzählung).
( unsigned
) long long
, wird für Dateigrößen verwendet.
unsigned int
oder unsigned long
, nützlich für "zählende" Zwecke (z. B. alle 1 Million Iterationen, Aktualisierung der Benutzeroberfläche).
unsigned char
für den raw-Byte-Level-Zugriff auf den Speicher.
(Randnotiz: Ich habe auch nie eine Verwendung für signed char
gefunden.)
intptr_t
und uintptr_t
für das gelegentliche Speichern von Betriebssystemhandles, Zeigern usw.
Ein wichtiger Aspekt von int
ist, dass Sie es nicht überlaufen lassen sollten (da es ein undefiniertes Verhalten ist), so dass Sie es nicht einmal zuverlässig zum Zählen verwenden können - insbesondere wenn Ihr Compiler es als 16 Bit definiert .
Also wann sollten Sie dann int
verwenden (abgesehen davon, ob eine Abhängigkeit von Ihnen das bereits erfordert)?
Gibt es heutzutage einen wirklichen Nutzen, zumindest in neu geschriebenem, portablem Code?
Ich habe endlich selbst einen guten Anwendungsfall gefunden:
int
ist der perfekte Kandidat zum Speichern von Ganzzahl-Logarithmen , z. B. der Zoomstufe einer Karte.
short
hat normalerweise nicht genug Präzision dafür (die Drehung eines glatten Mausrads kann sehr präzise sein), und long
ist normalerweise genauer, als wir brauchen.
Wir brauchen definitiv negative Werte, also sollten wir keine vorzeichenlosen Typen verwenden. Daher passt int
zur Rechnung.
Was ist der wichtigste Grund für alles - Lesbarkeit . (und einfache Mathematik)
%Vor% "Okay ... aber andererseits, wie viel kann ein Mensch tatsächlich pro Woche arbeiten, wir brauchen ein long
"
"Warte ... verwenden wir weeklyHours
, um über einen Vektor zu iterieren?"
"Klare genug." - mögliche Quelle für Fehler, wenn beide negativ sein können (Teil der Logik - es könnte eine Möglichkeit sein, Freizeit zu berücksichtigen oder zu verlassen, nicht wichtig)
%Vor%"Okay, einfach genug. Ich verstehe, was das macht."
Luchian hat einige ausgezeichnete Lesbarkeitspunkte, zu denen ich einige technische hinzufügen werde:
int
auswählt, die effizient behandelt werden kann, während long
nicht sein kann (riskiert mehr CPU-Zyklen pro Operation, mehr Byte Maschinencode, mehr benötigte Register usw.) abs(a - b)
sieht mathematisch korrekt aus, gibt aber kein intuitives Ergebnis, wenn b
& gt; a
und sie sind unsigned int second_delta = (x.seconds - y.seconds) + (x.minutes - y.minutes) * 60;
if (pending - completed > 1) kick_off_threads()
-1
benötigt wird, wird oft verwendet: Bei unsignierten Typen wird dieser Wert auf den größtmöglichen Wert konvertiert, was jedoch zu Missverständnissen und Codierungsfehlern führen kann (zB if (x >= 0)
Test für Nicht-Sentinel) / li>
Außerdem gibt es eine Menge Spielraum für implizite Konvertierungen zwischen Ganzzahlen mit und ohne Vorzeichen. Es ist wichtig zu verstehen, dass unsignierte Typen selten helfen, eine "nicht-negative" Invariante durchzusetzen: Wenn das ein Teil der Berufung ist, schreiben Sie besser eine Klasse mit Konstruktor und Operatoren, die die Invariante erzwingen.
Auf der Lesbarkeitsseite bezeichnet int
einen allgemeinen Bedarf für eine Zahl, die die Problemdomäne deutlich überspannt - sie kann übertrieben sein, ist aber in Maschinencode-Operationen und CPU-Zyklen als billig bekannt Lager. Wenn du sagst unsigned char
benutzt, um das Alter einer Person zu speichern - es spielt nicht nur nicht gut mit operator<<(std::ostream&...)
, sondern es wirft Fragen auf wie "war es nötig, hier Speicher zu sparen?" (besonders verwirrend für Stack-basierte Variablen), "Gibt es eine Absicht, dies als Binärdaten für E / A- oder IPC-Zwecke zu behandeln?", oder sogar "ist es ein bekanntes einstelliges Alter in ASCII?". Wenn etwas trotzdem in einem Register landen sollte, ist int
eine natürliche Größe.