【问题标题】:What is the difference between NULL in C++ and null in Java?C++ 中的 NULL 和 Java 中的 null 有什么区别?
【发布时间】:2010-06-02 17:54:58
【问题描述】:

我一直在试图弄清楚为什么 C++ 让我疯狂地输入NULL。前几天它突然袭击了我;多年来,我一直在用 Java 输入 null(小写)。现在突然间我在用 C++ 编程,而那一小块肌肉记忆让我发疯了。

Wikiperipatetic 将 C++ NULL 定义为 stddef 的一部分:

扩展为空指针的宏 持续的。它可以定义为 ((void*)0), 0 或 0L 取决于 编译器和语言。

Sun 的文档告诉我关于 Java 的“空文字”:

null 类型有一个值,null 引用,由字面量表示 null,由 ASCII 组成 人物。空文字总是 null 类型。

所以这一切都很好。我知道空指针引用是什么,感谢您的编译器注释。现在我对 Java 中文字的概念有点模糊,所以我继续阅读......

文字是源代码 固定值的表示; 文字直接表示为 您的代码无需 计算。

还有一个特殊的空字面量 可以用作任何值 参考类型。可以分配 null 到任何变量,除了变量 原始类型。你很少 可以处理超出的空值 测试它的存在。所以, null 通常在程序中用作 标记以指示某个对象是 不可用。

好的,我想我现在明白了。在 C++ 中,NULL 是一个宏,它在编译时计算为空指针常量。在 Java 中,null 是一个固定值,也可以分配任何非原始值;非常适合在方便的 if statement 中进行测试。

Java 没有指针,所以我可以理解为什么它们将 null 保留为一个简单的值,而不是任何花哨的值。 但是为什么 java 决定将所有大写的 NULL 改为 null

此外,我这里有什么遗漏吗?

【问题讨论】:

  • “Java 没有指针”。实际上,Java only 有指针。
  • ((void*)0) 不是 C++ 中NULL 的有效定义。
  • @Viktor Sehr:不正确。 Java没有指针。即使某些实现(甚至全部)决定通过物理指针来实现Java对象的概念,仍然不代表Java中的对象就是指针。
  • @AndreyT。 Java 对象显然不是指针。 Java 对象是 Java 对象。 @Viktor 的意思是不能将对象存储在变量中,而只能引用对象,这是真的。
  • 我要把这个送给 Noah,但要对 aioobe 和所有回答或至少分享他们对大写的看法的人表示敬意。

标签: java c++ null


【解决方案1】:
  • NULL 是一个预处理器指令标识符,按照惯例,应该全部大写。

  • null 是一种语言文字,表示一个常数值,并且按照惯例应该都较低(就像truefalse)。

    李>

【讨论】:

  • 很好,很好的回答。现在,知道为什么他们有这个约定吗?你知道他们必须围坐在一张桌子旁谈论真/假/空并思考......“嗯,我们正在改变他们的空......”
  • @Stephano 他们可能没有坐下来谈论它。 “true”和“false”在 C++ 中也是小写的。这是一个很常见的约定。一旦 Java 确定“这里没有对象”的概念是一个内置常量,它就需要遵循约定。因此,“空”。
  • 实在想不出什么好的答案,除了所有的关键字都是小写的。也许他们只是想强调它不是任何类型的宏,实际上是语言规范的一部分。老实说,我不认为他们认为这是对 C++ NULL 的“改变”。
  • 我想我只是个懒人。我想象着 Bjarne 在 90 年代后期的一个早晨穿着睡衣,他试图写一个 if(foo == NULL) 并诅咒 Java 的疯狂小写
  • 我一直认为它们被大写是为了让你知道它们不是语言的一部分,甚至在编译器看到之前就被替换了,并且可能有副作用。例如,如果预处理器放置了两次“b++”,则 MAX(a,++b) 可能不会执行您想要的操作。在我看来,大写约定是一个警告,并提示在哪里查找定义(/include 而不是 /lib)。
【解决方案2】:

Java 的 null 更像是 C++0x 的 nullptr。 C++ 中的 NULL 只是 0,最终可以解析为 int 而不是您想要的指针。考虑:


void f(int);
void f(char*);

...

f(NULL); // which f()?

C++0x 有 nullptr,它解决了这个问题,但它仍然不能完全等同于 Java 的 null。它们只是不同的语言。

哦,另一个区别是 Java 没有指针(或者它是这么说的)。在 Java 中,您可以合法地将 null 分配给引用,而在 C++ 中,如果没有使用格式错误的构造,则无法做到这一点。诚然,如果没有这种能力,Java 几乎毫无用处,但这绝对是另一个重要的区别。

【讨论】:

  • Java引用具有C++指针的一些属性和C++引用的一些属性,所以很难直接比较。
  • 不,Java 的 null 与 C++ 的 nullptr 完全没有相似之处,因为 Java 没有指针,而 C++ 的 nullptr 是严格特定于指针的。
  • +1 很好的答案,不过,您错过了关于大写字母的部分。 Anyhoo,我认为人们通常对此不太感兴趣。我显然是个怪人。
  • @Stephano - 是的,我做到了。我真的不知道孙为什么这样做。这里的其他一些答案是有道理的,但最后我认为这一切都只是猜测。除非我们能在某个地方找到它的文档,否则除了 Sun 没有人会真正知道。
  • 我不知道我正在开启“Java 指针是/否”的争执。我同意诺亚的观点。那是跑题了。不要对回答问题但冒犯您的敏感代码视图的人投反对票。
【解决方案3】:

关于你的最后一个问题,我不确定小写 null 背后的设计原理是什么, 但我认为目标是使 null 成为语言级别的文字(如真或假)而不是常量。

java 中的关键字通常是小写的,因此被命名为文字。常量(如 Integer.MAX_VALUE)通常是大写的。

【讨论】:

  • +1 也是一个很好的答案。我不得不去查找一堆常量,但似乎它们大多是大写的。有趣的一点。
  • 作为评论,我想指出 C 没有 truefalse,但头文件通常是 #define TRUE 1#define FALSE 0。 C NULL 符合这种模式。
【解决方案4】:

不,你已经明白了。在 C++ 中,空指针是分配给指针的任何文字零值。 NULL 只是 0 的宏,所以 ptr = 0ptr = NULL 是相同的。它只是为了方便/可读性而包含在内。它是大写的原因是因为在 C 和 C++ 中有一个长期的约定,即宏的名称应该是大写的。

在 Java 中,null 是一个内置字面量,并且由于它不是宏(而且 Java 也没有宏的概念),因此没有令人信服的理由将其设为大写。

【讨论】:

    【解决方案5】:

    使用0 而不是NULL

    摘自该语言的创建者 Bjarne Stroustrup 的“C++ 编程语言”一书:

    在 C 语言中,定义一个宏 NULL 来表示零指针是很流行的。因为 C++ 更严格的类型检查,使用普通的0,而不是任何建议的NULL 宏,导致问题更少。如果您觉得必须定义NULL,请使用const int NULL = 0

    【讨论】:

    • 哇,很有趣。所以我可以说这样的话:(类)节点n = 0; ?
    • 它必须是 Node *n = 0,因为 0 是一个(空)指针。换句话说,由于没有对象可以在内存 0 中拥有地址,因此在这种情况下,0 表示指针不指向 Node 类的实例。否则,看起来您正在尝试将 Node 强制转换为整数。
    • 对,C++ NULL 是 0,而 C NULL 更多时候是 (void*)0。
    • +1 教我一些很酷的东西。我不知道 Node* n = 0;是有效的。
    • @Metaliving 我想你的意思是将一个整数转换(=隐式转换)一个节点,以防 * 被省略。
    【解决方案6】:

    Java null 关键字用于将变量标识为不引用任何对象。不能将 null 关键字分配给使用原始数据类型声明的变量。 C++ NULL 值是一个定义为 0 的常量。

    【讨论】:

      【解决方案7】:

      在 C++ 中,NULL 是一个宏,当 编译,定义空指针 常数。

      这是你弄错的地方。在 C++ 中,NULL 为 0,仅此而已。指针和整数都可以为NULL。

      另一方面,在java中,null是一个空指针,意味着只有对象可以为null。

      【讨论】:

      • 我不会说这是错的。 NULL 是一个计算结果为空指针常量 0 的宏。它没有定义空指针上下文,但我认为这只是一个模棱两可的词选择问题。
      • 那是一个糟糕的词选择。我已将其更改为“评估为”。
      • @both cmets - 这张海报是正确的,这是需要注意的重要事项。 NULL 不是指针常量,它是一个整数常量。碰巧 NULL 的值 0 在指针值的上下文中使用时也会计算为空指针。正如我在自己的帖子中提到的那样,NULL 将在指针之前解析为整数,因为它实际上就是这样。
      【解决方案8】:

      正如您自己所说,Java 没有指针,这就是为什么“null”的概念在 Java 和 C++ 之间完全无法比拟的原因。

      您的问题与“角度和苹果之间有什么区别”一样有意义,即除了显而易见的问题之外,无法以任何其他方式回答:C++ 中的NULL 和Java 中的null 是两个完全不相关的概念。

      Java 从未“决定”将所有大写字母 NULL 更改为 null,因为 Java 的 null 与 C++ 的 NULL 没有任何关系。

      【讨论】:

      • 从另一个角度来看,Java 主要是指针,因此概念非常接近。
      • Andrey:这完全正确,但实际上是错误的。没错,Java 本身就缺少指针,但它的引用与 C/C++ 指针非常相似。
      【解决方案9】:

      好吧,我不知道为什么 java 决定将 NULL 更改为 null,但是大写字母更难输入(至少在我的考虑中)。但是您可能总是可以问太阳:-P。无论如何,说 java 没有指针并不完全正确,因为 java 或 c# 或类似的普通引用更像指针而不是 c++ 中的引用。例如,在 c++ 中,引用不能为 NULL,但 java 中的引用可以。 c++ 中的引用不能改变它指向的变量(我可能在这一点上弄错了),但是 java 引用可以。

      【讨论】:

        【解决方案10】:

        指针基本上是内存地址。并且只有一个众所周知且已建立的内存地址 0。c++ NULL 是大写的,因为它是一个预处理器宏,并且它们总是按照惯例大写。指针概念直接映射到硬件地址空间的概念。

        Java 使用引用,并且它有自己的内部表示它们的方式。有一个众所周知的参考,null。它是小写的,因为它基本上是另一个符号,尽管它指的是文字值。我认为他们没有“改变”任何从 C 到 Java 的东西。我认为他们只是想要 null 概念,所以他们称之为“null”。

        在这两种情况下,null 都允许函数返回附加信息。它可以返回结果的地址可能操作不成功的事实。

        【讨论】:

        • 在 C 和 C++ 中将 0 用于空指针并不是基于内存位置 0 是特殊的想法,尽管它通常是这样实现的。常量整数 0 将被强制转换为空指针常量。
        • 我并不是说内存位置 0 是特殊的,只是它是众所周知的并且被用作约定说指针不是有效地址。
        猜你喜欢
        • 2013-10-19
        • 2011-02-14
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 2016-12-23
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多