stdint.h
, inttypes.h
, limits.h
Ein Integer ist in den Sprachen C und C++ definiert als eine zusammengehörige Menge an Bits, welche eine Ganzzahl codieren. Je nach Anwendung ist die Ganzzahl zudem als vorzeichenbehaftet oder vorzeichenlos zu interpretieren. Die Anzahl an Bits, welche für die Codierung benötigt wird, definiert den Werteumfang des Typs.
Mit dem Standard C99 wurden die Bibliotheken stdint
und inttypes
eingeführt, welche eine präzise Festlegung der benötigten Bits erlauben.
Integer-Typen mit Bit-Angabe
In der stdint
-Bibliothek werden Integer-Typen bereitgestellt, welche eine unterschiedliche Anzahl Bits aufweisen und entweder vorzeichenbehaftet oder vorzeichenlos sind. Je nach Anwendungsgebiet ist erwünscht, dass die gewünschte Anzahl Bits exakt eingehalten wird, es nur eine Mindestanforderung ist, oder dass es demjenigen Typ entspricht, welcher am schnellsten vom Prozessor verarbeitet werden kann.
Das N steht für die gewünschte Anzahl Bits. Jeder Compiler gemäss C99-Standard muss mindestens die Integer-Typen mit 8, 16, 32 und 64 Bits bereitstellen. Es steht einem Compiler jedoch frei, auch weitere Typen bereitzustellen, beispielsweise mit 24 Bits.
Ein 32-Bit Integer kann beispielsweise folgendermassen auf verschiedene Arten deklariert werden:
Vorsicht: Obige Angaben müssen auf gewissen Systemen mit Vorsicht genossen werden. Die Typen mit exakter Anzahl Bits beispielsweise existieren nur dann, wenn das System eine entsprechende Speicherung ohne Padding-Bits überhaupt beherrscht und zudem die signed
-Variante mit dem Zweierkomplement codiert wird. Es ist somit auch nur bei den exakten Typen garantiert, dass die vorzeichenbehafteten Zahlen im Zweierkomplement codiert werden. Bei modernen Systemen kann jedoch grundsätzlich davon ausgegangen werden, dass dem so ist.
Der Autor empfielt grundsätzlich, diese Typen anstelle der traditionellen Typ-Modifikatoren (siehe unten) zu nutzen. Auf modernen Systemen und mit modernen Compilern sind obengenannte Typen allesamt definiert und führen zu plattformunabhängigem Code.
In der stdint
-Bibliothek werden noch weitere Typen definiert. Diese sind jedoch (vorerst) auf dieser Seite nicht aufgeführt.
Minimal- und Maximalwerte (Limits)
Zu all den Typen, welche gemäss obiger Liste definiert sind, werden gleichzeitig verschiedene Makros angeboten, um die vorliegenden Minimal- und Maximalwerte abzufragen:
Wiederum steht N für die Anzahl Bits des entsprechenden Typs. Das Makro für den Minimalwert eines unsigned
-Typs fehlt, da dieser stets als 0
(Null) definiert ist.
Im Folgenden werden illustrativ die Werte der exakten Typen aufgelistet. Diese Werte sollten für die meisten Nutzer von Nutzen sein:
-128
127
255
-32768
32767
65535
-2147483648
2147483647
4294967295
-9223372036854775808
9223372036854775807
18446744073709551615
Diese Minimal- und Maximal-Werte werden auch als Limits
(Grenzwerte) bezeichnet, da sie auf traditionellem Wege durch die limits
-Bibliothek abgefragt werden konnten. Siehe dazu den Abschnitt weiter unten.
Die stdint
-Bibliothek definiert noch einige weitere Makros, welche jedoch (vorerst) hier auf dieser Seite nicht aufgeführt werden.
Makros für printf
und scanf
Bei der Ein- und Ausgabe mittels printf
und scanf
muss mittels Formatierungs-Zeichen (beispielsweise "%hhd"
) angegeben werden, wie ein übergebenes Argument interpretiert werden soll. Bei der Einführung der neuen Integer-Typen in der stdint
-Bibliothek wurde für jeden neuen Typ auch ein entsprechendes Makro definiert, welches die entsprechenden Formatierungs-Zeichen festlegt. All diese Makros stehen zur Verfügung, wenn folgende Bibliothek eingebunden wird:
Die Makros für printf
beginnen mit PRI
und die Makros für scanf
beginnen mit SCN
. Die weiteren Angaben beziehen sich auf das Ein- und Ausgabeformat sowie den Typ des Argumentes.
Die Unterscheidung zwischen d
und i
macht nur bei scanf
Sinn. Bei printf
bewirken beide Angaben dasselbe.
Diese Makros werden verwendet, indem sie durch Hintereinanderhängen des Formatstrings an die gewünschten Positionen geschrieben werden:
123
50000
75bcd15
34327724461477777
Es ist zu beachten, dass die Makros OHNE das Prozentzeichen %
definiert sind. Dadurch ist es möglich, weitere Formatierungs-Zeichen hinzuschreiben:
Die inttypes
-Bibliothek definiert noch einige weitere Makros, welche jedoch (vorerst) hier auf dieser Seite nicht aufgeführt werden.
Der traditionelle Weg: Die limits
-Bibliothek
Die in die Sprachen C und C++ eingebauten Basistypen char
, short
, int
, long
und long long
weisen je nach System eine unterschiedliche Anzahl Bits auf und können dementsprechend einen mehr oder weniger grossen Zahlenbereich abdecken. Die im aktuell verwendeten Compiler verfügbaren Minimal- und Maximalwerte der Basistypen sind als Konstanten in der limits
-Bibliothek definiert.
Der Autor empfielt, wenn immer möglich die limits
-Bibliothek nicht mehr zu verwenden und stattdessen mit der stdint
-Bibliothek zu arbeiten. Siehe oben.
Folgendes Beispielprogramm soll zur Auflistung der Makros genügen:
-128
127
255
-32768
32767
65535
-2147483648
2147483647
4294967295
-2147483648
2147483647
4294967295
-9223372036854775808
9223372036854775807
18446744073709551615
Es ist zu beachten, dass je nach System die ausgegebenen Werte durchaus unterschiedlich sein mögen, oder aber gewisse Makros gar nicht definiert sind. Die auf dieser Seite angegebenen Werte sind diejenigen, welche auf dem System des Autors ausgegeben wurden.
Es ist des weiteren zu beachten, dass keine Makros für den Minimalwert eines unsigned
-Typs existieren. Dieser ist in jedem Fall 0
(Null).
In der limits
-Bibliothek befinden sich zudem noch ein paar weitere Makros, welche jedoch für die alltägliche Programmierung kaum relevant sind. Sie sind in der folgenden Tabelle zusammen mit den beim Autor definierten Werten aufgelistet, allerdings wird auf dieser Seite nicht weiter darauf eingegangen. Der Interessierte Leser möge die Bedeutungen in der limits
-Bibliothek oder in anderen Quellen nachlesen.
Des weiteren definieren gewisse Implementationen noch zusätzliche Makros, welche jedoch weniger neue Funktionalität einführen, denn einfach die bestehende mit neuen Symbolen zu belegen.