在C中打破递归函数

时间:2013-11-08 02:04:06

标签: c recursion binary-tree

有问题的功能:

struct node* findNext(struct node *root, struct node *ldr, int *p) {

  // Check if there are nodes in the tree.
  if(p == 0){
  if (root != NULL) {
    // correct organ/bt combo
    if(cmpOrgan(root, ldr) == 1){
        if (strcmp(root->organ.name, ldr->organ.name) != 0){
            if(cmpDates(root, ldr) == 1){
                p = 1;
                return root;
            }
            // The leader has been in longer then root
            if(cmpDates(root, ldr) == 2){
                return findNext(root->left, ldr, p);
            }
        }
        else{
            findNext(root->left, ldr, p);
            findNext(root->right, ldr, p);
            }
    }
    if(cmpOrgan(root, ldr) == 2){
        return findNext(root->left, ldr, p);
    }

    if(cmpOrgan(root, ldr) == 3){
        return findNext(root->right, ldr, p);
    }
  }
  }
  return NULL;
}

我想在这一部分突破这个递归函数:

if (strcmp(root->organ.name, ldr->organ.name) != 0){
    if(cmpDates(root, ldr) == 1){
        p = 1;
        return root;
    }

我尝试这样做的方法是扫描一个指向该函数的全局指针,并在希望函数中断后将其更改为1。我的目标是在断点处返回当前的根。这可能吗?我正在通过这样做初始化main中的指针:

int *p = 0;

当我尝试使用* p = 1设置值时,程序将崩溃。我很确定我错过了一些基本的指针,但我只是不知道什么是我还是新编码。谁能帮我?还有另一种比较简单的方法,我不知道吗?感谢您提前提供任何帮助。

3 个答案:

答案 0 :(得分:3)

当您说int *p = 0时,您正在创建一个空指针,NULL == 0

当您稍后尝试说*p = 1时,您取消引用空指针,导致程序崩溃。

更准确地说,如果你真的想使用指针,你应该为你想要存储的int分配内存:

int *p = malloc(sizeof(int));
*p = 0;

然后你就有了放置int的地方。

或者,不要把它创建为指针 - 只需说

int p = 0;

然后使用p传递&p的地址,之前已经通过p,将作业更改为*p = 1

三分之一的可能性是根本不会传递p,只有一个全局变量p可以被任何级别的函数更改。这通常被认为是错误的编码风格,但会完成你似乎想要做的事情。

最后,请注意,您不应该真正需要设置一个变量来突破递归 - 当您返回时,它应该只是继续返回您的函数调用堆栈,这通常可以布局至于不需要这样的标志变量。

特别是,您对findNext进行两次递归调用,其返回值被简单地丢弃(在第一个else块内)。这些似乎并没有真正完成任何事情,你最有可能更好地保持他们的返回值并使用它们来决定返回什么,或者更好的是,只调用一个,检查它的返回值,然后制作只在必要时才打电话。

答案 1 :(得分:0)

在findNext中,您执行了以下操作

p = 1

但是p是指向integer的指针,因此您实际上将p指向的地址设置为等于1.这可能会导致访问冲突和SIGSEGV。

这就是你的程序崩溃的原因。它尝试将数据写入应用程序地址空间之外的地址。做qaphla说的应该工作,虽然我自己没有测试过。

答案 2 :(得分:0)

代码的以下部分出现错误:

else{
    findNext(root->left, ldr, p);
    findNext(root->right, ldr, p);
    }

在这两种情况下都会丢失返回值,这意味着任何路径中的任何成功搜索都将丢失。

类似下面的代码片段应该有效:

else{
    struct node *rv = findNext(root->left, ldr, p);
    if (rv) {
        return rv;
    } else {
        return findNext(root->right, ldr, p);
    }

也没理由调用cmpOrgan三次,每次调用cmpOrgan的递归中的任何级别都应该返回完全相同的值。同样适用于cmpDates。

因为每个路径都返回一个值。不再需要变量p。