以下六個程式片段皆能輸出「Hello, World」,但手段極盡混淆之能事:巨集遞迴展開、位元運算編碼、goto 狀態機、遞迴主函式、位移運算構建 ASCII、甚至需 C++ 編譯器的前置遞增藝術。全部在 GCC 下編譯通過(最後一個需 g++)。
#define _________ }
#define ________ putchar
#define _______ main
#define _(a) ________(a);
#define ______ _______(){
#define __ ______ _(0x48)_(0x65)_(0x6C)_(0x6C)
#define ___ _(0x6F)_(0x2C)_(0x20)_(0x77)_(0x6F)
#define ____ _(0x72)_(0x6C)_(0x64)_(0x21)
#define _____ __ ___ ____ _________
#include <stdio.h>
_____
層層巨集遞迴展開,最終生成一個呼叫 putchar 輸出各字元 ASCII 碼的 main 函式。
#include <stdio.h>
main(){
int x=0,y[14],*z=&y;
*(z++)=0x48; *(z++)=y[x++]+0x1D;
*(z++)=y[x++]+0x07; *(z++)=y[x++]+0x00;
*(z++)=y[x++]+0x03; *(z++)=y[x++]-0x43;
*(z++)=y[x++]-0x0C; *(z++)=y[x++]+0x57;
*(z++)=y[x++]-0x08; *(z++)=y[x++]+0x03;
*(z++)=y[x++]-0x06; *(z++)=y[x++]-0x08;
*(z++)=y[x++]-0x43; *(z++)=y[x]-0x21;
x=*(--z); while(y[x]!=NULL) putchar(y[x++]);
}
利用陣列與指標運算,以差分編碼方式重建字串,最後反向遍歷輸出。
goto 狀態機#include <stdio.h>
#define __(a) goto a;
#define ___(a) putchar(a);
#define _(a,b) ___(a) __(b);
main(){
_:__(t)a:_('r',g)b:_('$',p)
c:_('l',f)d:_(' ',s)e:_('a',s)
f:_('o',q)g:_('l',h)h:_('d',n)
i:_('e',w)j:_('e',x)k:_('\n',z)
l:_('H',l)m:_('X',i)n:_('!',k)
o:_('z',q)p:_('q',b)q:_(',',d)
r:_('i',l)s:_('w',v)t:_('H',j)
u:_('a',a)v:_('o',a)w:_(')',k)
x:_('l',c)y:_('\t',g)z:___(0x0)}
巨集將 goto 與 putchar 結合,構建一個隱含字串輸出順序的標籤跳轉網路。
main 輸出int n[]={0x48,0x65,0x6C,0x6C,0x6F,0x2C,0x20,
0x77,0x6F,0x72,0x6C,0x64,0x21,0x0A,0x00},*m=n;
main(n){putchar(*m)!='\0'?main(m++):exit(n++);}
全域陣列存放字串,main 遞迴呼叫自身,透過指標遞增遍歷陣列,遇到結束符退出。利用 main 參數作狀態傳遞。
main(){int i,n[]={(((1<<1)<<(1<<1)<<(1<<1)<<(1<<(1>>1)))+((1<<1)<<(1<<1))),
...(極長表達式省略)...
}; for(i=(1>>1);i<(((1<<1)<<(1<<1))+((1<<1)<<(1<<(1>>1)))+(1<<1));i++) printf("%c",n[i]);}
完全不使用字面常數,僅靠 1、位移、加減運算計算出每個字元的 ASCII 碼,展示位運算的表達能力。
#include <stdio.h>
#define _(_) putchar(_);
int main(void){int i = 0;_(++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++i)_ ...
利用大量 ++ 將 i 遞增至目標 ASCII 碼,再 putchar。需 C++ 編譯器(g++)因 C 標準限制單一運算式修改變數次數。
這六例展示了 C/C++ 預處理器、指標運算、控制流、遞迴、位運算、運算式求值順序等特性的極限應用。雖無工程價值,卻是理解語言機制的絕佳腦力體操。