2013-03-10 16 views
1

我發現了一個C程序,即使源文件被刪除,它也會自行打印。但我無法瞭解它是如何工作的。以下是此代碼即使源文件被刪除也能自行打印的程序

char *p="char *p=%c%s%c;main() {printf(p,34,p,34);}"; 
main() {printf(p,34,p,34);} 

任何人都可以通過解釋每個步驟來幫助我嗎?

+0

這哪一部分不清楚?你知道'printf'是如何工作的嗎? – 2013-03-10 17:44:07

+0

不,我不明白這個printf()是如何工作的... – 2013-03-10 17:45:11

+1

在這種情況下,我建議你先學習基本知識(在這種情況下,特別是'printf'的參數)。一旦你理解了,那麼應該清楚上面的代碼是如何工作的! – 2013-03-10 17:46:02

回答

5

這個版本是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是雙引號"

+0

有沒有辦法避免依賴ascii? ''\ n''和''「''會使那個便攜:) – 2013-03-10 18:03:51

+0

真棒...這就是我想要的... – 2013-03-10 18:04:06

+0

@JensGustedt:有趣的問題 - 我不知道... Lua和紅寶石在維基百科頁面上的quines管理避免使用ASCII碼,其他的例子不會,如果你要避免使用ASCII,你可能必須使用printf()以外的東西,或者你必須包含像'char q ='「';'在字符串和程序代碼中。 – 2013-03-10 18:09:02

1

如果上面的程序中的printf()被下面的代碼替換,你會理解它嗎?

printf("char *p=%c%s%c;main() {printf(p,34,p,34);}", 
     34, "a string", 34); 
+0

是的我明白了,但是這裏34是做什麼的? – 2013-03-10 18:00:24

+0

'34'與格式字符串中的'%c'「鏈接」。只需在環境使用的編碼中打印值爲「34」的字符(ASCII爲引用)。 – pmg 2013-03-10 18:03:32

相關問題