Nun, Sie haben &x
, die eine Adresse, die auf x
zeigt, und eine p
ebenfalls.
Dann ändern Sie den Wert , dh. Ändern Sie, dass es auf x
nur zeigt, dass jetzt, wenn Dereferenzierung p
die Bytes als Float interpretiert werden. Als (möglicherweise) sizeof(int) != sizeof(float)
werden sogar einige Bytes ausgewertet, die vorher nicht oder umgekehrt waren.
Sie greifen also auf den Speicher zu, für den der C-Standard keine Definitionen hat, d. UB.
Außerdem weisen Sie *p
einen neuen Gleitkommawert zu und schreiben sogar in diesen Bereich, der einmal ein int
war.
Es ist kein Wunder, dass bei der Auswertung der ersten printf()
der Compiler ist verwirrt - es ist sowieso UB.
Die zweite Anweisung atleast gibt ihm nicht widersprüchliche Anweisungen: Drucken Sie eine int
von einer int
(und nicht versuchen, eine int
als float
zu interpretieren).
Der dritte hat dich glücklich gemacht, da, wie ich vorher erwähnt habe, die float
möglicherweise nicht in die int
passen würde und somit die Werte jederzeit überschrieben werden oder sogar eine SEGFAULT verursachen.
Ja, es ist UB. Welche Leistung haben Sie erwartet? –
Ja, aus zwei Gründen: 1) Sie brechen die Strict-Aliasing-Regel 2) Sie verwenden den falschen Formatbezeichner '% f' für einen' int'. –
Ich nehme an, nur der erste printf braucht eine Erklärung, aber es hängt ganz davon ab, wie die Argumente an die Funktion übergeben werden, was vom Compilermodus und der Version abhängt. Beachten Sie, dass vs2015 sogar eine Warnung erzeugt, dass ein falsch eingegebenes Argument verwendet wurde. –