Seite 1 von 1

Was ist der Unterschied zwischen zuweisung und instialisierung?

Verfasst: Fr Nov 29, 2019 2:31 pm
von zaid38
1)/* Zuweisungen für erstes Feld */
anzahlFeld[0] = 2;
anzahlFeld[1] = 7;
anzahlFeld[2] = 3;
/* Zuweisungen für zweites Feld */
preisFeld[0] = 1.45;
preisFeld[1] = 0.85;
preisFeld[2] = 0.75;

2)int main()
{
/* Deklaration, teilweise mit Initialisierung *
/
int anzahlFeld[3] = {2, 7, 3};
double preisEinzelFeld[3] = {1.45, 0.85, 0.75};
int index;
double preisGesamt;

Re: Was ist der Unterschied zwischen zuweisung und instialisierung?

Verfasst: Fr Nov 29, 2019 2:54 pm
von Xin
Eine Initialisierung findet auf einem nicht initialisiertem Speicherbereich statt, während eine Zuweisung auf einem initialisierten Speicherbereich schreibt.

In C macht das auf den ersten Blick erstmal wenig Unterschied.

In dem von Dir beschriebenen Fällen spart die Initialisierung allerdings nicht unnötigen Code, sondern auch Zeit.
Während die Zuweisung einzeln, Zahl für Zahl, auf den jeweiligen Speicherbereich geschieht, der auch in Abhängigkeit des Indizes immer wieder neu berechnet werden muss, besagt die Initialisierung, das da jetzt ein Speicherblock folgt, der genau dahin geschrieben wird, wo das Feld beginnt und der als ein Block kopiert werden kann.
Hierfür haben CPUs teilweise Spezialbefehle, bzw. man muss die Positionen nicht laufend neu Berechnen, sondern es ist bekannt, dass ein Byte dem nächsten folgt.

In C++ unterscheidet sich das noch, üb ein Objekt konstruiert wird (der Speicherbereich also zuvor kein gültiges Objekt repräsentierte) oder ein existierendes Objekt entsprechend der Zuweisung geändert wird. Ein Pointer muss hierfür bei der Zuweisung evtl. freigegeben werden, bevor er überschrieben wird, während bei der Initialisierung der Pointer definitiv nicht valide war.

Re: Was ist der Unterschied zwischen zuweisung und instialisierung?

Verfasst: Fr Nov 29, 2019 3:10 pm
von zaid38
Zitat(Eine Initialisierung findet auf einem nicht initialisiertem Speicherbereich statt, während eine Zuweisung auf einem initialisierten Speicherbereich schreibt.) verstehe immer nicht gut

Re: Was ist der Unterschied zwischen zuweisung und instialisierung?

Verfasst: Fr Nov 29, 2019 3:32 pm
von Xin
zaid38 hat geschrieben:
Fr Nov 29, 2019 3:10 pm
Zitat(Eine Initialisierung findet auf einem nicht initialisiertem Speicherbereich statt, während eine Zuweisung auf einem initialisierten Speicherbereich schreibt.) verstehe immer nicht gut
Wie gesagt: Das ganze ist aus einer C++-Sicht, wo hier deutlicher unterschieden wird.

Eine Variable ist ja ein Speicherblock. In dem Moment, wo die Variable beginnt zu existieren, ist dieser Speicherblock aber halt uninitialisiert - der Inhalt ist willkürlich. Die erste Zuweisung nennt man Initialisierung. Das passiert im Idealfall aber nicht durch eine eigene Zuweisung, sondern durch eine Zuweisung, die der Compiler macht. Überschreibt man den Speicherblock spricht man von einer Zuweisung.
In C ist die Unterscheidung nur dadurch gegeben, dass die Initialisierung das erstmalige Beschreiben darstellt, im Idealfall beim Anlegen der Variable:

Optisch sieht das häufig ähnlich wie die Zweisung aus

Code: Alles auswählen

int a = 0; // Initialisierung
float f = 0.0f; // Initialisierung
int v[2] = { 1, 2 };  // Initialisierung.
Es ist aber eben keine Zuweisung, denn beispielsweise

Code: Alles auswählen

v = { 1, 2 };
ist keine valide Syntax, auch wenn

Code: Alles auswählen

f = 0.0f; // Zuweisung
a = 1;    // Zuweisung
eine valide Zuweisung ist und der Initialisierung sehr ähnlich aussieht.

In C werden Primitive (dazu zählen auch int, float und Zeiger) nur auf Anfrage des Programmierers initialisiert, während Felder manchmal automatisch initialisiert werden (nämlich dann, wenn es zur Laufzeit nichts kostet). Vereinfacht ausgedrückt - es schadet nicht davon auszugehen, dass sie nicht ohne ausdrücklichen Wunsch initialisiert werden. ;-)

Bei einer Zuweisung sollte eine Variable bereits einen gültigen Wert haben, denn dann überschrieben wird. Ohne Initialisierung haben die Variablen aber einen willkürlichen Wert.
Während eine Integervariable nur einen willkürlichen aber validen Wert haben kann, kann eine float auch einen invaliden Wert haben. Ein nicht initialisierter Integer sorgt für fehlerhafte Berechnungen. Es gibt bei floats hingegen Zahlen, die es nicht gibt. Das sind also keine gültigen Werte. Damit kann man auch nichts Falsches rechnen, wenn einem das Programm um die Ohren fliegt. ;)

Nicht initialisierte Variablen sind eine häufige Fehlerursache. Deswegen wurde da in C++ mehr Wert drauf gelegt, dass eigene Datentypen initialisiert werden, weswegen die Unterscheidung auch hier erst deutlicher zum Tragen kommt und sich auch mehr Unterschiede aufzeigen. Ansonsten vereinfacht: Initialisierung ist die erstemalige Zuweisung.

Re: Was ist der Unterschied zwischen zuweisung und instialisierung?

Verfasst: Fr Nov 29, 2019 5:42 pm
von mfro
in 99% der Fälle: Initialisierung = Deklaration + Zuweisung

Code: Alles auswählen

int main()
{
    int xy[2] = { 1, 2 };
  
    ...
}
und

Code: Alles auswählen

int main()
{
    int xy[2];

    xy[0] = 1;
    xy[1] = 2;
    
    ...
}
erzeugt (zumindest bei allen mir bekannten Compilern) 100% den exakt identischen Code. Für das Programm spielt es keine Rolle, ob man die Deklaration von der Zuweisung trennt oder nicht.

Es gibt eine Ausnahme: die Initialisierung von globalen Variablen:

Code: Alles auswählen

int xy[2] = { 1, 2 };

int main()
{
    ...

Code: Alles auswählen

int xy[2];

int main()
{
    xy[0] = 1;
    xy[1] = 2;
    
    ...
Im ersten Beispiel kann der Compiler optimieren und die Variablenwerte direkt ins Programm (bzw. in sein .data-Segment) schreiben (dann müssen die Variablen zur Laufzeit nicht mehr umgeschaufelt werden weil die bereits der Loader beim Programmstart an die richtige Stelle packen kann). Die erste Variante ist die schnellere (macht sich aber nur bei der Initialisierung von grossen Feldern oder Strukturen bemerkbar).

Bei lokalen Variablen (also den beiden Beispielen vom Anfang, wo die Variable innerhalb von main() deklariert/initialisiert wurde) geht das nicht. Lokale Variablen "wohnen" auf dem Stack und wo der ist, weiss man erst nach dem Start des Programms.