簡體   English   中英

指針到C指針的麻煩

[英]Trouble With Pointers to Pointers in C

我試圖在C中編寫某種列表,而沒有為列表的開頭創建全局變量,但遇到了一些麻煩。

我的代碼最初是這樣的:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

struct Node {
    char *data;
    struct Node *next;
};

struct Node *init(struct Node *head) {
    head = malloc(sizeof(struct Node));
    head->data = "abc";
    head->next = NULL;

    return head;
}

struct Node *getHead(struct Node *head) {
    struct Node *retNode = NULL;

    if (head != NULL) {
        retNode = head;
        head = head->next;
    }

    return retNode;
}

int main(int argc, char **argv) {
    struct Node *head;
    head = init(head);
    printf("Head pointer before method:%p\n", head);

    getHead(head);
    printf("Head pointer after method:%p\n", head);
}

產生輸出:

Head pointer before method:0x7fffd36ad260  
Head pointer after method:0x7fffd36ad260

我以為這是失敗的,因為C是通過值傳遞的,這使我認為方法內部顯示了具有不同指針的相同副本。 但是,當我檢查方法中指向Head的指針時,我發現它與原始的head指針相同,因此看起來實際的指針在方法中。 我不明白這里發生了什么,所以如果有人可以解釋為什么即使存在相同的指針也不會更新頭部指針的原因。

我認為它應該工作,因為如果您有一個swap(int * a,int * b)方法,並且實際的指針是從main發送的,則內部進行的更改將同時影響外部的變量。 在網上看了之后,人們說要為此使用指針,盡管我似乎無法正常工作。

嘗試將其編碼如下:

//... same code as before for other methods
struct Node *getHead(struct Node **head)
{
    struct Node *retNode = NULL;

    if (head != NULL)
    {
        retNode = *head;
        *head = *head->next;
    }

    return retNode;
}

int main(int argc, char **argv)
{
    struct Node *head;
    head = init(head);
    printf("Head pointer before method:%p\n", head);

    getHead(&head);
    printf("Head pointer after method:%p\n", head);
} 

雖然在嘗試編譯時會遇到錯誤:

pointers.c:50:22: error: ‘*head’ is a pointer; did you mean to use ‘->’?
         *head = *head->next;

我也很茫然為什么會引發此錯誤。

就像其他人已經指出的那樣,由於運算符的優越性,您必須將*head放在括號中。

我有什么理解的是,為什么你覆蓋問題head與它的后繼者? 函數getHead應該更好地稱為removeHead嗎?

還要注意,函數init head參數無效,因為它會被以下malloc覆蓋。

我還建議閱讀有關Linux內核如何使用結構嵌入實現有效列表的出色文章。 很高興!

將雙指針傳遞給getHead因為您試圖在調用getHead的范圍內更新head

struct Node *getHead(struct Node **head) {
    struct Node *retNode = NULL;

    if (head != NULL && *head != NULL) {
        retNode = *head;
        *head = (*head)->next;
    }

    return retNode;
}

第一次嘗試之前和之后方法head的值相同的原因是,您從未更改mainhead的值。 函數getHead更改其指針head本地副本。 因此,如果您第一次嘗試在getHead內打印head ,您將看到它指向另一個地址。

暫無
暫無

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

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