为什么此Java代码的行为不同于此C代码?

时间:2018-12-15 08:01:24

标签: java c brainfuck

长话短说,我是怎么到达这里的?涉及到C编译器的Brainfuck和JVM Bytecode编译器的Brainfuck ...似乎无关紧要。 有问题的Brainfuck代码如下:

>-[[<+>>>-<-<+]>]

我有以下C代码:

#include <stdlib.h>
#include <stdio.h>

typedef unsigned char u8;

void m1();
void m2();

u8 *dp;

int main() {
    dp = (u8*) calloc(30000, sizeof(u8));

    dp += 1;
    *dp -= 1;
    while(*dp) {
        m1();
    }

    return 0;
}

void m1() {
    while(*dp) {
        m2();
    }
    dp += 1;
}

void m2() {
    dp -= 1;
    *dp += 1;

    dp += 3;
    *dp -= 1;

    dp -= 1;
    *dp -= 1;

    dp -= 1;
    *dp += 1;
}

此代码终止。

我有以下Java代码:

public class test {
    public static void main(String[] args) {
        new test().run();
    }

    int[] tape = new int[30000];
    int dp = 0;

    void adjust(int n) {
        tape[dp] += n;
        if(tape[dp] < 0) tape[dp] += 255;
        if(tape[dp] > 255) tape[dp] -= 255;
    }

    void run() {
        dp += 1;
        adjust(-1);
        while(tape[dp] != 0) {
            m1();
        }
    }

    void m1() {
        while(tape[dp] != 0) {
            m2();
        }
        dp += 1;
    }

    void m2() {
        dp -= 1;
        adjust(1);

        dp += 3;
        adjust(-1);

        dp -= 1;
        adjust(-1);

        dp -= 1;
        adjust(1);
    }
}

它不会终止。

为什么这些看似等效的程序的行为有所不同?我一定错过了明显的东西吗?

1 个答案:

答案 0 :(得分:0)

这些代码不相等:

  1. C版本将字节数组分配为Java的-整数数组
  2. C版本不像Java那样夹紧数组元素

因此在Java中,您应该改用字节数组:

byte[] tape = new byte[30000];

并在adjust()函数中删除夹紧:

 // if(tape[dp] < 0) tape[dp] += 255;
 // if(tape[dp] > 255) tape[dp] -= 255;

然后Java的版本也会终止

OR 如果要保留整数数组-那么必须更改上溢/下溢规则:

 if(tape[dp] < 0) tape[dp] = 256-Math.abs(tape[dp]) % 256;
 if(tape[dp] > 255) tape[dp] = tape[dp] % 256;

因为您实施的方法不正确