Was ist der Unterschied zwischen size_t und int in C ++?

In einigen C ++ – Beispielen sehe ich eine Verwendung des Typs size_t, wo ich einen einfachen int verwendet hätte. Was ist der Unterschied und warum sollte Size_t besser sein?

Von der freundlichen Wikipedia :

Die Headerdateien stdlib.h und stddef.h definieren einen Datentyp namens size_t, der die Größe eines Objekts darstellt. Bibliotheksfunktionen, die Größen annehmen, erwarten, dass sie vom Typ “size_t” sind, und der Operator “sizeof” wird als size_t ausgewertet.

Der tatsächliche Typ von size_t ist plattformabhängig; Ein häufiger Fehler ist die Annahme, dass size_t dasselbe ist wie unsigned int, was zu Programmiererrorsn führen kann, insbesondere wenn 64-Bit-Architekturen häufiger werden.

Überprüfen Sie auch, warum size_t wichtig ist

size_t ist der Typ, der verwendet wird, um Größen darzustellen (wie seine Namen implizieren). Seine Plattform (und möglicherweise auch die Implementierung) ist abhängig und sollte nur für diesen Zweck verwendet werden. Offensichtlich ist size_t eine Größe vorzeichenlos. Viele stdlib-functionen, einschließlich malloc, sizeof und verschiedenen String-functionen, verwenden size_t als Datentyp.

Ein int ist standardmäßig signiert, und obwohl seine Größe auch plattformabhängig ist, wird es auf der modernsten Maschine eine feste 32Bits sein (und obwohl size_t 64 Bits auf 64-Bit-Architektur ist, bleiben Int 32 Bit lang auf diesen Architekturen).

Zusammenfassend: Verwenden Sie size_t, um die Größe eines Objekts darzustellen, und int (oder long) in anderen Fällen.

Das liegt daran, dass size_t alles andere als ein int (vielleicht eine Struktur) sein kann. Die Idee ist, dass es seinen Job vom zugrunde liegenden Typ entkoppelt.

Der Typ size_t ist als vorzeichenloser ganzzahliger Typ des Operators sizeof . In der realen Welt werden Sie int oft als 32 Bit (aus Gründen der Abwärtskompatibilität) definiert sehen, aber size_t als 64 Bit definiert (damit Sie Arrays und Strukturen mit mehr als 4 GiB deklarieren können) auf 64-Bit-Plattformen. Wenn ein long int ebenfalls 64 Bits hat, wird dies als LP64-Konvention bezeichnet; Wenn long int 32 Bits long int ist, aber long long int und pointers 64 Bits, ist das LLP64. Sie können auch das Umgekehrte erhalten, ein Programm, das 64-Bit-statementen für Geschwindigkeit verwendet, aber 32-Bit-pointers, um Speicher zu sparen. Außerdem ist int signiert und size_t ist vorzeichenlos.

Es gab in der Vergangenheit eine Reihe anderer Plattformen, auf denen Adressen breiter oder kürzer waren als die ursprüngliche Größe von int . Tatsächlich war dies in den 70er und frühen 80er Jahren häufiger als nicht: Alle gängigen 8-Bit-Mikrocomputer hatten 8-Bit-Register und 16-Bit-Adressen, und der Übergang zwischen 16 und 32 Bits erzeugte auch viele Maschinen hatte Adressen weiter als ihre Register. Ich sehe gelegentlich noch Fragen über Borland Turbo C für MS-DOS, dessen großer Speichermodus 20-Bit-Adressen hatte, die in 32 Bits auf einer 16-Bit-CPU gespeichert waren (die aber den 32-Bit-Befehlssatz des 80386 unterstützen könnte); das Motorola 68000 hatte eine 16-Bit-ALU mit 32-Bit-Registern und -Adressen; Es gab IBM Mainframes mit 15-Bit-, 24-Bit- oder 31-Bit-Adressen. In eingebetteten Systemen sehen Sie immer noch unterschiedliche ALU- und Adressbusgrößen.

Jedes Mal, wenn int kleiner als size_t ist und Sie versuchen, die Größe oder den Offset einer sehr großen Datei oder eines Objekts in einem unsigned int zu speichern, besteht die Möglichkeit, dass es überläuft und einen Fehler verursacht. Bei einem int besteht auch die Möglichkeit, eine negative Zahl zu erhalten. Wenn ein int oder ein unsigned int breiter ist, wird das Programm korrekt ausgeführt, aber es wird Speicherplatz verschwendet.

Sie sollten im Allgemeinen den richtigen Typ für den Zweck verwenden, wenn Sie Portabilität wünschen. Viele Leute empfehlen, dass Sie signierte Mathematik anstelle von unsigned verwenden (um böse, kleine Fehler wie 1U < -3 zu vermeiden). Zu diesem Zweck definiert die Standardbibliothek ptrdiff_t in als den signierten Typ des Ergebnisses, bei dem ein pointers von einem anderen subtrahiert wird.

Eine Umgehung könnte jedoch sein, alle Adressen und Offsets gegen INT_MAX und entweder 0 oder INT_MIN INT_MAX und die Warnungen des Compilers zum Vergleichen signierter und unsignierter Mengen INT_MIN , falls Sie eine verpassen. Sie sollten immer, immer, immer Ihre Array-Zugriffe auf Überlauf in C sowieso überprüfen.

Die Definition von SIZE_T finden Sie unter: https://msdn.microsoft.com/en-us/library/cc441980.aspx und https://msdn.microsoft.com/en-us/library/cc230394.aspx

Hier die erforderlichen Informationen einfügen:

SIZE_T ist ein ULONG_PTR der die maximale Anzahl von Bytes ULONG_PTR auf die ein pointers zeigen kann.

Dieser Typ wird wie folgt deklariert:

 typedef ULONG_PTR SIZE_T; 

Ein ULONG_PTR ist ein vorzeichenloser langer Typ, der für die ULONG_PTR wird. Es wird verwendet, wenn ein pointers auf einen langen Typ übergeben wird, um pointersarithmetik auszuführen.

Dieser Typ wird wie folgt deklariert:

 typedef unsigned __int3264 ULONG_PTR;