我越想明白这个困惑的谜团就越想放弃。程序哪个源代码与其输出完全相同
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