3 Stimmen

Warum funktioniert printf("%d\n", printf("%d\b", a)) so?

Das ist mein C-Code, kompiliert mit gcc.

#include

int main()
{
    int a=1;
    switch(a)
    {
       int x=10;
       case 1:
           printf("%d\n",printf("%d\b",x));
           break;
       default:
           printf("%d\n",printf("%d\b",x));
    }
    return 0;
}

printf() soll die Anzahl der erfolgreich gedruckten Elemente zurückgeben. printf("%d\b", x) sollte von alleine 10 drucken (da das \b den Druckzeiger um einen Schritt zurücknimmt (zur Ziffer 0 in 10) und danach nichts mehr zum Drucken da ist. Es sollte also nur 10 gedruckt sein. Das sind 2 Zeichen. Nun würde das äußere printf 2 anzeigen. Die Ausgabe sollte also 102 sein. Die tatsächliche Ausgabe, die ich sehe, ist 2.

Und im Fall von verschachtelten printfs wird die Druckzeigerposition erinnert? Das heißt, wenn es ein \b im inneren printf gibt, würde der Druckzeiger einen Schritt zurücknehmen. Und wenn die Steuerung dann zum äußeren printf geht, wird diese geänderte Position erinnert? Wird sie über dieses letzte Zeichen drübergeschrieben?

5voto

Keith Thompson Punkte 240701
printf("%d\b",x)

druckt die Zeichen '1', '0' (weil x==10) und \b. Das \b ist ein Rückschritt-Zeichen; wenn Sie auf ein Terminal drucken, wird es 10 drucken und dann den Cursor um eine Spalte zurücksetzen.

Ein Aufruf von printf gibt die Anzahl der gedruckten Zeichen zurück; in diesem Fall ist das Ergebnis 3 (ja, '\b' zählt als ein Zeichen).

printf("%d\n",printf("%d\b",x));

Der innere Aufruf von printf funktioniert wie oben erklärt und gibt 3 zurück. Der äußere Aufruf von printf druckt "3\n".

Also wird die gesamte Anweisung drucken:

10\b3\n

Das '\b' bewirkt, dass die 3 das 0 auf dem Bildschirm ersetzt, also ist das endgültig angezeigte Ergebnis (wenn ich das Programm auf meinem System ausführe):

13

Wenn ich die Ausgabe durch cat -v weiterleite, erhalte ich:

10^H3

wo ^H das Rückschritt-Zeichen darstellt.

BEARBEITEN:

Die Frage wurde gerade bearbeitet und das veränderte Verhalten des Programms ist ziemlich anders. Die switch-Anweisung lässt die Kontrolle vorbei an der Deklaration int x = 10; springen, aber in den Bereich, in dem x deklariert ist. Als Ergebnis ist x nicht initialisiert, wenn printf aufgerufen wird. Das führt zu undefiniertem Verhalten und höchstwahrscheinlich zu einem fehlerhaften Output (ich habe gerade -1217572876^H12 erhalten). Wenn x zufällig 0 ist, würde man wahrscheinlich 0^H2 erhalten, was wie 2 aussehen würde.

Was auch immer Sie vorhaben, bitte finden Sie einen besseren Weg, um es zu tun.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X