代码之家  ›  专栏  ›  技术社区  ›  camh

对于C++中的指针,你使用NULL还是0(零)?

  •  180
  • camh  · 技术社区  · 16 年前

    在C++的早期,当它被闩到C的顶部时,不能使用null,因为它被定义为 (void*)0 . 您不能将NULL分配给除空指针以外的任何指针 void* 0 (零)表示空指针。

    直到今天,我仍然使用零作为空指针,但我周围的人坚持使用零 NULL . 我个人认为,说出一个名字没有任何好处( )到现有值-并且由于我也喜欢将指针作为真值进行测试:

    if (p && !q)
      do_something();
    

    然后使用零更有意义(就像使用 ,则不能在逻辑上使用 p && !q ,除非你假设 无效的 是零,在这种情况下为什么使用 无效的

    有没有客观的理由选择零而不是零(反之亦然),或者这一切都只是个人偏好?

    22 回复  |  直到 10 年前
        1
  •  197
  •   Community rcollyer    4 年前

    下面是Stroustrup的看法: C++ Style and Technique FAQ

    在C++中,定义 NULL 无效的 人们有时会错误地认为它不同于0和/或不是整数。在标准前规范中, 无效的 有时被定义为不合适的东西,因此必须避免。现在这种情况不太常见了。

    nullptr ; 这就是它在C++11中的名称。然后 将是一个关键字。

    也就是说,不要为小事操心。

        2
  •  126
  •   Toby Speight    4 年前

    1. 意向书

      NULL 允许对其使用进行搜索,并突出显示开发人员 受通缉的 无效的 无效的 或者不是。

    2. 指针和“int”的重载相对较少

       void foo(int*);
       void foo (int);
      
       void bar() {
         foo (NULL);  // Calls 'foo(int)'
       }
      

      然而,至少在我看来,上述问题并不是我们在使用 对于空指针常量:我们有 foo() 这需要非常不同的论点。参数必须是一个 int 同样,由于任何其他类型都会导致调用不明确,因此会生成一个有用的编译器警告。

    3. 分析工具可以帮助今天!

      即使在没有C++0x的情况下,今天也有可用的工具来验证这一点 无效的 用于指针,而且 0

    4. C++ 11 将有一个新的 std::nullptr_t 类型

      这是表中最新的参数。问题 正在为C++0x积极地解决这个问题,您可以保证,对于提供

       #define NULL  nullptr
      

      对于那些使用 无效的 0 ,这一变化将是一个在类型安全性方面的改进,几乎不需要或根本不需要付出任何努力——如果有任何改变的话,它也可能在它们使用的地方捕获一些bug 无效的 . 任何使用 0

        3
  •  46
  •   Andy Lester    16 年前

    使用NULL。NULL表示您的意图。它是0这一实现细节应该无关紧要。

        4
  •  40
  •   Donald Duck abhilash-ram    6 年前

    我总是使用:

    • NULL 指针
    • '\0' 查尔斯
    • 0.0 花车和双人

        5
  •  34
  •   Ferruccio bayda    16 年前

    很久以前,我就不再使用NULL,而是使用0(以及大多数其他宏)。我这样做不仅是因为我想尽量避免宏,而且因为空似乎已经过度使用C和C++代码。它似乎在需要0值时使用,而不仅仅是指针。

    对于新项目,我将其放在项目标题中:

    static const int nullptr = 0;
    

    现在,当符合C++0x的编译器到达时,我所要做的就是删除这一行。 这样做的一个好处是VisualStudio已经将nullptr识别为关键字,并适当地突出显示它。

        6
  •  22
  •   abonet    14 年前
        cerr << sizeof(0) << endl;
        cerr << sizeof(NULL) << endl;
        cerr << sizeof(void*) << endl;
    
        ============
        On a 64-bit gcc RHEL platform you get:
        4
        8
        8
        ================
    

    这个故事的寓意。在处理指针时,应该使用NULL。

    1) 它声明了您的意图(不要让我搜索所有代码,试图找出变量是指针还是数字类型)。

    2) 在某些期望变量参数的API调用中,它们将使用空指针指示参数列表的结尾。在这种情况下,使用“0”而不是NULL可能会导致问题。在64位平台上,va_arg调用需要一个64位指针,但只传递一个32位整数。在我看来,你依赖于其他32位为你调零?我见过某些编译器(例如英特尔的icpc)不那么优雅——这导致了运行时错误。

        7
  •  17
  •   Dominik Grabiec    12 年前

    如果我回忆正确,NULL在我使用的标题中的定义是不同的。对于C,它被定义为(空隙*)0,而对于C++,它定义为0。代码看起来像:

    #ifndef __cplusplus
    #define NULL (void*)0
    #else
    #define NULL 0
    #endif
    

    就我个人而言,我仍然使用NULL值来表示NULL指针,这使得使用指针而不是某个整数类型更为明确。是,在内部,空值仍然是0,但它没有这样表示。

    此外,我不依赖整数到布尔值的自动转换,而是显式地比较它们。

    if (pointer_value != NULL || integer_value == 0)
    

    而不是:

    if (pointer_value || !integer_value)
    

    只需说,在C++11中,这一切都得到了修正,人们可以简单地使用 nullptr 而不是 NULL ,以及 nullptr_t 那是一种 .

        8
  •  16
  •   nobody    10 年前

    我要说的是,历史已经证明了这一点,那些支持使用0(零)的人是错误的(包括比亚恩·斯特劳斯特鲁普)。支持0的论点主要是美学和“个人偏好”。

    在创建了C++11之后,一些编译器开始抱怨(使用默认参数)将0传递给带有指针参数的函数,因为0不是指针。

    如果代码是使用NULL编写的,那么可以通过代码库执行简单的搜索和替换,使其成为NULL ptr。如果您一直使用选择0作为指针编写的代码,那么更新它要繁琐得多。

        9
  •  11
  •   Jared Burrows    10 年前

    我曾经在一台机器上工作,其中0是一个有效地址,NULL被定义为一个特殊的八进制值。在该机器上(0!=NULL),因此

    char *p;
    
    ...
    
    if (p) { ... }
    

    不会像你期望的那样工作。你必须写作

    if (p != NULL) { ... }
    

    虽然我相信现在大多数编译器都将NULL定义为0,但我仍然记得几年前的教训:NULL不一定是0。

        10
  •  10
  •   Mark Ransom    16 年前

    我认为标准保证NULL==0,因此您可以选择其中之一。我更喜欢NULL,因为它记录了您的意图。

        11
  •  10
  •   jon hanson    11 年前

    我通常使用0。我不喜欢宏,而且也不能保证您使用的某些第三方头不会将NULL重新定义为奇怪的东西。

    您可以使用Scott Meyers和其他人提出的NulLPTR对象,直到C++获得NulLPTR关键字:

    const // It is a const object...
    class nullptr_t 
    {
    public:
        template<class T>
        operator T*() const // convertible to any type of null non-member pointer...
        { return 0; }
    
        template<class C, class T>
        operator T C::*() const   // or any type of null member pointer...
        { return 0; }
    
    private:
        void operator&() const;  // Can't take address of nullptr
    
    } nullptr = {};
    

    谷歌“nullptr”获取更多信息。

        12
  •  9
  •   Chris    10 年前

    然而,这并不意味着它们都是好的编程实践。考虑到性能没有差异,选择低级别感知选项而不是不可知/抽象选项是一种糟糕的编程实践。 帮助代码读者理解您的思维过程 .

    NULL、0、0.0、'\0',0x00和whatelse都转换为相同的内容,但在程序中是不同的逻辑实体。它们应该这样使用。NULL是指针,0是数量,0x0是位有趣的值等。无论指针是否编译,都不会将“\0”分配给指针。

    我知道一些社区鼓励通过打破环境合同来展示对环境的深入了解。然而,负责任的程序员会编写可维护的代码,并将这些实践排除在他们的代码之外。

        13
  •  5
  •   Michael Krelin - hacker    15 年前

    奇怪的是,没有人提到这一点,包括斯特劳斯特鲁。虽然谈论了很多关于标准和美学的问题,但没有人注意到这一点 危险的 使用 0 NULL sizeof(int) != sizeof(void*) . 像Stroustroup,我更喜欢 出于美学的原因,但必须小心不要在其类型可能模棱两可的地方使用它。

        14
  •  4
  •   Ðаn    15 年前

    尽可能避免使用C++引用来解决整个问题。而不是

    void foo(const Bar* pBar) { ... }
    

    你可能经常会写作

    void foo(const Bar& bar) { ... }
    

    当然,这并不总是有效的;但是空指针可能被过度使用。

        15
  •  3
  •   Rob    16 年前

    因为NULL不是语言的一部分,所以我更喜欢使用0。

        16
  •  3
  •   Jimmy    16 年前

    主要是个人偏好,尽管有人可能会提出NULL的论点,这使得对象很明显是一个指针,它当前不指向任何东西,例如。

    void *ptr = &something;
    /* lots o' code */
    ptr = NULL; // more obvious that it's a pointer and not being used
    

    IIRC,标准不要求NULL为0,因此使用<标准差速>可能对编译器来说是最好的。

        17
  •  3
  •   Michael Burr    16 年前

    我更喜欢使用NULL,因为它清楚地表明您的意图是值表示指针,而不是算术值。事实上,这是一个宏是不幸的,但由于它是如此广泛的根深蒂固,没有什么危险(除非有人做了一些真正愚蠢的事情)。我真希望从一开始它就是一个关键词,但是你能做什么呢?

    C++09将添加nullptr构造,我认为这是早就应该添加的。

        18
  •  1
  •   Gerald    16 年前

    我总是使用0。不是因为任何真正的思考原因,只是因为当我第一次学习C++时,我读了一些用0推荐的东西,我总是这样做。从理论上讲,可读性可能会有一个混乱的问题,但在实践中,我从未在数千工时和数百万行代码中遇到过这样的问题。正如斯特劳斯特鲁普所说,在标准成为nullptr之前,这实际上只是个人审美问题。

        19
  •  1
  •   Simon Hayter Simon Perepelitsa    11 年前

    有人告诉过我一次。。。我将把NULL重新定义为69。从那以后我就不用它了:P

    它使您的代码非常容易受到攻击。

    标准中并非所有内容都是完美的。宏NULL是一个实现定义的C++空指针常数,它与C NULL宏不完全兼容,除了隐式隐藏之外,它还将它转换成一个无用且容易出错的工具。

    告诉我下一个例子并不令人困惑:

    void foo(char *); 
    void foo(int); 
    foo(NULL); // calls int version instead of pointer version! 
    

    正因为如此,新标准中出现了std::nullptr\t

        20
  •  1
  •   Jan P    11 年前

    我主张尽可能不使用0或空指针。

    使用它们迟早会导致代码中出现分段错误。根据我的经验,C++中的指针是C++中错误的最大来源之一。

    此外,它还会导致代码中出现“if not null”语句。如果您可以始终依赖有效状态,则会更好。

    几乎总是有更好的选择。

        21
  •  -4
  •   Lehue    8 年前

    将指针设置为0并没有那么清楚。特别是如果你使用的是C++以外的语言。这包括C和Javascript。

    我最近研究了一些代码,如:

    virtual void DrawTo(BITMAP *buffer) =0;

    第一次使用纯虚函数。我以为这是一个星期的魔术。当我意识到它基本上只是将函数指针设置为 null (对于C++来说,虚拟函数在大多数情况下只是函数指针)我踢了自己一脚。

    virtual void DrawTo(BITMAP *buffer) =null;

    就像现在它使用小写的false和true一样。