我听说有一些事情是计算机程序员无法做到的,但我不知道它们是什么。我最近发生的一件事是:如果有一个类可以复制它运行的程序源,修改该程序并向该类添加一个方法,然后运行,这不是一件好事吗程序的副本并终止自身。代码是否可以编写代码?
答案 0 :(得分:14)
如果您想了解可计算性的限制,请阅读halting problem
在可计算性理论中,停止 问题是一个决定问题 可以说如下:给出一个 程序的描述和有限的 输入,决定是否该程序 完成运行或将永远运行, 鉴于此输入。
阿兰图灵在1936年证明了这一点 一般算法解决所有人的停顿问题 可能的程序输入对不存在
答案 1 :(得分:13)
首先查看quines,然后查看Macro-Assemblers,然后查看lex & yacc和flex & bison。然后考虑self-modifying code。
这是一个quine(格式化,使用输出作为新输入):
#include<stdio.h>
main()
{
char *a = "main(){char *a = %c%s%c; int b = '%c'; printf(a,b,a,b,b);}";
int b = '"';
printf(a,b,a,b,b);
}
现在,如果你只是在寻找程序员不能做的东西,那就找np-complete的反面。
答案 2 :(得分:8)
当然可以。这就是很多病毒的工作方式!
答案 3 :(得分:4)
是的,这就是大多数Lisp宏所做的事情(仅举一例)。
答案 4 :(得分:4)
了解这一点:computability theory。
答案 5 :(得分:3)
是的,肯定是这样,虽然可能不是在你所指的上下文中,在t4上查看这个post。
答案 6 :(得分:3)
如果你看一下有很多机会编写代码来生成更多代码的函数式编程,那么像Lisp这样的语言不区分代码和数据的方式是它的强大功能。
Rails在创建新应用程序时从数据库模式生成各种默认模型和控制器类。用动态语言做这种事情是非常标准的 - 我有几个PHP生成php文件,只是因为它是我当时处理的问题的最简单的解决方案。
所以有可能。至于你问的问题,那可能有点模糊 - 你使用的环境和语言是什么?你期望代码做什么以及为什么需要添加它?一个具体的例子可能会带来更直接相关的反应。
答案 7 :(得分:2)
是的,可以创建代码生成器。 大多数情况下,他们接受用户输入并生成有效代码。但还有其他可能性。
自我修改程序也是可能的。但它们在dos时代更为常见。
答案 8 :(得分:2)
看看Langtom's loop。这是自我复制“程序”的最简单的例子。
答案 9 :(得分:2)
动态语言通常不能像你建议的那样工作,因为它们没有完全独立的编译步骤。程序没有必要修改自己的源代码,重新编译,并从头开始。通常,新功能会即时编译和链接。
Common Lisp是一种非常好的语言,但是在其他地方你可以创建代码并在那里运行它。通常,这将通过称为“eval”的功能或类似的功能。 Perl具有“eval”功能,脚本语言通常具有这种功能。
有许多程序可以编写其他程序,例如yacc或bison,但它们没有您想要的动态质量。
答案 10 :(得分:2)
复制它运行的程序的源代码,修改该程序并向该类添加一个方法,然后运行该程序的副本并自行终止
您还可以生成代码,将其构建到库而不是可执行文件中,然后动态加载库,甚至不退出当前正在运行的程序。
答案 11 :(得分:2)
关于人工智能,请查看Evolutionary algorithms。
答案 12 :(得分:2)
当然可以。我为Paint.NET *编写了一个效果,它为您提供了一个编辑器,允许您“动态”编写图形效果。当您暂停键入时,它会将其编译为dll,加载并执行它。现在,在编辑器中,您只需要编写实际的渲染函数,创建dll所需的一切都由编辑器编写并发送到C#编译器。
您可以在此免费下载:http://www.boltbait.com/pdn/codelab/
实际上,甚至可以选择在将其发送到编译器之前查看为您编写的所有代码。帮助文件(上面链接)讲述了所有相关内容。
源代码也可以从该页面下载。
* Paint.NET是一个免费的图像编辑器,您可以在此处下载:http://getpaint.net
答案 13 :(得分:2)
你混淆/混淆了“写”这两个词的两个含义。一个含义是将字节物理写入介质,另一个是设计软件。当然,如果设计的话,你可以让程序做前者。
程序员做一些程序员没有明确打算做的事情的唯一方法就是表现得像一个生物:mutate(自身包含一些环境),并以不同的速率复制不同的突变体(到如果突变终止,则避免完全灭绝。
答案 14 :(得分:2)
当然可以!实际上,如果使用动态语言,则在程序仍在运行时,类可以更改自身(或其他类)。它甚至可以创建以前不存在的新类。这称为元编程,它可以让您的代码变得非常灵活。
答案 15 :(得分:1)
始终可以编写代码生成器。使用XML技术,代码生成器的使用可以成为必不可少的工具。假设您为一家必须处理来自其他公司的XML文件的公司工作。编写一个程序使用XML解析器解析新的XML文件并编写另一个程序,其中设置了所有回调函数以读取该格式的XML文件,这是相对简单的。您仍然需要编辑新程序以使其特定于您的需求,但是使用这种类型的代码生成器大大减少了新XML文件(新结构,新名称)的开发时间。在我看来,这是XML技术优势的一部分。
答案 16 :(得分:1)
我在PHP中这样做。
为了保持类的设置,我保留了一个名为$data
的局部变量。 $ data只是一个字典/哈希表/关联数组(取决于你来自哪里)。
加载类时,它包含一个基本定义数据的php文件。当我保存类时,它会为每个数据值写出PHP。这是一个缓慢的写入过程(目前存在一些并发问题),但它比光更快读取。比使用数据库快得多(也更轻)。
这样的东西不适用于所有语言。它适用于PHP,因为PHP非常实时。
答案 17 :(得分:1)
Lisp lisp lisp lisp:p
开玩笑,如果你想要生成代码的代码运行,你有时间放松学习它并用递归的东西来产生更多的代码来打破你的想法,试着学习lisp:)
(eval '(or true false))
答案 18 :(得分:1)
有一类称为“代码生成器”的东西。 (虽然编译器也适合你设置的描述)。那些描述了这些野兽的两个区域。
大多数代码生成,采取某种形式的用户输入(大多数采用数据库模式)和产品源代码,然后进行编译。
更高级的可输出可执行代码。使用.NET,有一个专用于创建可执行代码的完整命名空间(System.CodeDom)。这些对象,您可以使用C#(或其他语言)代码,编译它,并将其链接到您当前运行的程序。
答案 19 :(得分:1)
如果有一个类可以复制它运行的程序的源代码,修改该程序并向该类添加一个方法,然后运行该程序的副本并不是一件好事。终止自己
几乎没有任何情况可以解决使用非自修改代码无法“更好”解决的问题。
也就是说,有一些非常常见(有用)的代码编写其他代码的情况。最明显的是任何服务器端的Web应用程序,它生成HTML / Javascript(嗯,HTML是标记,但它是相同的理论)。此外,任何改变终端环境的脚本通常都会输出一个由父shell评估的shell脚本。 wxGlade生成的代码可以创建基于wx的裸机GUI。
答案 20 :(得分:1)
请参阅我们的DMS Software Reengineering Toolkit。这是通用机器,用于读取和修改程序,或通过组合片段生成程序。
答案 21 :(得分:0)
这是人工智能的基本问题之一。我个人希望这是不可能的 - 否则我很快就会失业!!! :)
答案 22 :(得分:0)
它被称为meta-programming,既是编写有用程序的好方法,也是一个有趣的研究课题。 Jacques Pitrat的Artificial Beings: the conscience of a conscious machine书应该让你感兴趣。它主要与基于元知识的计算机程序有关。
另一个相关术语是multi-staged programming(因为有几个阶段的程序,每个阶段产生下一个程序)。