2016-05-01 25 views
20

ich dieses C-Code Beispiel gefunden, und ich bin verwirrt absolut:C seltsam Makro Syntax

#include <stdio.h> 
#define M(a,b) a%:%:b 

main() 
{ 
    int a=1, b=2, ab[]={10,20}, c; 
    printf("%d", M(a,b)<:a:>); 
    printf("%d", M(a,b)<:a:>?a:b); 
    printf("%d", c=M(a,b)<:a:>?a:b); 
} 

Könnte jemand erklären, was das tun soll? Es kompiliert nicht sogar in Visual Studio, aber ich lief es online (auf ideone.com) und es druckte 2011, das auch zur Verwirrung hinzufügte.

+2

Mögliche Duplikat [Was die C tut ??! ??! Betreiber tun?] (http://stackoverflow.com/questions/7825055/what-does-the-coperator-do) – GSerg

+4

Ist dies von der verschleierten C Contest? –

+0

kann ich nicht erklären, auch nicht vorher gesehen. Es kompiliert in osx/darwin/unix. FYI, erste Zeile wertet und druckt "20", zweite Zeile "1", dritte Zeile "1". – user3078414

Antwort

37

Es verwendet C digraphs, die 1994 zur C-Norm wurden und daher Teil des C99-Standards sind. Vertauschen der Digraphe aus mit ihren tatsächlichen Zeichen erhalten Sie:

#include <stdio.h> 
#define M(a,b) a##b 

main() 
{ 
    int a=1, b=2, ab[]={10,20}, c; 
    printf("%d", M(a,b)[a]); 
    printf("%d", M(a,b)[a]?a:b); 
    printf("%d", c=M(a,b)[a]?a:b); 
} 

Also, denken Sie daran, dass a##b fusionieren zusammen, um den Eingang zu einer einzigen Kennung. Da das Makro nur a und b übergeben wird, ist das Ergebnis nur ab, so dass Sie effektiv haben:

main() 
{ 
    int a=1, b=2, ab[]={10,20}, c; 
    printf("%d", ab[a]); 
    printf("%d", ab[a]?a:b); 
    printf("%d", c=ab[a]?a:b); 
} 

Die Zuordnung zu c nicht wirklich relevant ist, so können wir davon loswerden:

main() 
{ 
    int a=1, b=2, ab[]={10,20}; 
    printf("%d", ab[a]); 
    printf("%d", ab[a]?a:b); 
    printf("%d", ab[a]?a:b); 
} 
Jetzt

, lassen sie uns loszuwerden, die ternäre Operator (?:), weil wir es statisch aus arbeiten können (ab[a] immer wahr ist, weil a 1 und ab[1] 20 ist, dh nicht-Null):

main() 
{ 
    int a=1, b=2, ab[]={10,20}; 
    printf("%d", ab[a]); 
    printf("%d", a); 
    printf("%d", a); 
} 

Nun ersetzen Variablen mit ihren tatsächlichen Werten, das heißt ab[a] mit 20 und a mit 1

main() 
{ 
    int a=1, b=2, ab[]={10,20}; 
    printf("%d", 20); 
    printf("%d", 1); 
    printf("%d", 1); 
} 
+7

beeindruckende Analyse –

+3

Wow, das eröffnet eine ganz neue Welt der Möglichkeiten. : D Danke! – Eutherpy

+58

@Eutherpy: Nein. Nein, tut es nicht. Tu so, als hättest du das nie gesehen. –