Initialisierung von Variablen
-
initialize schrieb:
Andromeda schrieb:
Variablen ausserhalb von Funktionen und static Variablen werden mit 0 initialisiert, wenn du keine explizite Initialisierung hinschreibst. Alle anderen Variablen haben undefinierten Inhalt, wenn du sie nicht initialisierst.
Ok - das heisst also bei (nehmen wir an int ist 2 Byte gross)
int = 10;
sieht der Speicher so aus:
00 0A
im anderen Fall
int i; i = 10;
ist der Speicher zuerst undefiniert und nach der Zuweisung ebendalls 00 0A.
Nein, der Compiler wird den gleichen Code erzeugen, als hättest du int i=10; hingeschrieben. Der Inhalt von i ist nur undefiniert, wenn du i niemals beschrieben (oder initialisiert) hast und dann ein Lesezugriff darauf ausgeführt wird.
initialize schrieb:
Das wirft aber etliche Frageb auf:
Nehmen wir an es gibt 2 Variable oder mehr:
int i =10; int i = 11;
Sieht dann der Speicher
00 0A 00 0B
so aus? Oder wie macht der Compiler das?
Bei zwei Variablen gleichen Namens streikt der Compiler.
Angenommen sie haben unterschiedliche Bezeichner: die beiden Variablen müssen nicht direkt hintereinander im Speicher sein. Das ist noch nicht einmal bei Struct-Members garantiert.
-
Variablen sind Schall und Rauch. Sie sind Hilfsmittel für den Programmierer. Der Compiler erzeugt ein Programm, dass sich so verhält, wie der Programmierer es mit den Variablen beschreibt. Wie das intern genau funktioniert, ist nicht genau definiert. Das kann eventuell so funktionieren, wie Andromeda das hier beschreibt, denn es ist eine sehr naheliegende Art und Weise ein Programm zu erzeugen, dass sich so verhält, wie der Programmierer es mit variablen beschrieben hat, indem man tatsächlich jeder Variablen eine Speicherzelle zuordnet. Das ist aber nicht die einzige Methode und auch selten die effizienteste Methode. Daher wird ein vom Compiler erzeugtes optimiertes Programm oft ganz anders funktionieren.
-
Ok - damit ist die Frage beantwortet - besten Dank!
Ich ging davon aus, dass der Datenteil eines C-Programms genauso behandelt wird, wie der Code selbst - sprich: Der Code MUSS ja an einem "Stück" sein - da darfs irgendwie keine Lücken geben, Wenn das beim Datenteil nicht so ist... Schade eigentlich.
Besten Dank nochmal
-
initialize schrieb:
Andromeda schrieb:
Variablen ausserhalb von Funktionen und static Variablen werden mit 0 initialisiert, wenn du keine explizite Initialisierung hinschreibst. Alle anderen Variablen haben undefinierten Inhalt, wenn du sie nicht initialisierst.
Ok - das heisst also bei (nehmen wir an int ist 2 Byte gross)
int = 10;
sieht der Speicher so aus:
00 0A
im anderen Fall
int i; i = 10;
ist der Speicher zuerst undefiniert und nach der Zuweisung ebendalls 00 0A.
Die Annahme dass es zwei Byte sind ist de facto falsch, da die Zahl 10 als ein Byte bzw. mit 8 Bit intern dargestellt werden kann. Es ist kein "char" bzw. char Array oder im Volksmund "String"...
Man sollte auch immer Variablen setzen, wenn du mit "-Wall" kompilierst, wird dein Compiler dich zu dem warnen, das Variablen nicht deklariert worden sind, zumindest der GCC. Es kann natürlich sein, dass du den Wert direkt darunter setzt und es auch so erkannt wird. Aber alles was du zwischen "Deklaration" und "Initialiersung" machst - ist undefiniert und kann etwas zum Abstürzen bringen oder Garbage Ausgeben, wenn der Wert "irgendwas" beinhaltet aber nicht das was du eigentlich haben willst zur Berechnungen oder was auch immer.
Daher würde ich dazu raten, Variablen immer zu initialisieren (also einen Wert zu setzen) bevor diese verwendet werden bzw. gleich während der Deklaration.
Worauf willst du damit eigentlich hinaus, mit dieser "Storage Map"?
-
theSplit schrieb:
Die Annahme dass es zwei Byte sind ist de facto falsch, da die Zahl 10 als ein Byte bzw. mit 8 Bit intern dargestellt werden kann.
Nun, er ging von einem
int
aus und der hat mindestens 16 Bit, was i.A. zwei Byte sind.theSplit schrieb:
Daher würde ich dazu raten, Variablen immer zu initialisieren (also einen Wert zu setzen) bevor diese verwendet werden bzw. gleich während der Deklaration.
Bei der Deklaration hat das wenig Zweck, da dort kein Speicher belegt wird, der den Wert aufnehmen kann.
Bei der Definition ist das freilich anders.Wenn die erste Verwendung die Zuweisung von einem Rückgabewert einer Funktion ist, brauchst sie vorher keinen anderen Wert.
-
DirkB schrieb:
theSplit schrieb:
Die Annahme dass es zwei Byte sind ist de facto falsch, da die Zahl 10 als ein Byte bzw. mit 8 Bit intern dargestellt werden kann.
Nun, er ging von einem
int
aus und der hat mindestens 16 Bit, was i.A. zwei Byte sind.Kommt auf das System an, es gibt auch noch 8bit Integers, oder? Bzw. gab es die mal, ich bin da nicht so firm
theSplit schrieb:
Daher würde ich dazu raten, Variablen immer zu initialisieren (also einen Wert zu setzen) bevor diese verwendet werden bzw. gleich während der Deklaration.
Bei der Deklaration hat das wenig Zweck, da dort kein Speicher belegt wird, der den Wert aufnehmen kann.
Bei der Definition ist das freilich anders.Wenn die erste Verwendung die Zuweisung von einem Rückgabewert einer Funktion ist, brauchst sie vorher keinen anderen Wert.
Ja, das ergibt sich aber aus dem Kontext. Wenn die Variable deklariert wird, zum Beispiel außerhalb einer For-Schleife (als "Platzhalter") und in dieser ein Rückgabewert den Wert setzt, ist es ja auch relativ "safe" - so fern gesichert ist, das der Rückgabewert die Variable "initialisiert" bzw. "aktualisiert".
Es war eigentlich auch nur ein gut gemeinter Hinweis das man nichts "im Raum schweben" lassen sollte, außer man wäre sich 100% sicher.
Aber selbst dann ist ein Initialisieren nie schlecht, es tut nicht wirklich weh, glaube ich mal sagen zu können. Außer man befindet sich in einer Schleife.
-
theSplit schrieb:
Kommt auf das System an, es gibt auch noch 8bit Integers, oder? Bzw. gab es die mal, ich bin da nicht so firm
Du kannst das bei (manchen) Compilern für (8-Bit-)Mikrocontrollern umschalten.
Aber nach ISO-Standard (achte auf den Titel dieses Unterforums) ist der Wertebereich eine
int
mindestens von -32767 bis 32767.
-
Und ich dachte...
Folgendes zeigt es aber auch, es sind 16 Bit..
https://de.wikipedia.org/wiki/Integer_(Datentyp)#BeispieleIch dachte immer nur zahlen bis 65.535 (unsigned) bzw. signed (−32.768 bis 32.767) lassen sich in einem Bit darstellen, wobei man im "Hintergrund" den Signed/Unsigned Flag auf Prozessorebene hat welcher die Reichweite bestimmt.
Wohl doch nicht so einfach wie ich dachte, danke für den Hinweis
Wobei, irgendwie auch logisch...
-
theSplit schrieb:
Ich dachte immer nur zahlen bis 65.535 (unsigned) bzw. signed (−32.768 bis 32.767) lassen sich in einem Bit darstellen, wobei man im "Hintergrund" den Signed/Unsigned Flag auf Prozessorebene hat welcher die Reichweite bestimmt.
Damit bist du total auf dem Holzweg. Mit EINEM Bit kannst du nur 2 Zahlen bzw. Zustände speichern.
-
Ja, ich glaub ich verstehe es vielleicht auch.
Aber dann müsste ich mit einem "signed" Integer theoretisch auch negative Werte bis zu -65535 speichern können.
Rein von der Logik, wenn das am Prozessor-Flag entschieden wird ob der Wert negativ oder positiv ist.. da ist die andere Aufteilung nicht ganz logisch.
Wobei, es müsste "signed" geben (negativ, ist aber auch positiv!) "unsigned" (positiv) und noch etwas drittes...
Ist wohl ein Zustand zu viel...
-
signed
heißt "mit Vorzeichen". Das Vorzeichen wird mit abgespeichert und belegt somit auch etwas von den 16-Bit.
Das Prozessor-Flag nützt im Speicher nicht viel.Bei
unsigned
hat mansich aufpositive Zahlengeeinigtfestgelegt.
-
DirkB schrieb:
signed
heißt "mit Vorzeichen". Das Vorzeichen wird mit abgespeichert und belegt somit auch etwas von den 16-Bit.
Das Prozessor-Flag nützt im Speicher nicht viel.Bei
unsigned
hat mansich aufpositive Zahlengeeinigtfestgelegt.Macht auch Sinn. "Irgendwo" muß die Information ablegt sein, ob ich positiv oder negativ dargestellt werden will, egal wie hoch oder niedrig der Wert an sich wäre.
Dann macht das mit dem begrenzten "signed" Raum auch Sinn. Hab ich noch gar nicht darüber nachgedacht.
-
theSplit schrieb:
Ja, ich glaub ich verstehe es vielleicht auch.
Aber dann müsste ich mit einem "signed" Integer theoretisch auch negative Werte bis zu -65535 speichern können.
Rein von der Logik, wenn das am Prozessor-Flag entschieden wird ob der Wert negativ oder positiv ist.. da ist die andere Aufteilung nicht ganz logisch.
Wobei, es müsste "signed" geben (negativ, ist aber auch positiv!) "unsigned" (positiv) und noch etwas drittes...
Ist wohl ein Zustand zu viel...
Bei n Bits wird ein Bit fürs Vorzeichen reserviert, wenn man positive und negative Zahlen haben will, also bleiben für den Betrag nur n-1 bits. Bei 16-bittigen Integers also 15 Bits, d.h. 2^15, respektive 32768 Zahlen positiv und ebenso viele negativ. Da man dann aber 2 Nullen (oder gar keine) hätte, nimmt man das Zweierkomplement-Format. Dann hat man 32768 negative Zahlen, 32767 positive Zahlen und eine Null.