簡體   English   中英

為什么 C++ 使用指向鏈表中下一個節點的指針,但像 C# 或 Java 節點僅使用 C# 或 Java 的名稱

[英]Why C++ uses pointer for next node in linked list, but langauges like C# or Java use just the name of the class Node?

C++中的大部分鏈表實現都是這樣的,指針引用將作為“下一個”節點的類型

class Node {
public:
    int data;
    Node* next;
}

但是對於像 C#、Java 和 Python 這樣的語言,為什么不直接使用指針呢? 我只能看到這種實現:

// C#
class Node {
    int data;
    Node next;
}
// Java
class Node {
    int data;
    Node next;
}

根本區別是什么? 當然 Java 不支持指針,但是 c# 呢?

CPP 的Node*相當於 java 的Node ,我很確定 C# 的Node也是如此。在 java 中,所有原語都是直接值。原語是intlongshortbytechardoublefloatboolean 。這些是直接按值傳遞的:如果調用傳遞5的方法,則 5 被壓入堆棧。如果調用的方法改變了它們的值,調用者無法判斷。

但是除了那個硬編碼的原語列表之外,所有其他類型都稱為引用,這只是指針的 java-ese - 除了在 java 中,你不能做指針算術。 一點也不。 您不能像在 C 中那樣要求“memory 位置比 object 居住的任何地方高 5 處”。

這是一個簡單的例子:

class Example {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("Hello!");
        System.out.println(list);
        example1(list);
        System.out.println(list);
        example2(list);
        System.out.println(list);
    }

    static void example1(List<String> in) {
        list.add("World!");
    }

    static void example2(List<String> in) {
        in = new ArrayList<String>();
        in.add("Bye!");
    }
}

這將打印:

[Hello!]
[Hello!, World!]
[Hello!, World!]

example1 從不更改變量(引用),它只是“取消引用它”(跟隨指針),因此您所做的更改會在調用者中觀察到。

但是 example2 對 main 的列表變量沒有影響:它重新分配變量(創建一個新的 object,然后更新它的引用以指向這個新對象)。 example1 的列表沒有改變; 它的指針不會改變。

就像藏寶圖:每個人都有一份藏寶 map,但沒有藏寶。 in.add就像:“跟隨 map,打開寶箱,放入新物品”。 in = new ArrayList是:“做一個新的寶箱,把它埋在沙子里,把這個寶箱 map 擦掉,現在把這個新埋的寶箱的位置寫在上面”。 如果我有你的 map 的副本,如果你跟隨你的副本並添加到寶藏中,那么我會看到,如果我以后跟隨我的 map。 但如果你制造了一個全新的 map,那么無論你對新位置的寶藏做什么,我都不會注意到。

這符合 C++ 的行為......至少對於Node* 不適用於Node

根本區別是什么?

可能根本沒有。 在機器代碼級別,每個節點都包含鏈中下一個節點的地址。

相反,問題在於語言如何在源代碼中表示對象。 是寫成Foo bar (例如)的變量聲明將成為Foo類型的實際實例,還是將成為獲取(句柄、指針、引用)實際實例的一種方式。 如果它是實際實例,您的語言可能還需要一些語法來描述不是實例,而是描述實例的方式。 也許不止一種方式( Foo*Foo&在 C++ 中)。

不同方法的可能性是我們使用不同編程語言的原因之一。

在 C++ 中,變量(對象)可以通過三種方式傳遞:

  • 按價值
  • 通過指針
  • 引用

它們實際上都是按值傳遞的,但非常具體

在例如 Java 中,對象總是通過引用傳遞,而基元則通過值傳遞。 Java 中沒有指針或顯式引用。

在 C++ 中,當您不再需要 object 時,您需要使用delete將其刪除。 在 Java 中,您只需要替換變量或不使用它 - GB 會為您刪除它。

在閱讀了與引用和指針相關的已發布答案和其他 stackoverflow 內容后, C++ 參考與 C# 參考

這對我來說更有意義,

  • C# 參考是托管參考。 但是在 C++ 中沒有這樣的管理環境,因此我們需要分配和小心地取消分配 memory。 在 C# 中,這將由 GC 自動管理。 因此,建議盡可能使用引用而不是直接使用指針。

  • 與 C++ 指針類似,C# 也可以保持空值。 C++ pointers hold address of a memory location, C# References holds the address of another object in the memory.

  • 在 C# 中我們只能在不安全的 scope 下使用指針,而在 java 中則沒有這樣的指針概念。

考慮到所有這些,對於在托管環境中執行的編程語言,我們可以使用引用而不是指針。

如果可以進一步改進此答案,請隨時編輯!

暫無
暫無

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

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