2016-02-05 57 views
1

我讀到那些關於樹在C:爲什麼在C結構中使用兩個指針

struct node 
{ 
    int key_value; 
    struct node *left; 
    struct node *right; 
}; 

/* insert a value to tree */ 
insert(int key, struct node **leaf) 
{ 
    if(*leaf == 0) 
    { 
     *leaf = (struct node*) malloc(sizeof(struct node)); 
     (*leaf)->key_value = key; 
     /* initialize the children to null */ 
     (*leaf)->left = 0;  
     (*leaf)->right = 0; 
    } 
    else if(key < (*leaf)->key_value) 
    { 
     insert(key, &(*leaf)->left); 
    } 
    else if(key > (*leaf)->key_value) 
    { 
     insert(key, &(*leaf)->right); 
    } 
} 

我不明白這裏:插入(INT鍵,結構節點**葉)爲什麼兩個指針**葉,葉子好嗎?我很困惑什麼時候使用兩個指針.pls幫助,非常感謝!

+1

這是一個指向'struct node *'的指針。 – immibis

+0

這看起來像一棵二叉樹,如果是這樣,你的左右節點或「樹葉」就是子分支。 –

+2

**備註:** **葉;它不被稱爲「雙指針」。它被稱爲「指針指針」 – sami1592

回答

1

insert(int key, struct node **leaf)你通過C版本的「Pass By Reference」傳遞*leaf指向的地址。並且在insert(int key, struct node *leaf)中,您正在通過*leaf指定的地址通過Pass By Value方法。注C參數總是按值傳遞。

因此,在這種特殊情況下它不會,如果你使用insert(int key, struct node **leaf)insert(int key, struct node *leaf)兩者都將獲得相同的outputs.The只有在這種情況下區別。重要的是,在insert(int key, struct node **leaf)你的C版過關的傳遞地址的參考和在insert(int key, struct node *leaf)您通過Pass By Value方法傳遞地址。

示例代碼A,

#include<stdio.h> 

struct node 
{ 
    int data; 
}; 

void AddFive(struct node **t); 

int main() 
{ 
    struct node *n = NULL; 
    n = new node; 
    n->data = 5; 
    printf("%d\n", n->data); 
    AddFive(&n); 
    printf("%d\n", n->data); 

    return 0; 
} 

void AddFive(struct node **t) 
{ 
    (*t)->data = (*t)->data+5; 
} 

示例代碼B,

#include<stdio.h> 

struct node 
{ 
    int data; 
}; 

void AddFive(struct node *t); 

int main() 
{ 
    struct node *n = NULL; 
    n = new node; 
    n->data = 5; 
    printf("%d\n", n->data); 
    AddFive(n); 
    printf("%d\n", n->data); 

    return 0; 
} 

void AddFive(struct node *t) 
{ 
    t->data = t->data+5; 
} 

如果發現兩個代碼A和代碼B達到相同的輸出。

0

C只有通過價值。如果使用指向node struct的指針作爲參數,則在調用者函數中不會看到對傳遞指針的任何修改。在這種情況下,您必須返回函數insert的指針。指向指針的指針用於更新傳遞給函數insert的指針。

0

當您想要通過某個函數更改在main()中定義的變量的值時。想想你做了什麼。您發送該變量的地址,然後使用該地址,更改該變量的內容。現在

,在示例情況下,變量是int類型,因此發送該變量的地址將意味着在功能,你必須接受它在類型的變量int *

void test(int* var) { 
    *var++; 
} 

int main() { 
    int integer = 1; 
    test(&integer); 
    printf("%d", integer); 
    return 0; 
} 

要更改變量integer的值,將其地址發送給函數test()


現在採取這種相同的情況下,如果你需要改變一個變量,它本身就是一個struct node *的內容想。然後你發送該變量的地址,並用(struct node *)*接收它。那就是你發佈的例子中發生了什麼。

您希望對insert()函數中的leaf變量所做的更改反映在調用函數中。要發生這種情況,請發送地址並相應地更改內容。

0

它是通過引用來調用。如果我們必須改變*葉的值,那麼我們應該有它的地址這就是爲什麼當我們爲葉的指針和其他的時候使用兩個*來獲得*葉的地址。

0

情況1:

你逝去的變量的地址,則單個指針足以訪問變量

實施例:

struct node a; 

func(&a); // calling 

func()定義:

func(struct node *a); 

這裏指向節點的地址。我們可以直接使用它的地址訪問a

案例2:

當發送指針變量的地址:

struct node *a; 

func(&a); // calling 

然後在功能定義,它應該使用雙指針:

func(struct node **a);