首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

六種讓人大開眼界的 C 語言 Hello World 寫法

     編輯:關於C語言

前言:當 Hello World 變成藝術品

「Hello, World!」是幾乎所有程式設計師寫的第一行程式碼。但如果不使用任何可讀的字元、不呼叫 printf 或 puts,甚至完全隱藏主函式,還能印出這行字串嗎?本文收集六種極具創意、甚至略帶「變態」風格的 C 語言 Hello World 實作,展示前置處理器、指標運算、goto、位元操作等特性的極限應用。這些寫法雖不適合實務專案,卻能深化對 C 語言編譯機制的理解。

作品一:巨集地獄——全程只用 #define

#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 碼(0x48='H', 0x65='e'...)的 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++]);
}

解析: 利用陣列 y 當作緩衝區,z 為指標依序寫入。第一個字元直接寫 'H'(0x48),後續字元皆以前一個字元為基準加減偏移量計算而得(例如 'e' = 'H' + 0x1D)。最後倒著遍歷陣列輸出。展示指標遞增、陣列索引運算與 ASCII 碼數學關係的巧妙結合。

作品三: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:_(' ',z)
l:_('H',l) m:_('X',i) n:_('!',k) o:_('H',o) p:_('e',m) q:_('l',n)
r:_('l',c) s:_('o',d) t:_(' ',b) u:_('w',a) v:_('o',u) w:_('r',v)
x:_('l',w) y:_('d',x) z:_('!',y)
}

解析: 完全放棄迴圈與函式呼叫,改用大量 goto 標籤跳轉。每個標籤印出一個字元並跳往下一個標籤,形成一條長長的執行鏈。字元順序被打亂分散在各標籤中,靠跳轉順序重組出 "Hello world!"。極致展示 goto 的流程控制能力(以及為什麼現代軟體工程極力避免它)。

作品四:遞迴主函式——main 呼叫 main

#include <stdio.h>
main(int argc, char *argv[]) {
    static char *s = "Hello, World!\n";
    if (*s) putchar(*s++), main(0, 0);
}

解析: 利用靜態字串指標 s 保持狀態,每次遞迴印出一個字元並遞增指標。當遇到字串結束符 \0 時遞迴終止。展示 C 語言允許 main 遞迴呼叫(雖然 C++ 標準禁止),以及靜態區域變數跨呼叫保持值的特性。

作品五:位元運算與三元運算子的壓縮藝術

#include <stdio.h>
main(){int i=0;while(puts("Hello, World!")&~i++);}

解析: puts 回傳非負值(成功),~i++ 最初為 ~0(全 1),按位元 AND 結果為真,迴圈繼續;i 變 1 後 ~1 最低位為 0,配合 puts 回傳值導致條件為假,迴圈恰好執行一次。展示位元運算子與短路求值的巧妙組合。

作品六:字串字面常量的地址運算

#include <stdio.h>
main(){printf("%s","Hello, World!\n"+0);}

解析: 看似平凡,實則利用字串字面常量在記憶體中連續分布的特性,+0 無實質運算但強調指標算術。若改為 +1 則輸出 "ello, World!\n",展示字串指標偏移的基本觀念。

總結:從玩梗看見語言本質

這六種寫法橫跨前置處理器元程式設計、指標算術、非結構化流程控制、遞迴、位元運算、指標偏移等核心議題。它們提醒我們:

  • C 語言給予程式設計師極大的自由度,也意味著極大的責任
  • 理解編譯器如何展開巨集、處理指標、解析流程控制,有助於除錯與效能調優
  • 實務開發中應優先考慮可讀性、可維護性,將這些技巧留給教學示範或 IOCCC(國際混亂 C 程式碼大賽)

若您有更瘋狂的 Hello World 寫法,歡迎分享交流!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved