C Müsste wissen wieviel Byte char,int,double usw. belegen

ReVo

Lieutenant
Registriert
Jan. 2006
Beiträge
567
Hallo,

mir wurde gesagt, dass ich unbedingt wissen sollte wieviel Byte einzelne chars,int,double bis hinzu struct belegt werden wenn ich C richtig verstehen will. Also ich denke ich habs, bin mir aber bei einigen Sachen nicht sicher. Nehmen wir ich arbeite mit C unter einem 32bit betriebsystem, dann müsste alles wie folgt aussehen:

char = 1Byte
int = 4Byte
long = bin mir nicht sicher, ist es 4 oder 8Byte?
float = das gleiche wie mit long?
double = 8Byte
long double = 10Byte

struct = es werden alle Elemente aufaddiert. Das heißt, wenn man 1 int und 1 char im struct hat, dann hat man 5Byte. Das ist klar, aber bei union verstehe ich die ganze geschichte nicht ganz. Soweit ich weiß, wird von allen die größte Wert genommen. Also habe ich ein struct mit 1 char 1 int und 1 double, dann hat struct die größe von 8Byte. Heißt die Antwort, weil union versucht alles auf einem Speicher zu legen? - das wäre jetzt meine eigene Erklärung.

Ahja noch was, wenn ich zb. int[5] habe, dann ist das sowas wie 5*4 = 20Byte ja? Nehme das mal stark an, denn bei char ist das so, dass char[20] = 1*20 = 20Byte ist. Ich muss leider hier Fragen, denn in C weiß ich nicht wirklich wie ich da nachgucken soll wieviel Byte dies und das ist. Vielleicht kann man das ja auch in C prüfen?

Also korrigiert mich bitte, wenn ich was falsch habe. Danke!

Gruß
 
Grundsätzlich hast Du Recht.

C-Compiler @ 32-Bit:

char: 1 Byte
short: 2 Bytes
int: 4 Bytes
long: 4 Bytes
long long: 8 Bytes
float: 4 Bytes
double: 8 Bytes

In der Praxis belegt ein Struct mit 1x char, 1x short, 1x int nicht zwingend 7 Bytes, es können durchaus 8 Bytes sein, da möglicherweise aus Geschwindigkeitsgründen ein 4-Byte-Alignment benutzt wird. Die Compiler-Direktive #pragma pack(push,1) erzwingt dann ein 1-Byte-Alignment (nützlich bei Netzwerkprogrammierung/Dateiformaten).

Eine Union legt alle darin enthaltenen Werte auf dem selben Speicherplatz ab. Der größte Member bestimmt sodann die Gesamtgröße der Union (in Deinem Fall das Double). Je nach angesprochenem Member wird beim Auslesen der Typ auf die Member-Größe beschränkt/ausgedehnt.


Bei der Programmierung solltest Du "sizeof" nutzen, um die tatsächliche Größe im Speicher zu erfragen. Dies ist übrigens keine Funktion, sondern wird bei der Kompilierung in eine Konstante übersetzt.
Somit evaluiert sizeof(int) auf einem 32-Bit-Compiler zu 4 und auf einem 64-Bit-Compiler zu 8.
 
Wenn du sicher gehen willst, kannst du auch Datentypen mit fester Breite wie z. B. int32_t nehmen, die es seit C99 gibt. Ansonsten die die Größe der Datentypen in C nicht festgeschrieben.
 
Somit evaluiert sizeof(int) auf einem 32-Bit-Compiler zu 4 und auf einem 64-Bit-Compiler zu 8.
Bist du dir da sicher? Ist das bei jedem Compiler und jedem Betriebssystem so?
Ich dachte immer, dass es hierfür spezielle 64bit ints gibt, aber ich lass mich gerne eines Besseren belehren...
 
Es gibt ein spezielles 64 bit int das heißt: __int64
Ob ein int auf einem 64 bit System auch 8 Byte groß ist hängt natürlich vom Compiler ab.

Gruß
BlackMark
 
Hallo,

danke für die infos. Versuche jetzt immer mit sizeof zu arbeiten, wenn ich wissen will wieviel Byte etwas belegt.

Gruß
 
sizeof ist definitiv am besten geeignet dafür, wenn man standardkonform bleiben möchte.
Warum schreibst du nicht ein Testprogramm, dass dir die Größen auf die Konsole ausgibt? Man könnte auch in einem Pre-Build-Step ein Progrämmchen mit den aktuellen Compiler-Optionen kompilieren und ausführen, was dann eine Headerdatei mit Typen passender Größe generiert.

Wichtig zu beachten ist: Die größe der Datentypen kann sich je nach Compileroptionen ändern (außer char/signed char/unsigned char). Lediglich für char's wird dir von der Sprache selbst eine Größe von einem Byte garantiert. Der Rest ist zwar bei einem Compiler in der selben Version und den selben Compileroptionen konstant, aber eine Garantie auf die Größen hast du nicht. Gerade deshalb sollte man niemals versuchen, Datentypen und deren Layout im Speicher zu "röntgen". Immer daran denken: if you're trying to be smarter than your compiler, it'll get its revenge.

Und außerdem: Wenn man C richtig können will, sollte man sich nicht auf Repräsentationen im Speicher verlassen, sondern mit der Sprache und deren Typen arbeiten! Nur wenn man die tatsächliche Repräsentation im Speicher zwingend benötigt, sollte man sich auf so schmutzige, gefährliche Untiefen begeben.
 
mit typengrößen bei C musst du ganz vorsichtig sein. das is sehr compiler-spezifisch.
insbesondere long ist davon betroffen.

hier kurze zusammenfassung:
char = 1 byte (32/64)
short = 2 byte (32/64)
int = 4 byte (32/64)
long = 4 byte (32/64, 64 kann abweichen!)
float = 4 byte (32/64)
double = 8 byte (32/64)

jetz kommt der komplizierte part:
long long = 8 byte (KEIN microsoft! zu verwenden z.b. bei GCC)
__int64 = 8 byte (NUR microsoft!)
long double = 10 bytes (ebenfalls vom compiler abhängig! microsoft z.b. unterstützt das nicht und macht ein normales double drauss)

es empfiehlt sich generell ne header-datei anzulegen, wo man seine eigenen typen abhängig vom compiler definiert. dann biste idr auf der sicheren seite.
 
ist auch nicht automatisch überall verfügbar. msvc kennt int32_t z.b. nicht. müsste man dann zusätzlich über ne custom stdint.h importieren.
 
hängt alles vom kompiler ab! bei mir war es so eingestellt das man char bis 1 Gig adressieren konnte...
 
Zurück
Oben