25

我需要能够区分C++NULL0C++。

有没有办法使用类似===运算符(例如JavaScript中的身份运算符)来区分c++NULL0 c++ 之间的区别?

4

7 回答 7

36

NULL是一个预处理器宏,在预处理器运行时会直接替换为0。所以简而言之,没有。

于 2013-05-10T18:29:03.770 回答
34

这样的运算符在 C++ 中不是必需的,因为没有内置类型能够以有意义的可区分方式存储这两个值。此外,NULL在 C++ 中不需要,因为你可以0在任何地方用零替换它NULL。Bjarne Stroustrup 甚至建议NULL完全避免:

在 C++ 中,NULL 的定义是 0,所以只有审美上的区别。我更喜欢避免使用宏,所以我使用 0。NULL 的另一个问题是人们有时会错误地认为它不同于 0 和/或不是整数。在准标准代码中,NULL 有时被/被定义为不合适的东西,因此必须/必须避免。这几天不太常见了。

于 2013-05-10T18:30:20.083 回答
16

没有什么区别——NULL需要用值定义为整数常量0。整数类型通常被选择为与指针大小相同,但这实际上不是必需的。在 C 中,它经常被定义为(void *)0,但在 C++ 中这是不允许的(在 C 中这是合理的,因为指向 void 的指针支持到任何其他指针类型的隐式转换——但在 C++ 中这是不允许的,所以 ifNULL被定义为指向 void 的指针,您必须强制转换它才能获得任何其他指针类型)。

当/如果您想要一个可与 区分的空指针0时,您可能想要使用nullptr. nullptr可以分配给任何指针类型的变量,但不能分配给整数类型(例如,intlongsize_t等)

于 2013-05-10T18:29:26.663 回答
10

我想你要问的是:

如果我有一个变量x,我该如何区分

  1. x包含一个数字0
  2. x丢失/无值/空指针

C++ 具有强类型变量,因此即使有一个变量同时存在这两种可能性也是不寻常的。但是 NULL 值逻辑在数据库中很有用,所以让我们看一下在 C++ 中表示它的几种方法。

  1. 情况:x == 0在模板代码中检测到,其中的含义0不明确。
    答案:使用类型特征来确定是否x是指针(案例#2)或不是(案例#1)。

    if (is_pointer(x))
    
  2. 情况:p是一个 C 风格的 NULL 值逻辑变量,它是指向数值的指针。
    答:测试指针是否为空。如果没有,您可以检查指向的对象。

    if (p == NULL) { /* case 2 */ }
    else if (*p == 0) { /* case 1 */ }
    
  3. 情况:v是一个Win32 VARIANT,它是一个可区分的联合,用于在脚本语言中实现变量。
    答:检查鉴别键。

    if (v.vt == VT_EMPTY) { /* case 2a */ }
    else if (v.vt == VT_NULL) { /* case 2b */ }
    else if (v.vt == VT_I4 && v.lVal == 0) { /* case 1 */ }
    else if (v.vt == VT_I2 && v.iVal == 0) { /* case 1 */ }
    // and so on
    
  4. 情况:o是 NULL 值逻辑的 C++ 主义表示,例如boost::optional.
    回答:这些用于 NULL 值逻辑的 C++ 类提供了一种检测缺失值的方法。一个具体的例子boost::optional<int>表明它被设计为像指针一样被访问:

    boost::optional<int> o;
    if (!o) { /* case 2 */ }
    else if (*o == 0) { /* case 1 */ }
    
于 2013-05-10T19:14:58.653 回答
1

一般来说NULL,在C++0中是一样的(两者都是空指针)。

我假设您要问如何在C++中获得一个可以同时具有NULL0值的整数类型,并且能够区分它们。

你可以这样做boost::optional

boost::optional<int> val;

if(!val)
    std::cout << "null" << std::endl;
else
    std::cout << "val=" << *val << std::endl;

val = 0;
if(!val)
    std::cout << "null" << std::endl;
else
    std::cout << "val=" << *val << std::endl;

这应该打印出来nullval=0

于 2013-05-10T18:47:38.167 回答
1

实际上,这取决于您要比较的对象NULL0与之比较的对象……如果您要比较整数,则NULL应该像0与地址比较0一样起作用NULL

于 2013-05-10T20:22:12.687 回答
0

NULL是一个预处理器宏,将0在编译开始之前立即被替换。

C++ 没有 Javascript 的 operator ===。我能想到的最接近 C++ 的东西是排序伪等价关系,它用 JS 完成同样的事情===

if (!(x > y) && !(y > x)) { /* ... */ }

于 2018-09-29T14:12:54.707 回答