在早期C++当它被栓上的C,你不能使用空,因为它被定义为 (void*)0.你不能分配空的任何指比其他 void*, ,这使得这种无用的。在那些日子,它被接受了,你使用 0 (zero)为空指针。

到这一天,我们继续使用零作为一个空的指针,但是这些围绕着我坚持使用 NULL.我个人没有看到任何利益给予一个名称(NULL)到现有的价值-因为我也想测试指针作为事实的价值观:

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

然后采用零使得更有意义(正如在如果你使用 NULL, 你不能从逻辑上使用 p && !q -你需要明确地对比 NULL, 除非你承担 NULL 是零,在这种情况下,为什么使用 NULL).

是否有任何客观理由喜欢过零NULL(反之亦然),或者只是个人喜好?

编辑:我应该补充(并意味着原来说),与RAII和例外情况,我很少使用零/NULL指针,但有时你需要他们。

有帮助吗?

解决方案

这是Stroustrup对此的看法: C ++ Style and Technique FAQ

  

在C ++中,NULL的定义是0,因此只有美学差异。我更喜欢避免宏,所以我使用0. nullptr的另一个问题是人们有时会错误地认为它与0不同和/或不是整数。在预标准代码中,有时被定义为不适合的东西,因此必须/必须避免。这些日子不太常见。

     

如果必须命名空指针,请将其命名为<=>;这就是它在C ++ 11中所称的内容。然后,<=>将是一个关键字。

那就是说,不要让小东西流汗。

其他提示

有一些论点(其中一个是相对较新的),我认为这与Bjarne的立场相矛盾。

  1. 意图文档
  2. 使用NULL允许搜索它的使用,它还突出显示开发人员想要使用int指针,无论编译器是否将其解释为0或不。

    1. 指针超载和'int'相对较少
    2. 每个人引用的例子是:

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

      但是,至少在我看来,上面的问题并不是我们对空指针常量使用NULL,而是我们有'foo'的重载,这些重载采用了不同类型的参数。该参数也必须是std::nullptr_t,因为任何其他类型都会导致模糊调用,因此生成有用的编译器警告。

      1. 分析工具今天可以提供帮助!
      2. 即使没有C ++ 0x,现在还有一些工具可以验证<=>是否用于指针,<=>用于整数类型。

        1. C ++ 11 将有一个新的<=>类型。
        2. 这是该表的最新参数。正在为C ++ 0x积极解决<=>和<=>的问题,并且您可以保证对于提供<=>的每个实现,他们将要做的第一件事是:

          #define NULL  nullptr
          

          对于那些使用<=>而不是<=>的人来说,改变将是类型安全的改进,很少或没有努力 - 如果有的话,它也可能会捕获一些他们使用<=>的错误<=>。对于任何今天使用<=>的人......呃......希望他们对正则表达式有很好的了解......

使用NULL。 NULL显示您的意图。它是0是一个无关紧要的实现细节。

我很久以前就停止了使用NULL(和大多数其他宏一样)。我这样做不仅是因为我想尽可能地避免使用宏,而且因为NULL似乎已经在C和C ++代码中被过度使用了。它似乎只在需要0值时使用,而不仅仅是指针。

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

static const int nullptr = 0;

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

我总是使用:

  • NULL 为指针
  • '\0' 对于字符
  • 0.0 对于浮动和双打

其中0会做得很好。这是一个问题的信号意图。这就是说,我没有肛门。

    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调用中,它们将使用NULL指针来指示参数列表的结尾。在这种情况下,使用“0”而不是NULL可能会导致问题。在64位平台上,va_arg调用需要一个64位指针,但是你只会传递一个32位整数。对我来说,就像你依赖其他32位为你清零一样?我已经看到某些编译器(例如Intel的icpc)并不那么优雅 - 这导致了运行时错误。

如果我没记错的话,在我使用的标题中定义的NULL不同。对于C,它定义为(void *)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也是<=>的类型。

我会说历史已经说过了,并且赞成使用0(零)的人是错的(包括Bjarne Stroustrup)。支持0的论据主要是美学和<!>“个人偏好<!>”。

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

如果代码是使用NULL编写的,则可以通过代码库执行简单的搜索和替换,以使其成为nullptr。如果您对使用0选择作为指针编写的代码感到困惑,那么更新它会更加繁琐。

如果你现在必须编写新的代码到C ++ 03标准(并且不能使用nullptr),你真的应该使用NULL。这将使您将来更容易更新。

我通常使用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 = {};

Google <!> quot; nullptr <!> quot;了解更多信息。

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

char *p;

...

if (p) { ... }

无法按预期工作。你必须写

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

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

我认为标准保证NULL == 0,所以你可以做到。我更喜欢NULL,因为它记录了你的意图。

使用0或NULL将产生相同的效果。

但是,这并不意味着它们都是良好的编程习惯。鉴于性能没有差异,在不可知/抽象替代方案上选择低级别感知选项是一种糟糕的编程习惯。 帮助您的代码读者理解您的思维过程

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

我知道有些社区鼓励通过破坏环境合同来展示对环境的深入了解。但是,负责任的程序员会制作可维护的代码,并将这些实践排除在代码之外。

奇怪,没有人,包括Stroustroup提到过。在谈论标准和美学时,没有人注意到在0中使用NULL代替是危险的,例如,在sizeof(int) != sizeof(void*)的架构上的变量参数列表中。就像Stroustroup一样,我更喜欢<=>出于美学原因,但是必须注意不要在类型可能不明确的地方使用它。

我尝试尽可能使用C ++引用来避免整个问题。而不是

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

你可能经常能够写

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

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

我和Stroustrup在这一个:-) 由于NULL不是语言的一部分,我更喜欢使用0。

主要是个人偏好,尽管有人可以提出NULL的论点,很明显该对象是一个当前没有指向任何东西的指针,例如。

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used
IIRC,标准不要求NULL为0,因此使用<!> lt; stddef.h <!> gt;中定义的内容;可能最适合您的编译器。

论证的另一个方面是你是否应该使用逻辑比较(隐式强制转换为bool)或明确检查NULL,但这也归结为可读性。

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

那就是说,我将指针用作真值本身没有问题。就像NULL一样,它是一个根深蒂固的习语。

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

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

有人告诉我一次......我要将NULL重新定义为69.从那时起我就不再使用它了:P

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

修改

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

NULL不会表现为空指针,而是表现为O / OL文字。

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

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

正因为如此,在新标准中出现了std :: nullptr_t

如果您不想等待新标准并且想要使用nullptr,请使用至少像Meyers建议的那样(请参阅jon.h评论)。

嗯,我认为尽可能不使用0或NULL指针。

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

也会导致<!>“if-not-null <!>”;代码中的语句。如果你可以完全依赖有效状态,那就更好了。

几乎总会有更好的选择。

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

我最近使用了一些代码:

virtual void DrawTo(BITMAP *buffer) =0;

第一次用于纯虚函数。我认为这是一个神奇的jiberjash一个星期。当我意识到它基本上只是将函数指针设置为null(因为虚函数在大多数情况下只是C ++的函数指针)我自己踢了。

virtual void DrawTo(BITMAP *buffer) =null;

如果没有与我的新眼睛适当的间隔,那么会比没有那种混乱更令人困惑。实际上,我想知道为什么C ++不使用小写<=>,就像它现在使用小写的假和真。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top