奇怪的控制流程顺序
Strange order of flow of control
我被分配编写一个 'maze' 程序,该程序将允许用户通过从头到尾导航来玩和解决随机迷宫。到目前为止,我已经开发了一个适用于预定义迷宫的工作原型,但该机构要求我使其尽可能随机。为此,我包含了一个函数 'findpath',用于检查和验证是否可以解决随机迷宫,或者调用 'mazebuilder' 来创建另一个随机迷宫。整个代码在这里:http://codepad.org/wb1OGGrZ。
现在执行时,此函数显示非法控制流。
int findpath(int x, int y)
{
if(fpmap[x][y]==END) //1
{
return TRUE;
}
if(fpmap[x][y]!=PATH||fpmap[x][y]!=START) //2
{
return FALSE; //2a
}
min_moves++; //3
fpmoves++;
fpmap[x][y]=SOLUTION;
if(findpath(x,y-1)) //4
{
return TRUE;
}
if(findpath(x+1,y))
{
return TRUE;
}
if(findpath(x,y+1))
{
return TRUE;
}
if(findpath(x-1,y))
{
return TRUE;
}
min_moves--; //5
fpmap[x][y]=PATH;
return FALSE; //6
}
我试图跟踪程序,这是函数在调用时所做的事情:
1. 检查是否为#1。
2. 检查是否#2。
3. 跳至#6。
那么,如果程序在#4 或#5 之后,为什么不转到#2a 或#3?
它似乎只是跳过整个代码并冲到#6。这其中有逻辑错误还是语法错误?
请帮我解决这个问题。
PS:这段代码是为 TurboC 编译器编写的,因为我的能力要求我这样做。请耐心等待:(
有关 findpath 中使用的算法的更多信息:http://www.cs.bu.edu/teaching/alg/maze
编译器有时是奇怪的野兽。我能提供的最好的解释(因为我没有看到可能导致你的问题的直接编码错误)是编译器已经确定你正在引入未定义的行为并且只是拒绝编译有问题的代码(你可以通过检查生成的汇编代码来检查这一点在调试器中)。
有问题的代码是在递归调用 findpath
之前没有检查 x
和 y
的边界。递归会导致 x
and/or y
变得小于零或大于 scr+1
.
N.B.: 同样在 mazeloader 中,你有不必要的递归,最终会导致堆栈溢出:if(findpath(start.x,start.y))...else goto top;
而不是 else mazeloader();
甚至更好,单独的 mazeloader 从用户播放.
说明说您应该用 x
(BAD_PATH) 标记回溯位置,以避免再次尝试该子路径。您的代码用 .
(PATH).
标记它们
另外,你没有越界检查。
我被分配编写一个 'maze' 程序,该程序将允许用户通过从头到尾导航来玩和解决随机迷宫。到目前为止,我已经开发了一个适用于预定义迷宫的工作原型,但该机构要求我使其尽可能随机。为此,我包含了一个函数 'findpath',用于检查和验证是否可以解决随机迷宫,或者调用 'mazebuilder' 来创建另一个随机迷宫。整个代码在这里:http://codepad.org/wb1OGGrZ。 现在执行时,此函数显示非法控制流。
int findpath(int x, int y)
{
if(fpmap[x][y]==END) //1
{
return TRUE;
}
if(fpmap[x][y]!=PATH||fpmap[x][y]!=START) //2
{
return FALSE; //2a
}
min_moves++; //3
fpmoves++;
fpmap[x][y]=SOLUTION;
if(findpath(x,y-1)) //4
{
return TRUE;
}
if(findpath(x+1,y))
{
return TRUE;
}
if(findpath(x,y+1))
{
return TRUE;
}
if(findpath(x-1,y))
{
return TRUE;
}
min_moves--; //5
fpmap[x][y]=PATH;
return FALSE; //6
}
我试图跟踪程序,这是函数在调用时所做的事情: 1. 检查是否为#1。 2. 检查是否#2。 3. 跳至#6。 那么,如果程序在#4 或#5 之后,为什么不转到#2a 或#3? 它似乎只是跳过整个代码并冲到#6。这其中有逻辑错误还是语法错误? 请帮我解决这个问题。 PS:这段代码是为 TurboC 编译器编写的,因为我的能力要求我这样做。请耐心等待:(
有关 findpath 中使用的算法的更多信息:http://www.cs.bu.edu/teaching/alg/maze
编译器有时是奇怪的野兽。我能提供的最好的解释(因为我没有看到可能导致你的问题的直接编码错误)是编译器已经确定你正在引入未定义的行为并且只是拒绝编译有问题的代码(你可以通过检查生成的汇编代码来检查这一点在调试器中)。
有问题的代码是在递归调用 findpath
之前没有检查 x
和 y
的边界。递归会导致 x
and/or y
变得小于零或大于 scr+1
.
N.B.: 同样在 mazeloader 中,你有不必要的递归,最终会导致堆栈溢出:if(findpath(start.x,start.y))...else goto top;
而不是 else mazeloader();
甚至更好,单独的 mazeloader 从用户播放.
说明说您应该用 x
(BAD_PATH) 标记回溯位置,以避免再次尝试该子路径。您的代码用 .
(PATH).
另外,你没有越界检查。