Dieses Stück Code ist zwar nicht standardkonform, aber gcc kompiliert es und die Ausgabe stimmt mit meiner Analyse des Codes überein. Leider kann ich die Ausgabe ohne etwas mehr Kontext nicht wirklich interpretieren. Wenn ich die Backspaces ignoriere, sieht die Ausgabe ungefähr so aus:
C!o!r!s!i!...
Um den Code zu analysieren, müssen wir ihn zunächst ein wenig formatieren:
#include <stdio.h>
char* _ ="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){
for(l+=7; l != putchar(010); ++l); // 010 = 8 -> backspace char
if(*(++_))
main(
*_ != 88 ? // *_ != 'X'
( putchar(*_ ^ 073) | putchar(33) ) & 1 : // 33 = '!'
0xffff2a8b);
}
Bevor wir weitermachen, sollten wir noch ein paar Dinge erwähnen:
- Si putchar erfolgreich ist, gibt es das übergebene Zeichen zurück.
- In C sind Zahlen, die mit 0 beginnen, eigentlich Oktale und nicht Dezimalzahlen. 010 ist also eigentlich die Dezimalzahl 8.
Beachten Sie nun, dass der Zeiger _ bei jeder Ausgabe mit dem Oktalwert 073 XOR-verknüpft wird. Wenn wir dies auf die gesamte Zeichenfolge anwenden, erhalten wir:
cCorsixcxCorsicixCorscsixCorcrsixCocorsixCcCorsixc
Dies ähnelt allmählich der Ausgabe, die wir zuvor gesehen haben. Fahren wir fort, indem wir einige der interessanteren Zeilen analysieren:
for(l+=7; l != putchar(010); ++l); // 010 = 8 -> backspace char
Der Sinn dieser Zeile ist es, eine Reihe von Leerzeichen auszugeben. Wenn l gleich 1 ist, wird nur ein Backspace ausgegeben. Wenn es aber gleich etwas anderem ist, wird es durchdrehen und eine ganze Ladung von Zeichen ausgeben. Das Verhalten hängt davon ab, wie main aufgerufen wird. Beim Start scheint es immer mit dem Wert 1 aufgerufen zu werden (ich weiß nicht, warum).
Schauen wir uns nun die Komponenten des rekursiven Hauptaufrufs an.
( putchar(*_ ^ 073) | putchar(33) ) & 1 : // 33 = '!'
Dies ist die erste mögliche Verzweigung. Zuerst wird eines der XOR-verknüpften Zeichen und dann ein '!'-Zeichen ausgegeben. Wenn Sie sich das Bitmuster von 33 ansehen, werden Sie feststellen, dass (x | 33) & 1 immer zu 1 ausgewertet wird. In diesem Fall geben wir also nur ein einziges Backspace-Zeichen in der for-Schleife aus.
Die zweite Verzweigung hingegen ist ein wenig kniffliger, weil der an main übergebene Wert nicht 1 ist. Wenn Sie sich die Ausgabe des Programms genau ansehen, werden Sie feststellen, dass es an einer bestimmten Stelle in der Zeichenkette eine ganze Reihe von Leerzeichen ausgibt. Ohne Kontext kann ich nicht wirklich sagen, was das Ziel ist.
Nun, da wir alle Teile haben, können wir den Code neu schreiben:
#include <stdio.h>
#define BIG_CONSTANT 42 // Not the actual value.
int main () {
char* str = "cCorsixcxCorsicixCorscsixCorcrsixCocorsixCcCorsixc";
putchar(8);
char* c = str;
while (*c != '\0') {
if (*c != 'c') { // 'X' ^ 073 = 'c'
putchar(*c);
putchar('!');
putchar(8);
}
else {
for (int i = 0; i < BIG_CONSTANT; ++i)
putchar(8);
}
c++;
}
}
Mein C ist ein wenig eingerostet, so dass dies möglicherweise nicht kompilieren/ausführen. Es sollte immer noch geben Sie eine gute Vorstellung davon, was los ist.
EDIT: Nun, ich war ein wenig spät dran, meine Antwort zu posten, und ich habe gerade festgestellt, dass meine Konsole die Leerzeichen ein wenig zu wörtlich ausgibt, anstatt einfach nur Zeichen zu entfernen. Das ist der Grund, warum ich die Ausgabe etwas falsch interpretiert habe. Also wie die akzeptierte Antwort sagt, wenn Sie tatsächlich die Backspaces richtig verarbeiten, druckt es Corsix!.