簡體   English   中英

struct node * head和struct node ** head之間有什么區別?

[英]What is the difference between struct node *head and struct node ** head?

我正在嘗試對鏈表進行排序。 我很困惑何時使用struct node*head以及何時使用struct node **head ,可以使用它們來完成實現。

我什么時候應該使用:

void sortedinsert(struct node **head)

我什么時候應該使用:

void sortedinsert(struct node *head)

有了這個功能簽名:

void changeNode(struct node *head)

您有一個指向該節點的指針,因此您可以更改該結構。 無法更改變量頭指向的內容 我們假設struct node的以下定義:

struct node
{
    int field1;
    struct node *next;
}

使用給定的函數簽名和struct node ,考慮以下操作可以更改函數中的結構:

void changeNode(struct node *head)
{
    head->field1 = 7;
    head->next = malloc(sizeof(struct node));
}

C是按值傳遞:當我們將變量傳遞給函數時,函數會獲得一個副本 這就是我們將指針傳遞給struct node ,以便我們可以更改它,並在函數外部具有這些更改的效果。 但是我們仍然只獲得指針本身的副本 所以以下操作沒用:

void changeNode(struct node *head)
{
    // we're only changing the copy here
    head = malloc(sizeof(struct node));
}

head的變化不會反映在功能之外。 為了改變head要點,我們必須使用額外的間接級別:

void changeNode(struct node **head)
{
    // now we're changing head
    *head = malloc(sizeof(struct node));

    // alternately, we could also do this:
    *head = NULL;
}

現在head的變化反映在功能之外

如果head總是指向鏈接列表的頭部(一個恆定的位置)然后使用struct node * head如果你打算改變頭部使用節點指向的位置** head

struct node **head你可以通過它來引用/指向不同的內存區域來傳遞head指針的地址。 使用struct node *head您無法在其他任何地方進行head對點修改

第一個是指向節點的指針,節點是一個結構。

(struct node *) head;

head定義為可以存儲node地址的變量。

這允許在方法中通過引用傳遞node

第二個是指向節點的指針,該節點是結構。

(struct node **) head;

head定義為變量,它可以存儲具有node地址的另一個變量的地址。

這允許在方法中通過引用傳遞node *

node*是指向節點struct的指針。 node**是指向節點struct的指針。 如果要通過引用修改指針,則在C中使用指針指針。

假設您要在節點B上執行操作,該操作可能會使用不同的節點替換節點B. 一種做事方法是

nodeA.next = foo(nodeA.next);

另一種選擇就是做

foo(&nodeA.next);

並讓foo隱式替換nodeA.next指針。

在此示例中,由於head的值可能會在創建時發生變化(它可以指向與當前節點不同的某些其他節點),

你應該用,

void sortedinsert(struct node **head)

因為你的頭可能需要修改。

看來,下面的原型需要改變,

void sortedinsert(struct node *head)

因為這不允許你修改頭部,在這種情況下應該是(如果你使用這個),

struct node * sortedinsert(struct node *head)

返回更新的頭部,可以在此函數的調用者中使用。

運行或閱讀這個你可以看到它

#include <stdio.h>
struct node{
    int one;
    int two;
    struct node * next;
    //char location[100];
};
void changeHead(struct node** head){

}
void sort(struct node* head){

}
int main(){
    struct node* head = (struct node*) (malloc (sizeof(struct node)));

    // now head pointing to a node stucture ( if you dereferance head you get teh first value)

    struct node* tmp = head;

    struct node** newHead = (struct node**) (malloc (sizeof(struct node*)));

    //New head points to a 'struct node*', which hold an addtess of another struct node

    head->one = 12;//*head->one =12; //head.one = 12 is wrong cos it is holding an address.
    // you can do it but it doesnt make sence since you dont know whats on address #12


    // now if you want head to point to old head which is on tmp at the moment
    *newHead = head;

    // now if you working with 2 linked list and you want to change the heads use below
    changeHead(newHead);

    // if you want to just sort its better and easy to use
    sort(head);

    //chack whats on head and newhead
    printf("double derefence newHead:%d\n",**newHead);
    printf("derefence newHead(its and address same ad address of head):%d\n",*newHead);
    printf("Head(its and address):%d\n",head);
    printf("derefence Head:%d\n",*head);//head->one works too
}

簡單來說,當您想要更改“head”指向的位置時,請使用**head ,否則使用*head ,它不允許更改位置。

  1. 要改變指向第一個節點的指針的頭部,你需要傳遞head的地址,即(&head)來調用函數(因此你已經聲明了指向函數中指針變量的指針(struct node**head)因為它接收head地址,它只是指向第一個節點的指針。
  2. 但是,如果你知道頭部將保持固定,即你不希望頭部指向其他節點(例如......在開頭插入一個新節點),那么你只能傳遞(頭部)調用函數並寫入(*head)在函數定義中。

案例1:當您使用時:

void sortedinsert(struct node **head)

在函數內部你將實際修改 head 指針 ,因為很可能你會在里面使用*head sortedinsert很可能會使用參數&head調用。

案例2:當您使用時:

void sortedinsert(struct node *head)

在函數內部,您將修改 head 指針 的副本 ,因為很可能您將在內部使用head變量。 sortedinsert很可能會使用參數head調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM