如何编写一个可以输出自己源代码的程序,要满足以下要求:
1.该程序不可以从外部读取输入。
2.该程序的输出不可以为空。
想了很久始终无法想明白要如何做到。。。
如何编写一个可以输出自己源代码的程序,要满足以下要求:
1.该程序不可以从外部读取输入。
2.该程序的输出不可以为空。
想了很久始终无法想明白要如何做到。。。
除非源码文件还在,不然二进制文件无法将本身再解释成源代码,解释其他二进制也不行。目前,很多编译器在解析源代码时候都会进行优化,对应到二进制的一条条指令。这些指令没办法再翻译成高级语言了。就像2+2=4,但4不一定2+2.
C语言的话,用宏定义应该可以构造特殊的程序,使其输出恰好等于其源码,但是如果你想要输出全部源代码(包括include和注释)就做不到了。要想从编译好的可执行文件中获得代码就属于逆向工程了,而且有些编译过程本身就是不可逆的。
最简单的C:
EXEC_OUTPUT(a = 1);
不过只支持简单表达式,不支持本身有字符串的表达式,不支持宏,不支持全局变量。。。
((lambda (x)
(list x (list (quote quote) x)))
(quote
(lambda (x)
(list x (list (quote quote) x)))))
首先,为了限制篇幅,我在外部定义一个quote
函数,作用是将一个字符串中的特殊字符转义起来。这个函数就不纳入源文件了,否则代码太长:
// quote.h
char* quote(const char* s)
{
static char buf[512];
for(unsigned len = 0; *s; s++) {
if(*s == '\n') { buf[len++] = '\\'; buf[len++] = 'n'; }
else if(*s == '\"') { buf[len++] = '\\'; buf[len++] = '"'; }
else buf[len++] = *s;
}
return buf;
}
这个源文件是这样的:
#include <stdio.h>
#include <quote.h>
int main()
{
const char *s = "#include <stdio.h>\n#include <quote.h>\n\nint main()\n{\n const char *s = \"%s\";\n printf(s, quote(s));\n}";
printf(s, quote(s));
}
s
就是一个把整个源文件压扁成字符串,然后在字符串里代表自身的地方用%s
代替。总的来说只是算printf
的一种有趣的应用罢了。
这个有个缺陷,就是在你改动源码的时候,你要相应地改动s
。你可以将quote
函数也纳入源码,但是要相应地在加入单引号和斜杠的转移。
8 回答6.4k 阅读
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答4.1k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
这个叫做Quine
https://en.wikipedia.org/wiki/Quine_(computing)
https://zh.wikipedia.org/wiki/%E8%87%AA%E7%94%A2%E7%94%9F%E7%A8%8B%E5%BC%8F
Java 版本比较罗嗦,可以去wiki看看其他语言的版本