我越想明白這個困惑的謎團就越想放棄。程序哪個源代碼與其輸出完全相同
char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}
如何發生的這一行的源代碼,當程序運行並且是有這種程序的任何共同的概念,產生完全相同的輸出?
我越想明白這個困惑的謎團就越想放棄。程序哪個源代碼與其輸出完全相同
char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}
如何發生的這一行的源代碼,當程序運行並且是有這種程序的任何共同的概念,產生完全相同的輸出?
這被稱爲Quine。
那麼讓我們來看看main()
做:
printf(s,34,s,34);
34是字符"
(雙引號)的ASCII碼,所以這是一樣的:
printf(s, '"', s, '"');
的第一個參數printf(3)
是格式字符串。傳遞的字符串是:
"char *s = %c%s%c; main(){printf(s,34,s,34);}"
所以,printf(3)
將輸出正是這樣,但要注意%c
,%s
和%c
格式說明,它指示printf(3)
打印字符,然後是字符串,然後在另一個字符地點,分別是第二,第三和第四個參數。
正如我們所看到的,字符都是"
,字符串是s
(相同的字符串)。因此,該程序的輸出是:
char *s = "X"; main(){printf(s,34,s,34);}
凡X
是在程序中的字符串s
。所以我們得到這個作爲輸出:
char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}
其中,有趣的是,程序源本身。
採取從printf的第一參數即字符串:
'char *s = %c%s%c; main(){printf(s,34,s,34);}'
和做替代其中
%c = 34 = '"' //(same for both %c)
%s = 'char *s = %c%s%c; main(){printf(s,34,s,34);}'
的printf將做替代只有一次(未遞歸),所以結果是:
'char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}'
理解代碼,第一簡化並重新格式化:
char *s = "some format string";
main() {
printf(s,34,s,34);
}
所以它使用s
作爲格式化字符串打印三個實體:34
,字符串s
本身34
。在這種情況下,格式化字符串s
的重要組成部分是:
char *s = "... %c%s%c ..."
這意味着兩個34
小號成爲雙引號("
)和格式串s
只是打印爲正常的字符串。現在你應該看到其餘的的格式化字符串s
只是整個程序的一個副本。
你知道'printf'的作用嗎?你可以計算出什麼'printf(「char * s =%c%s%c; main(){printf(s,34,s,34);}」,34,「char * s =%c%s% c; main(){printf(s,34,s,34);}「,34)'打印,因爲34是ASCII代碼的一個'''? – immibis
現在它是官方的 - 我非常缺乏分析技能 – Malina
我知道什麼是34和printf是什麼..它只是在語義上讓我困惑 – Malina