首页  >  文章  >  后端开发  >  防火测试:递归阶乘

防火测试:递归阶乘

PHPz
PHPz原创
2024-08-14 10:45:051149浏览

Teste de fogo: fatorial recursivo

对于那些不遵循 POJ(JVM 上的 Pascal)的人来说,它是一个将 子集 从 Pascal 转换为 JASM 的编译器( Java Assembly),以便我们可以使用 JVM 作为执行环境。

在上一篇文章中,实现了对 Pascalread/readln 的支持,这些函数允许从标准输入 (stdin) 读取数据。在本出版物中,我们将完成 POJ 的目标之一:从标准输入读取数字并递归计算阶乘。

当我们为 JVM 进行编译时,有必要详细说明这个令人难以置信的虚拟机的各个点的功能。因此,我多次详细介绍 JVM 的内部功能及其一些指令(操作码)。

递归阶乘,锦上添花:-)

正如项目开始时提到的,目标之一是能够递归计算阶乘,从标准输入中读取要计算的数字。迄今为止 POJ 中的实现已经使这一目标成为可能:

  • Hello world:使用 ANTLR、解析器和代码生成创建了项目的代码库Java Assembly;
  • 加法、减法、乘法、除法运算符和条件句开头 - if:开始支持运算符以及初步支持条件句;
  • Repeat、while 和 for:支持重复结构;
  • Pascal 中的函数:递归函数的实现。

现在是时候验证迄今为止所开发的内容了。也就是说,来自下面的 Pascal 程序:

program fatorial;

var numero : integer;

function fatorial(n : integer) : integer;
begin
    if n<0 then fatorial := 0
    else begin
        if n<=1 then fatorial := 1
        else fatorial := n * fatorial(n-1);
    end;
end;

begin
    write('Introduza numero inteiro: ');
    readln(numero);
    writeln;
    writeln('O fatorial de ', numero, ' e: ', fatorial(numero));
end.

POJ 正确生成以下 程序集:

// Code generated by POJ 0.1
public class fatorial {
    public static numero I

    static fatorial(I)I {
        iload 0
        sipush 0
        if_icmpge L4
        iconst 1 
        goto L5
    L4: iconst 0 
    L5: ifeq L1
        sipush 0
        istore 100
        goto L2
    L1: iload 0
        sipush 1
        if_icmpgt L9
        iconst 1 
        goto L10
    L9: iconst 0 
    L10:ifeq L6
        sipush 1
        istore 100
        goto L7
    L6: iload 0
        iload 0
        sipush 1
        isub 
        invokestatic fatorial.fatorial(I)I 
        imul 
        istore 100
L7: L2: iload 100
        ireturn 
    }

    public static main([java/lang/String)V {
        getstatic java/lang/System.out java/io/PrintStream
        ldc "Introduza numero inteiro: "
        invokevirtual java/io/PrintStream.print(java/lang/String)V

        invokestatic java/lang/System.console()java/io/Console
        invokevirtual java/io/Console.readLine()java/lang/String
        invokestatic java/lang/Integer.parseInt(java/lang/String)I
        putstatic fatorial.numero I

        getstatic java/lang/System.out java/io/PrintStream
        invokevirtual java/io/PrintStream.println()V

        getstatic java/lang/System.out java/io/PrintStream
        ldc "O fatorial de "
        invokevirtual java/io/PrintStream.print(java/lang/String)V

        getstatic java/lang/System.out java/io/PrintStream
        getstatic fatorial.numero I
        invokevirtual java/io/PrintStream.print(I)V

        getstatic java/lang/System.out java/io/PrintStream
        ldc " e: "
        invokevirtual java/io/PrintStream.print(java/lang/String)V

        getstatic java/lang/System.out java/io/PrintStream
        getstatic fatorial.numero I
        invokestatic fatorial.fatorial(I)I 
        invokevirtual java/io/PrintStream.print(I)V

        getstatic java/lang/System.out java/io/PrintStream
        invokevirtual java/io/PrintStream.println()V

        return
    }
}

最后,结束

我们通过这个项目结束了这次学习之旅。

可以通过这个项目探索编译器领域的一些有趣的事情(例如生成代码的优化)。谁知道呢,也许在不久的将来我们会开始一个新的优化系列:-)

完整的项目代码

包含项目完整代码和文档的存储库位于此处。

以上是防火测试:递归阶乘的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn