2017-02-02 4 views
0

Вот две структуры, которые я использую. Я не уверен, как инициализировать так, чтобы член структуры указывал на структуру. Я не уверен, возможно ли это или нет.Указательный элемент структуры для самой структуры в C

typedef struct __node 
{ 
    int value; 
    struct __node* left; 
    struct __node* right; 
}setNode; 

typedef struct __set { 
    setNode* root; 
    //mutex for this set (To be implemented) 
}set; 

Я хочу, чтобы инициализировать члены набора, но не знаю, как я должен сделать, чтобы получить result->root, чтобы указать на тот же адрес, что и set result.

set* new_set() 
{ 
    set* result = malloc(sizeof(set)); 
    result -> root = NULL; // Not sure??? 
} 

Я хочу получить указатель на корень.

void someOther(set* s) 
{ 
    setNode* temp = s -> root; 
    //.... 
} 

Извините, если вопрос слишком расплывчатый.

Additional Info

Я хочу два структур. Тот, который содержит узлы дерева [setNode] и второй структуры, который содержит указатель на корень дерева и некоторые другие члены (например, мьютекс для этого дерева) [set]. Это не проблема.

Проблема: В функции у меня есть setNode* temp = someSet -> root;, так что я должен иметь возможность перемещаться по дереву. I.e temp должен указывать на корень someSet. Итак, что я должен назначить result -> root в функции new_set?

+4

'__node' является UB, поскольку он содержит два последовательных символа подчеркивания. Не делай этого. – Bathsheba

+10

@ Bathsheba Not UB, но такие имена зарезервированы. –

+0

Вопрос не зависит от макета ... –

ответ

0

Пустой набор не содержит элементов. Если набор представлен двоичным деревом поиска, для него подходит корневой указатель NULL.

set* new_set() 
{ 
    set* result = malloc(sizeof(set)); 
    result -> root = NULL; // Yes, absolutely positively 100% sure 
    return s; // Don't forget! 
} 

Если вы хотите получить указатель на root, получите его.

void someOther(set* s) 
{ 
    setNode* temp = s -> root; 
    //!!!! 
} 

Ничто не является неправильным с temp существом NULL. Ваша функция должна быть в состоянии справиться с этим. Если вы хотите рекурсивную функцию обхода, написать один, который получает setNode* аргумент:

void someOther(set* s) 
{ 
    setNode* temp = s -> root; 
    someOtherDoThisActuallyIMeanItNow (temp); 
} 

void someOtherDoThisActuallyIMeanItNow (setNode* current) 
{ 
    ... 
    if (current) { // <-- here we check that it's not NULL 
     ... 
     someOtherDoThisActuallyIMeanItNow (current->left); 
     ... 
     someOtherDoThisActuallyIMeanItNow (current->right); 
    } else { 
     // do whatever is appropriate for an empty tree/set 
    } 
} 

Если вам нужна функция, которая рекурсивно пересекает и модифицирует дерево, сделать один, который принимает setNode** аргумент.

void someOtherWithMutation(set* s) 
{ 
    setNode* temp = s -> root; 
    someOtherWithMutationNow (&temp); // <---- here 
} 

void someOtherWithMutationNow (setNode** current) // <---- here 
{ 
    ... 
    if (*current) { // <-- here we check that it's not NULL 
     ... 
     someOtherDoThisActuallyIMeanItNow ((*current)->left); 
     ... 
     someOtherDoThisActuallyIMeanItNow ((*current)->right); 
     ... 
     if (...) { 
      free (*current); 
      *current = NULL; 
     }   
    } else { 
     // do whatever is appropriate for an empty tree/set 
     ... 
     *current = malloc(sizeof(setNode)); 
     ...   
    } 
} 
Смежные вопросы