2016-05-01 53 views
20

Bu C kodu örneği buldum ve kesinlikle şaşkın:C garip makro sözdizimi

#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); 
} 

Biri bunu yapmaya ne gerekiyor açıklayabilir misiniz? Visual Studio'da bile derleme yapmaz, ancak çevrimiçi (ideone.com) çalıştırdım ve karışıklığa da eklenmiş olan 2011'u yazdırdım.

+2

Olası yinelenen [ile 20 ve a ile gerçek değerleri, yani ab[a] Değişkenlerin yerini C neyi ??! ??! Operatör yapıyor musunuz?] (http://stackoverflow.com/questions/7825055/what-does-the-c-operator-do) – GSerg

+4

Bu gizlenmiş C yarışmasından mı geliyor? –

+0

, daha önce görmedim, açıklayamıyorum. Osx/darwin/unix derler. FYI, ilk satır "20", ikinci satır "1", üçüncü satır "1" değerlerini değerlendirir ve yazdırır. – user3078414

cevap

37

1994'te C standardında yapılan değişiklikler ve bu nedenle C99 standardının bir parçası olan C digraphs numaralı telefondan yararlanıyor. gerçek karakterlerle dışarı digraphs takas elde edersiniz:

#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); 
} 

Yani, a##b tek tanımlayıcı bir araya girdi birleşeceğini unutmayın.

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); 
} 

c için atama gerçekten alakalı değildir, bu nedenle bu kurtulabilirsiniz: Makro sadece a ve b geçirilir yana, sonuç etkili olması bu yüzden, sadece ab olduğunu

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); 
} 

Şimdi, statik olarak bunu halledebiliriz çünkü en, üçlü operatörü (?:) kurtulmak let (a 1 ve ab[1] 20 çünkü ab[a] daima doğrudur, yani sıfır olmayan):

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

Şimdi, bir 1

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

Etkileyici analizler –

+3

Vay, bu yeni bir olasılıklar dünyasını sunuyor. : D Teşekkürler! – Eutherpy

+58

@Eutherpy: Hayır. Yok. Bunu hiç görmedin mi? –