C - 按参考呼叫

时间:2011-12-04 19:45:09

标签: c pointers data-structures segmentation-fault

我编写了一个简单的程序来逐个对数字进行重复排序,然后将它们逐个插入到树中。我的问题是,我无法插入root的子节点,因为我无法将下面的函数更改为call-by-reference类型。

下面的q参数需要保存root的地址值。

void insertNode(int data, node *q, node *parent){
    if(q == NULL){
        node *p = createNode(data);
        p -> parent = parent;
        p -> key = generateKey(p);
        int i;
        for(i = 0;table[i][1] != 0;i++);
        table[i][1] = p -> data;
        table[i][0] = p -> key;
        q = p;
    }
    else if(q -> left > q -> right || q -> left == q -> right){
        q -> right++;
        insertNode(data, q -> rightChild, q);
    }
    else if(q -> right > q -> left){
        q -> left++;
        insertNode(data, q -> leftChild, q);
    }
}

3 个答案:

答案 0 :(得分:7)

在C中没有“通过引用传递”这样的东西。如果你需要为传递给函数的指针分配一个新值(不仅仅是改变指针指向的那个)你将需要传递指针指针,即

void insertNode(int data, node **q, node *parent){
    /* code */
    *q = p;
}

当您在C中传递指针(或其他任何内容)时,您正在传递指针的副本。因此,这种类型的更改对于您的函数的调用者是可见的:

q->someVal = someOtherVal;

但这不是因为您只修改传递给函数的副本:

q = p;

您需要添加另一个间接级别,以便修改参数本身,以便更改在函数外部可见。

答案 1 :(得分:2)

在“if(q == NULL){”中分配的节点 “块丢失;一旦函数返回,调用者就没有指向它的指针。(q = p;赋值什么都不做)

更新:** p也可以删除递归:

void insertNode(int data, node **qRef, node *parent){
  node *q;
  int i;

  for (   ; (q = *qRef) ; parent=q ) {
    if(q->left >= q->right) {
      q->right++;
      qRef = &q->rightChild;
    }
    else {
      q->left++;
      qRef = &q->leftChild;
    }
  }


  *qRef = q = createNode(data);
  q->parent = parent;
  q->key = generateKey(q);

  for(i=0; table[i][1] != 0; i++) {;}
  table[i][1] = q->data;
  table[i][0] = q->key;

}

答案 2 :(得分:0)

这个怎么样?

void insertNode(int data, node **qRef, node *parent){
  node *q = *qRef; //<-- changed
  if(q == NULL){
    node *p = createNode(data);
    p -> parent = parent;
    p -> key = generateKey(p);
    int i;
    for(i = 0;table[i][1] != 0;i++);
    table[i][1] = p -> data;
    table[i][0] = p -> key;
    *qRef = p; //<-- changed
  }
  else if(q -> left > q -> right || q -> left == q -> right){
      q -> right++;
      insertNode(data, &(q -> rightChild), q); //<-- changed
  }
  else if(q -> right > q -> left){
      q -> left++;
      insertNode(data, &(q -> leftChild), q);  //<-- changed
  }
}