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

Why does this Java code behave differently than this C code?

长话短说我是怎么来到这里的;涉及一个 Brainfuck 到 C 编译器和一个 Brainfuck 到 JVM 字节码编译器......似乎无关紧要。 有问题的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. 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的版本也终止了

如果你想保留整数数组——那么你必须改变你的overflow/underflow规则:

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

因为你实施的不对