我發現了一個C程序,即使源文件被刪除,它也會自行打印。但我無法瞭解它是如何工作的。以下是此代碼即使源文件被刪除也能自行打印的程序
char *p="char *p=%c%s%c;main() {printf(p,34,p,34);}";
main() {printf(p,34,p,34);}
任何人都可以通過解釋每個步驟來幫助我嗎?
我發現了一個C程序,即使源文件被刪除,它也會自行打印。但我無法瞭解它是如何工作的。以下是此代碼即使源文件被刪除也能自行打印的程序
char *p="char *p=%c%s%c;main() {printf(p,34,p,34);}";
main() {printf(p,34,p,34);}
任何人都可以通過解釋每個步驟來幫助我嗎?
這個版本是C 'quine'或自再現程序的不嚴格有效的C89,更不用說任何更新。但是,它可以在大多數系統上運行。
瞭解它的關鍵是要知道字符34是雙引號,"
。
char *p="char *p=%c%s%c;main() {printf(p,34,p,34);}";
main() {printf(p,34,p,34);}
的printf()
打印使用字符串p
作爲格式字符串,參數34
(或雙引號),p
再次,和34(再次)。
printf("char *p=%c%s%c;main() {printf(p,34,p,34);}", 34, p, 34);
這將產生:
char *p="char *p=%c%s%c;main() {printf(p,34,p,34);}";main() {printf(p,34,p,34);}
和當那是編譯和運行,它再現本身。
這個版本是符合標準C:
#include <stdio.h>
const char*s="#include <stdio.h>%cconst char*s=%c%s%c;%cint main(void){printf(s,10,34,s,34,10,10);}%c";
int main(void){printf(s,10,34,s,34,10,10);}
它使用來換行'\n'
是事實^ J是字符代碼10以及圖34是雙引號"
。
有沒有辦法避免依賴ascii? ''\ n''和''「''會使那個便攜:) – 2013-03-10 18:03:51
真棒...這就是我想要的... – 2013-03-10 18:04:06
@JensGustedt:有趣的問題 - 我不知道... Lua和紅寶石在維基百科頁面上的quines管理避免使用ASCII碼,其他的例子不會,如果你要避免使用ASCII,你可能必須使用printf()以外的東西,或者你必須包含像'char q ='「';'在字符串和程序代碼中。 – 2013-03-10 18:09:02
如果上面的程序中的printf()被下面的代碼替換,你會理解它嗎?
printf("char *p=%c%s%c;main() {printf(p,34,p,34);}",
34, "a string", 34);
是的我明白了,但是這裏34是做什麼的? – 2013-03-10 18:00:24
'34'與格式字符串中的'%c'「鏈接」。只需在環境使用的編碼中打印值爲「34」的字符(ASCII爲引用)。 – pmg 2013-03-10 18:03:32
這哪一部分不清楚?你知道'printf'是如何工作的嗎? – 2013-03-10 17:44:07
不,我不明白這個printf()是如何工作的... – 2013-03-10 17:45:11
在這種情況下,我建議你先學習基本知識(在這種情況下,特別是'printf'的參數)。一旦你理解了,那麼應該清楚上面的代碼是如何工作的! – 2013-03-10 17:46:02