控制到达非空函数的末尾

时间:2014-02-22 17:41:55

标签: c++ breadth-first-search

此代码应完美运行并提供正确的结果,但事实并非如此。我使用调试器,一切都很好。在函数返回之前,c.ic.j具有正确的值。我确保始终在开始和结束之间有一条路径,这不是问题所在。 pathvis数组也填充了正确的值。所以唯一的问题是它何时返回。它给出了随机的大数字。它仅在我在函数末尾放置一个return语句时才有效。但是我可以创建一个只有一个返回语句放在if子句中的函数,它可以工作。是否有某种规则,所以函数末尾必须有任何返回语句?为了测试它,我输入1x的3x3二维数组。任何解决方案?

编辑:我在ideone上运行它,它在函数末尾没有return语句。我的一个朋友也在他的电脑上测试它也工作。我在Windows 7上使用代码块。问题是什么?

link to ideone

#include <iostream>
#include <string>
#include <queue>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <cmath>

using namespace std;

struct crd {
    int i,j;
};

bool vis[50][50];
int map[50][50];
int path[50][50];

int di[4] = {1,-1,0,0};
int dj[4] = {0,0,1,-1};

int bfs(crd start, crd end, int n, int m)
{
    queue<crd> q;
    crd t,c;
    q.push(start);
    vis[start.i][start.j] = 1;
    path[start.i][start.j] = 0;

    while (!q.empty()) {
        t = q.front();
        q.pop();

        for (int i=0; i<4; i++) {
            c.i = t.i + di[i]; 
            c.j = t.j + dj[i]; 
            if (c.i >= 0 && c.j >= 0 && c.i < n && c.j < m) {
                if (map[c.i][c.j] != -1 && vis[c.i][c.j] != 1) {
                    q.push(c);
                    vis[c.i][c.j] = 1; 
                    path[c.i][c.j] = path[t.i][t.j] + 1; 
                    if (c.i == end.i && c.j == end.j)
                        return path[end.i][end.j];
                }
            }
        }

    }
    // if i put this: return path[end.i][end.j]; it works
}

int main()
{
    for (int i=0; i<3; i++) {
        for (int j=0; j<3; j++)
            cin >> map[i][j];
    }

    crd s,e;
    s.i = s.j = 0;
    e.i = e.j = 2;

    int sp = bfs(s,e,3,3);

    cout << sp << endl;


    return 0;

}

4 个答案:

答案 0 :(得分:1)

编译器是非常基础的 - 它无法知道你的函数总是会在if里面if内的if里面返回for内的while在{{1}}循环内循环。所以它会警告你,你可能不会从函数中返回任何内容。最简单的解决方法是在最后返回适当的值,并且只在你现在返回的点之外在循环之外中断。

答案 1 :(得分:1)

如果您声明一个非void返回类型的函数,则此函数返回一个值。如果执行到达函数的末尾,并且那里没有return <value>;语句,则函数的结果将是未定义的。

答案 2 :(得分:1)

当你“脱离函数的边缘”时,返回值是未定义的(意味着它可以是任何东西,包括对你返回的类型无效的值)。

所以,每个函数最后都应该有一个返回值。或者某种方式说“我没想到到这里,现在停下来”,如果这是合适的事情(例如,你在寻找列表中的某个东西,并且你不希望找不到它,那么有东西打印“我找不到,期望。停止......”然后退出程序)。

如果你找不到end.iend.j,我不完全确定返回的是什么,但你肯定应该返回SOMETHING。

答案 3 :(得分:1)

你有两个错误。

  1. 在返回值的函数末尾没有return语句,但如果永远无法到达函数的末尾,则。在这种情况下,您的搜索算法可能无法找到路径(当然取决于输入数据的内容),然后外部循环将终止而不会执行return语句。在while循环之后,您必须有另一个return语句,以说明这种可能性。它应返回path[end.i][end.j];而应返回一个特殊值,表示搜索失败。这是编译器检测到并告诉您的错误。

  2. 在您的广度优先搜索逻辑中某处出现错误,即使存在 ,也会导致找不到路径。您需要自己调试。