为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
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++中的大多数链表实现都是这样的,指针引用将用作"next"节点的类型
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中,所有原语都是直接值。基元是int
、long
、short
、byte
、char
、double
、float
和boolean
。这些是按值直接传递的:如果你调用一个传递5
的方法,5 被推到堆栈上。如果调用的方法更改了其值,则调用方无法分辨。
但是除了硬编码的原语列表之外,所有其他类型都称为引用,它只是指针的java-ese - 除了在java中,你不能做指针算术。你不能要求"内存位置比这个对象所在的位置高5",就像你在C中所做的那样。
这里有一个简单的例子:
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 的列表变量没有影响:它重新分配变量(创建一个新对象,然后更新其引用以指向这个新对象(。 example1 的列表不会更改;它的指针不会改变。
这就像藏宝图:每个人都有藏宝图的副本,但没有宝藏的副本。in.add
就像:"按照地图,打开宝箱,放一个新物品"。in = new ArrayList
是:"制作一个新的宝箱,把它埋在沙子里,把这张藏宝图抹掉,现在在上面写下这个新埋的宝箱的位置"。如果我有你的地图副本,如果你跟随你的副本并添加到宝藏中,那么如果我稍后按照我的地图,我会看到它。但是,如果你制作了一张全新的地图,那么你在新地点对宝藏所做的一切都不会被我注意到。
这与C++的行为相符。至少,对于Node*
.不适合Node
.
潜在的区别是什么?
可能根本没有。在机器代码级别,每个节点都包含链中下一个节点的地址。
相反,问题是关于语言如何在源代码中表示对象。写成Foo bar
的变量声明(例如(将是Foo
类型的实际实例,还是获取(句柄、指针、引用(实际实例的一种方式。 如果它是实际实例,您的语言可能还需要一些语法来描述不是实例,而是获取实例的方式。 也许不止一种方式(Foo*
,Foo&
C++(。
不同方法的可能性是我们拥有不同编程语言的原因之一。
在C++中,变量(对象(可以通过三种方式传递:
- 按值
- 通过指针
- 通过引用
(它们实际上都是按值传递的,但非常具体的一个(
例如,在Java中,对象总是通过引用传递,而原语则通过值传递。Java 中没有指针或显式引用。
C++当您不再需要某个对象时,您需要使用delete
将其删除。在Java中,你只需要替换变量,或者只是不使用它 - GB会为你删除它。
阅读了已发布的答案以及与参考文献和指针相关的其他堆栈溢出内容后,例如C++参考与 C# 参考
这对我来说更有意义,
-
C# 引用是托管引用。但在C++没有这样的 管理环境,因此我们需要分配和谨慎 取消分配内存。在 C# 中,这将由 气相色谱。因此,建议尽可能使用引用,而不是 比直接使用指针。
-
与C++指针类似,C# 也可以保存空值。 C++指针保持 内存位置的地址,C# 引用保存 内存中的另一个对象。
-
在 C# 中,我们只能在不安全的范围内使用指针,而在 Java 中没有这样的指针概念。
考虑到所有这些,对于在托管环境中执行的编程语言,我们可以使用引用而不是指针。
如果这个答案可以进一步改进,请随意编辑!
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- Java 和其他语言在生成子序列时的输出差异
- 为什么像C++和Java这样的语言有一个内置的LinkedList数据结构
- 解释Java作为一种安全语言?
- 用java编写源代码,并将其编译为其他语言的各种可执行文件?多重编译
- 高级语言(例如Java)和汇编语言之间的关系
- Java 服务器套接字,客户端采用 C 语言
- 如何使用C,C++,Java等语言动态生成HTML
- Java有垃圾回收,为什么C和C++语言没有垃圾回收
- 使用大多数Java代码制作可执行文件,但可能添加了其他语言
- constchar***是什么意思?它是如何从C语言转换为Java语言的
- 库在C/C++和其他语言中重现Java原语hashCode逻辑
- Java 编程语言中的数据类型如何映射到本机编程语言(如 C 和 C++)中的数据类型
- 什么编程语言最适合通过Arduino上的传感器控制屏幕上的动画?Java语言C++
- 如何将用Java编写的"ArrayList<ClassNod>"转换为C++程序语言?
- 是任何编程语言(C++、C#、Java、C.)中声明函数的最终内存地址,无论是相对地址还是绝对地址
- Java、C、C++等语言中的小数精度
- 为什么C/C++有不同于C#和Java等其他语言的头文件
- 为什么在MongoDB或CouchDB中使用Javascript而不是其他语言,如Java, c++
- 用于MySQL的编程语言:Java或c++