2015-05-23 4 views
0

я пытался реализовать BST с помощью C++, поэтому я попытался это:Передача указателя на функцию

#include <iostream> 
    #include <stdlib.h> 
    struct node 
    { 
     int value; 
     node* left; 
     node* right; 
    }; 

    void insert(node *cur , int val) 
    { 
     if(!cur) 
     { 
     cur = new node; 
     cur->value = val; 
     cur->left = NULL; 
     cur->right = NULL; 
     return; 
     } 

     if(val <= cur->value) 
     insert(cur->left , val); 
     else 
     insert(cur->right , val); 
    } 

    using namespace std; 

    int main() 
    { 
     node *root = NULL; 


     insert(root , 20); 
     insert(root , 21); 

     cout<<(*root).value; 

     return 0; 
    } 

, но у меня есть проблема, моя insert() функция работает хорошо, но не кажется, изменение cur для отражения в указателе root, так как root остается NULL после вызовов функции функции insert(). Что здесь не так?

EDIT: Спасибо за все ваши ответы, сделав указатель на указатель, кажется, будет уродливым и утомительным, есть ли какой-либо другой способ, с помощью чего-то другого?

+1

Почему C тег тогда? –

+1

параметры передаются по значению (функция получает копию значения параметра). Таким образом, 'cur' является локальной копией вызывающего параметра, поэтому' cur = whatever' изменяет локальный параметр. Вам нужно передать его по ссылке i.e. 'node * & cur' – bolov

ответ

1

Здесь root сам отправлен в insert() с использованием пропущенных значений. поэтому от insert() значение root не может быть изменено. Другими словами, cur является локальным для функции insert(). Любые изменения, внесенные в cur, не будут влиять на переданный фактический аргумент.

Если вы хотите изменить значение root от insert(), вам необходимо передать указатель на root от main().

Для elabotare, вы можете изменить значение по адресу указал на cur от insert(). Таким образом, следуя той же аналогии, если вы меняете

  1. insert(&root , 20);
  2. void insert(node **cur , int val)
  3. все вхождения cur в *cur

вы должны быть все хорошо идти.

+1

Было бы лучше использовать' void insert (node ​​* & cur, int val) ', который передал бы указатель в качестве ссылки ... – Nidhoegger

0

Неправильно то, что вы указали указатель по значению, измените это значение, но вызывающий не знает об этом. Измените его на

void insert(node **cur , int val) 
{ 
if(!*cur) 
{ 
    *cur = new node; 
    (*cur)->value = val; 
    (*cur)->left = NULL; 
    (*cur)->right = NULL; 
    return; 
} 

if(val <= (*cur)->value) 
    insert((*cur)->left , val); 
else 
    insert((*cur)->right , val); 
} 

И вызов функции изменения соответственно (... упражнение!)

0

C++ делает вызов функции вызова по значению. Таким образом, он делает копию указателя и передает его функции. Если вы передадите этот указатель, вы получите доступ к данным, на которые указывает указатель, но НЕ к указателю вне самой функции, поскольку копируется только адрес, на который указывает указатель.

Вам нужно передать указатель на указатель, если вы хотите изменить сам указатель (это будет попытка C) или передать по ссылке, с которой способен C++.

Если вы хотите использовать попытку C:

void insert(node ** cur , int val) 
if(!(*cur)) 
{ 
    (*cur) = new node; 
    (*cur)->value = val; 
    (*cur)->left = NULL; 
    (*cur)->right = NULL; 
    return; 
} 

или попытка C++ (здесь у вас есть только изменить тип дворняжка, Everthing остальное останется как есть):

void insert(node *& cur , int val) 
0

Если вы переназначите cur на новый узел вставки, это не означает, что этому корню присвоено это значение (особенно этот корень не является адресом вообще, а NULL).

Либо передайте указатель на пустой узел, чтобы вставлять его при инициализации (и обновлять его соответствующими данными), либо возвращать новый узел (и назначать его root в основном).

0

Если вы хотите, чтобы функция работать на указателе вне, а не локальной копии вам нужно пройти по ссылке:

void insert(node*& cur, int val) 
{ 
    // ... 
} 

В противном случае функция работает на копию указателя и вне переменная остается неизменной.

Смежные вопросы