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

コンパイル後、どのように再現されていますか?printf関数で34を書くことの役割は何ですか?

4

1 に答える 1

21

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


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

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

そして、操作はプログラムの残りの部分です:

 main(a){printf(a=_____,34,a,34);}

____カーネルはどこにありますか。それらは本質的に同じように見えることに気付くでしょう:操作は、カーネルをフォーマット指定子として使用することによってそれ自体を印刷でき(カーネルを印刷しますが、引用符で囲まれていないため、カーネルを出力の操作に変換します)、カーネル自体を次のようにフィードしますフォーマット指定子(%s)のパラメーターとそれを引用して、出力にカーネルを生成します。

operation(quoted kernel)=>カーネルのコピーを含む引用されていないカーネル、quoted=>元のプログラムです。


もう1つのポイント:この34のビジネスを使用する理由は、引用文字のないカーネルを使用することにより、引用操作を簡単に保つためです。使用しようとした場合

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

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

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

カーネルを引用するためには、文字列の途中で引用符をバックスラッシュでエスケープする必要があるため、はるかに困難になります。

于 2011-12-21T20:59:14.027 に答える