Quine(以邏輯學家 Willard Van Orman Quine 命名)是一種「不接受任何輸入、輸出自身完整原始碼」的程式。這是一種經典的程式設計智力遊戲,也是對語言特性(字串處理、轉義、格式化輸出)掌握程度的絕佳測試。
#include <stdio.h>
main(){char *s="#include<stdio.h>%cmain(){char *s=%c%s%c;printf(s,10,34,s,34);}";printf(s,10,34,s,34);}
核心技巧:
%c 對應 ASCII 碼:10 = 換行符 \n,34 = 雙引號 "。s 同時作為「資料」與「格式化模板」,printf 將自身內容填入模板並輸出。#include <stdio.h>
main() {
char *s = "#include<stdio.h>%cmain(){%c%cchar *s=%c%s%c;%c%cprintf(s,10,10,9,34,s,34,10,9,10);%c}";
printf(s, 10, 10, 9, 34, s, 34, 10, 9, 10);
}
10 = \n,9 = \t,34 = "。%c 位置,依序填入換行、縮排、引號、字串本體。//Copyright (c) LeafCore
#include <stdio.h>
void main() {
char *s = "//Copyright (c) LeafCore%c#include<stdio.h>%cvoid main() {%c%cchar *s=%c%s%c;%c%cprintf(s,10,10,10,9,34,s,34,10,9,10);%c}";
printf(s, 10, 10, 10, 9, 34, s, 34, 10, 9, 10);
}
//Copyright (c) LeafCore
#include <stdio.h>
main() {
FILE *fp = fopen("file.c", "w");
char *s = "//Copyright (c) LeafCore%c#include<stdio.h>%cmain(){%c%cFILE *fp=fopen(%cfile.c%c,%cw%c);%c%cchar *s=%c%s%c;%c%cfprintf(fp,s,10,10,10,9,34,34,34,34,10,9,34,s,34,10,9,10,9,10,9,10);%c%cfclose(fp);%c%creturn 0;%c}";
fprintf(fp, s, 10, 10, 10, 9, 34, 34, 34, 34, 10, 9, 34, s, 34, 10, 9, 10, 9, 10, 9, 10);
fclose(fp);
return 0;
}
編譯執行後,會在當前目錄生成 file.c,內容即為程式自身完整原始碼。這展示了「自我複製」程式的基本原理,也是病毒、編譯器引導、元程式設計的理論基石之一。
printf("%c", 34) 輸出雙引號,printf("%c", 10) 輸出換行,避免原始碼中直接寫死特殊字元導致巢狀引號混亂。%c/%s 的位置,任何參數錯位都會導致輸出錯誤。Quine 的構造思想可推廣至:
嘗試手寫一個 Quine,是深入理解程式語言「資料即程式、程式即資料」本質的最佳練習。