2011-12-21 15 views
9
main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);} 

コンパイル後の再生方法は? printf関数に34を書いているのは何ですか?自己再生プログラム

+3

(接尾辞:「偽りの時に偽りが生じたときは偽りを生じる」) –

+0

オフトピック:今日は面白いことがあります。ありがとう! – ArjunShankar

+0

申し訳ありませんが、私は34が明らかだと思いますか? – prongs

答えて

16

34( ")二重引用符のASCII文字コードで文字。


私の接線のコメントをフォローアップするために、(それがホフスタッターのを参照した『ゲーデルエッシャー、バッハ』)、これは動作しますそれは基本的に2つの要素を含むレシピです:データのカーネルとそのカーネルでの操作です。操作が完了すると、オリジナルのレシピが再現されます。これを行うために、カーネルと操作はほぼ同じですあなたが言及したプログラムでは、カーネルは文字列です

"main(a){printf(a=%c%s%c,34,a,34);}" 

と操作はプログラムの残りの部分である:

____はカーネルです
main(a){printf(a=_____,34,a,34);} 

。カーネルを書式指定子(カーネルを出力しますが、引用符で囲まず、したがってカーネルを出力の操作に変換する)としてカーネルを使用することで、カーネル自身を出力することができます。書式指定子(%s)のパラメータとそれを引用し、出力にカーネルを生成します。

操作(quoted kernel)=>引用符で囲まれていないカーネル(quoted =>は元のプログラム)を含みます。


もう1つの理由:この34のビジネスを使用する理由は、引用符を使用しないでカーネルを使用することで簡単に引用操作が保たれることです。あなたは

main(a){printf(a="%s",a);} 

の引用符で囲まれていないカーネルで、カーネルとして

"main(a){printf(a=\"%s\",a);}" 

を使用しようとした場合、カーネルを引用するためには、あなたはバックスラッシュエスケープをする必要があると思いますので、それははるかに困難であろう文字列の中央の引用符。

+0

ああ!高すぎですが、どうやって動いていますか? –

+2

@Arya:このページには、「クインズ」をどのように構築することができるかについてのまともな説明があります:http://www.madore.org/~david/computers/quine.htmlこれは、上記の仕組みの考え方を与えるかもしれません。 –

+0

このhtmlページのためのおかず... :) –

関連する問題