打印二维数组时出现致命错误

时间:2014-11-25 16:49:55

标签: c arrays gameboy

我遇到了一小块代码的问题:

for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
printf(" %d", occupy[x][y]);
}
printf(" \n");
}

我正在为Gameboy制作一个随机生成的迷宫游戏,我正在使用2D阵列来了解每个屏幕在迷宫中的位置。为了测试,我正在尝试打印该阵列,以便在继续之前我可以看到它是否正常生成。当我尝试使用那一小块代码进行编译时,我在它的顶行会出现错误,然后在文件中写出致命的编译器内部错误等等等等。那个代码中有一个我不知道的大禁忌吗?

完整代码:

#include <gb\gb.h>
#include <stdio.h>
#include <rand.h>


#define UP 0x01U
#define RIGHT 0x02U
#define DOWN 0x04U
#define LEFT 0x08U

int occupy[8][8]= {
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}
};


void generate(){
int temp;
int x;
int y;
UBYTE restrict;
UBYTE direction;
for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
occupy[x][y] = 0;
}
}
/* ========Occupy=Cleared========== */
restrict = 0x00U;
x = rand() & 7;
y = rand() & 7;

if(x == 6 || x == 7){ restrict += RIGHT;}
if(x == 0 || x == 1){ restrict += LEFT;}
if(y == 0 || y == 1){ restrict += UP;}
if(y == 6 || y == 7){ restrict += DOWN;}

/* in the rest of generation wrap this block in if(restrict != 0x0FU){ */

do{
temp = rand() & 3;
if(temp == 0){ direction = UP;}
if(temp == 1){ direction = RIGHT;}
if(temp == 2){ direction = DOWN;}
if(temp == 3){ direction = LEFT;}
}while(restrict & direction);


occupy[x][y] = 5;
if(direction == UP){ occupy[x][y-1] = 1;}
if(direction == RIGHT){ occupy[x+1][y] = 2;}
if(direction == DOWN){ occupy[x][y+1] = 3;}
if(direction == LEFT){ occupy[x-1][y] = 4;}

for(x = 0; x < 8; x++){
for(y = 0; y < 8; y++){
printf(" %d", occupy[x][y]);
}
printf(" \n");
}

}


void main(){
generate();

}

2 个答案:

答案 0 :(得分:2)

这是根据我的GBDK版本编写的,虽然我不确定为什么我所做的更改会修复它。

所做的更改:

  • occupy现在是一个unsigned int的数组,而不只是int(没有此更改sdcc崩溃)
  • 循环内的
  • printf调用已从" %d"更改为" %u"(因为值未签名)
  • 添加了显示printf地址的occupy。如果我删除它或更改它以执行其他操作,sdcc会崩溃。这很愚蠢,但似乎是必需的。我正在寻找不需要毫无意义的替代方案printf

    • 请注意,可以使用以下内容,这样就不会打印任何内容(因为它会尝试写入地址$0000,但这样只读并失败)。它仍然很愚蠢,但没有显示任何东西。它可能仍会导致一些减速。

       
      sprintf(0, "", &occupy);
      
  • 我还改进了缩进。

#include <gb\gb.h>
#include <stdio.h>
#include <rand.h>


#define UP 0x01U
#define RIGHT 0x02U
#define DOWN 0x04U
#define LEFT 0x08U

unsigned int occupy[8][8] = {
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0}
};

void generate(){
    int temp;
    int x;
    int y;
    UBYTE restrict;
    UBYTE direction;

    for(x = 0; x < 8; x++){
        for(y = 0; y < 8; y++){
            occupy[x][y] = 0;
        }
    }
    /* ========Occupy=Cleared========== */
    restrict = 0x00U;
    x = rand() & 7;
    y = rand() & 7;

    if(x == 6 || x == 7){ restrict += RIGHT;}
    if(x == 0 || x == 1){ restrict += LEFT;}
    if(y == 0 || y == 1){ restrict += UP;}
    if(y == 6 || y == 7){ restrict += DOWN;}

    /* in the rest of generation wrap this block in if(restrict != 0x0FU){ */

    do{
        temp = rand() & 3;
        if(temp == 0){ direction = UP;}
        if(temp == 1){ direction = RIGHT;}
        if(temp == 2){ direction = DOWN;}
        if(temp == 3){ direction = LEFT;}
    }while(restrict & direction);


    occupy[x][y] = 5;
    if(direction == UP){ occupy[x][y-1] = 1;}
    if(direction == RIGHT){ occupy[x+1][y] = 2;}
    if(direction == DOWN){ occupy[x][y+1] = 3;}
    if(direction == LEFT){ occupy[x-1][y] = 4;}

    printf(" %x\n", &occupy); //Strangely without this printf it doesn't compile???
    for(x = 0; x < 8; x++){
        for(y = 0; y < 8; y++){
            printf(" %u", occupy[x][y]);
        }
        printf(" \n");
    }

}


void main(){
    generate();
}

以下是关于代码的其他一些评论:

  • 您无法初始化RNG,因此结果将始终相同。设置种子有几种方法。通常情况下,您可以在标题屏幕上按时间进行操作,也可以选择种子选择器。

    //Seeds RNG by time taken to press start
    void seedRNG() {
        UINT16 seed = 0;
    
        printf("Press start\n");
        while (!(joypad() & J_START)) {
            seed++;
        }
        initrand(seed);
    }
    
    //Seeds RNG with a user-chosen number.
    //Requires inclusion of <gb\console.h>.
    void seedRNG() {
        UINT16 seed = 0x8000U; //In the middle to prevent over/underflow issues
    
        printf("Seed:");
    
        while (!(joypad() & J_START)) {
            if (joypad() & J_UP) { seed++; }
            if (joypad() & J_DOWN) { seed--; }
            gotoxy(0,1);
            printf("%x\n", seed);
            delay(10);
        }
        initrand(seed);
    }
    
  • 在这种情况下,您实际上不需要打印出来查看它,因为您可以使用&#34; Memory Viewer&#34;在大多数模拟器中找到。这些位置可以在使用-Wl-j-Wl-m选项生成的RAM地图中找到。

  • 我建议使用INT16WORD而不是intUINT16UWORD而不是unsigned int等它们包括名称中的大小。 UBYTE等等也很好用。

答案 1 :(得分:-1)

the following compiles



#include <stdio.h>
#include <stdlib.h> // contains rand and srand function prototypes
#include <time.h>
//#include "gb\gb.h"

void generate( void );

#define UP 0x01U
#define RIGHT 0x02U
#define DOWN 0x04U
#define LEFT 0x08U
typedef unsigned char UBYTE;

int occupy[8][8] =
{
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0}
};

int main()
{
    generate();
    return(0);
}


void generate()
{
    int temp;
    int x;
    int y;
    UBYTE block;
    UBYTE direction;

    for(x = 0; x < 8; x++)
    {
        for(y = 0; y < 8; y++)
        {
            occupy[x][y] = 0;
        }
    }
    /* ========Occupy=Cleared========== */
    block = 0x00U;
    srand(time(NULL) ); // initialize rand()
    x = rand() & 8;
    y = rand() & 8;

    if(x == 6 || x == 7){ block += RIGHT;}
    if(x == 0 || x == 1){ block += LEFT;}
    if(y == 0 || y == 1){ block += UP;}
    if(y == 6 || y == 7){ block += DOWN;}

    /* in the rest of generation wrap this block in if(block != 0x0FU){ */

    // NOTE:
    // in the following while loop if direction is not the same a block
    // then the loop will immediately exit
    // probably not what you want to do.
    do{
        temp = rand() & 4;
        if(temp == 0){ direction = UP;}
        if(temp == 1){ direction = RIGHT;}
        if(temp == 2){ direction = DOWN;}
        if(temp == 3){ direction = LEFT;}
    } while(block & direction);


    // NOTE:
    // in the following code,
    // 'x' and/or 'y' could be 0 or 7
    // in either case, one or more of the following statements
    // can/will cause accessing outside of the bounds
    // of the occupy[][] array
    occupy[x][y] = 5;
    if(direction == UP)   { occupy[x][y-1] = 1;}
    if(direction == RIGHT){ occupy[x+1][y] = 2;}
    if(direction == DOWN) { occupy[x][y+1] = 3;}
    if(direction == LEFT) { occupy[x-1][y] = 4;}

    for(x = 0; x < 8; x++)
    {
        for(y = 0; y < 8; y++)
        {
            printf(" %d", occupy[x][y]);
        }
        printf(" \n");
    }
}