2008-10-07 18 views
15

Bugün aşağıdaki kodla (bazılarınız bunu tanıyabilir) rastladı: Bildiğiniz C++ kodunun anlaşılması en zor olan nedir? iş yerinde

#define GET_VAL(val, type) \ 
    {             \ 
     ASSERT((pIP + sizeof(type)) <= pMethodEnd); \ 
     val = (*((type *&)(pIP))++);     \ 
    } 

Temelde biz bir bayt dizisi ve bir işaretçi var. Makro, bir değişken türüne bir başvuru döndürür ve işaretçiyi bu değişkenin sonuna doğru ilerletir.

C++ kodunu anlamak için "ayrıştırıcı gibi düşünmek" gerektiğimi birkaç kez hatırlattı.

Yapmanız gerektiğini düşündüğünüz şeyi kavrayabilmeniz için birkaç kez durmanıza ve okumanıza neden olan diğer kod örneklerini biliyor musunuz?

+3

onun değil - Bu soruyu, ilginç ve karışıklık yollarını gösterebilmemiz için yazdım. C++ kullanımı. Böylece bu örneklerden öğrenebiliriz. –

+4

Kapanış soruları hakkında bu yorum çok saçma. – Terminus

+2

Her halükarda, bu topluluk wiki olmalıdır. –

cevap

29

ters karekök uygulaması:

float InvSqrt (float x){ 
    float xhalf = 0.5f*x; 
    int i = *(int*)&x; 
    i = 0x5f3759df - (i>>1); 
    x = *(float*)&i; 
    x = x*(1.5f - xhalf*x*x); 
    return x; 
} 

Güncelleme: How this works (teşekkürler ryan_s)

+1

Chris Lamont'un makalesini, bu çılgın şeyin nasıl çalıştığına dair büyük bir açıklama için bağlamayı unutmayın. http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf –

2

C ancak C++ mevcut, ben virgül operatörü gerçekten kodu obfuscates bulmak ... bunu al

ihi = y[0]>y[1] ? (inhi=1,0) : (inhi=0,1); 

kısa ve öz ve oldukça şık, ama çok kolay kaçırmak veya yanlış anlamak için.

+2

Bana göre bu kod, "Sadece bir şey yapabileceğiniz için, yapmanız gereken anlamına gelmez" diye mükemmel bir örnektir. Temiz, çünkü bir satırda, ama eğer daha fazla yayılmışsa, ilk kez birileri tarafından bakıldığında bir çok kez daha anlaşılabilir olurdu. Bu hoş bir örnek değil. :) – Colen

9

Bu iyi bilinmektedir ancak yine etkileyici yolu geçici değişken yaratmadan iki tamsayı takas:

java.util.concurrent.ConcurrentHashMap bir örnek:

// a^=b^=a^=b;  // int a and int b will be swapped 
// Technically undefined behavior as variable may only 
// be assined once within the same statement. 
// 
// But this can be written correctly like this. 
// Which still looks cool and unreadable ;-) 

a^=b; 
b^=a; 
a^=b; 
+2

sadece sorun, bu, sıralama noktası kuralları nedeniyle teknik olarak tanımlanmamış bir davranış olmasıdır. "a^= b; b^= a; a^= b;" kullanın yerine. –

+0

Yanlış. bu doğru. Bu durumda operasyon sırası, sağdan sola mükemmel şekilde tanımlanır. Standardı okuyun, – Terminus

+3

@ Terminus: Siz infact yanlisisiniz. Bir değişkendeki bir değişkenden birden çok kez atanmak tanımlanmamış bir davranıştır. Bunu önlemek için ';' onları farklı ifadelere ayırmak. –

0

İkili kaymalar her zaman kafamı karıştırıyor :

dönüş ((h < < 7) -, h + (h >>> 9) + (h >>> 17))

+3

Neden bu oy verildi? Bu Java, ama soru C++ ile ilgili. – finnw

25

Bu kırmızı oldu dit son http://www.eelis.net/C++/analogliterals.xhtml

assert((o-----o 
     |  ! 
     !  ! 
     !  ! 
     !  ! 
     o-----o).area == (o---------o 
          |   ! 
          !   ! 
          o---------o).area); 
+0

bu bir totolojidir. – Haoest

+2

Şimdi * bu * neden C++ 'yı seviyorum! –

+0

Link şimdi kırık :( –

10
unsigned int reverse(register unsigned int x) 
{ 
x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); 
x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); 
x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); 
x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); 
return((x >> 16) | (x << 16)); 
} 

bir int bitlerin sırasını tersine çevirir.

+0

Bu akıllı bir hile kodu o zaman +1 olmuştu. –

+0

Aslında bunun işlev adı nedeniyle ne yaptığını anlamak çok zor değil. Bu _how_ bitti, bu çok zor. – einpoklum

+0

Bu, biraz daha belirsiz bir C kodu olan iki yönlü bir işlemdir. –

-3

Bazı siyah-sihir-hackerish şablon meta programlamasında oy veriyorum (maalesef yayınlamak için elinizde hiç yok).

14

Duff Cihazı (http://en.wikipedia.org/wiki/Duff%27s_device) Beni vermek kabus:

strcpy(to, from, count) 
char *to, *from; 
int count; 
{ 
    int n = (count + 7)/8; 
    switch (count % 8) { 
    case 0: do { *to = *from++; 
    case 7:  *to = *from++; 
    case 6:  *to = *from++; 
    case 5:  *to = *from++; 
    case 4:  *to = *from++; 
    case 3:  *to = *from++; 
    case 2:  *to = *from++; 
    case 1:  *to = *from++; 
       } while (--n > 0); 
    } 
} 
+0

Her zaman Duff Cihazını oldukça sezgisel buldum, sadece mantıklı. Döngünün garip sözdizimini ele geçirdikten sonra ya da belki de –

+0

'u açıp kapatabiliyorsanız, montajı arka plandan gelmektense montajı programladıysanız bunun daha kolay olduğunu düşünüyorum. – Skizz

6

En Boost şeyler - şablon metaprogramming yeterince kötü, ama gerekli geçici çözümler faktör zaman (bazı derleyicilerde işe gitmek için * coughborlandcough *), oldukça gülünç oluyor. Sadece Boost.Bind'i anlamaya çalış. Sadece dene.Quake 3