【问题标题】:Null pointer in C++C++中的空指针
【发布时间】:2011-11-24 17:14:18
【问题描述】:

当我在 C++ 中声明一个空指针为int* p=0 时,这是否意味着零是整数指针类型的某个特殊常量,还是意味着p 指向地址0x0? 当然,0x0 必须是一个特殊的地址,C++ 在分配变量/数组的过程中永远不会触及该地址。

【问题讨论】:

    标签: c++ pointers


    【解决方案1】:

    C++ 标准定义整数常量 0 转换为空指针。 这并不意味着空指针指向地址 0x0。它只是意味着文本'0'在转换为指针时会变成空指针。

    当然,使空指针具有0x0 以外的表示是相当复杂的,因此大多数编译器只是让0x0 成为空指针地址,并确保没有任何内容被分配为零。

    请注意,使用这种零转换被认为是不好的风格。使用NULL(这是一个定义为00L 或其他零整数常量的预处理器宏),或者,如果您的编译器足够新,可以支持它,则使用nullptr

    【讨论】:

    • 使用零并不被一致认为是不好的风格。有些人认为宏版本更糟糕。
    • @Paul 宏并不漂亮,但在这种情况下,我同意应该使用 NULL 而不是 0。假设您切换/升级到支持 nullptr 的编译器。现在哪一个更容易 - 用nullptr 搜索和替换0NULL 的所有实例?
    • @Paul,我觉得零读起来有点含糊不清。尽管 NULL 也有缺点,它可以隐藏重载问题。但我想我们都同意nullptr 是最好的:)
    • @Praetorian 我并不是在争论 NULL 是好是坏。我刚才说这个问题没有解决,所以不应该这样描述。希望nullptr 能够结束“争议”。
    【解决方案2】:

    表示一个值为0的整型常量表达式在C++中有特殊含义;它被称为空指针常量。当您使用这样的表达式来初始化指针或分配给指针时,实现会确保指针包含适当类型的 空指针值。这保证与指向真实对象的任何指针的值不同。它可能有也可能没有“零”表示。

    ISO/IEC 14882:2011 4.10 [conv.ptr] / 1:

    空指针常量是整数类型的整数常量表达式 (5.19) 纯右值,其计算结果为零或std::nullptr_t 类型的纯右值。空指针常量可以转换为指针类型;结果是该类型的 空指针值,并且可以与对象指针或函数指针类型的所有其他值区分开来。

    【讨论】:

      【解决方案3】:

      这是一个特殊值,按照标准,它保证永远不会等于指向对象或函数的指针。地址运算符& 永远不会产生空指针,也不会产生任何成功的动态内存分配。您不应将其视为地址 0,而应将其视为指示指针无处指向的特殊值。为此目的有一个宏NULL,新的成语是nullptr

      【讨论】:

        【解决方案4】:

        这意味着它没有指向任何东西。

        【讨论】:

          【解决方案5】:

          指针的值只是0。并不一定意味着它指向地址0x0。 NULL 宏只是一个 0 常量。

          【讨论】:

            【解决方案6】:

            指针指向地址 0。在大多数平台上这很特别,但你应该使用NULL,因为它并不总是0(但很常见)。

            【讨论】:

              【解决方案7】:

              是的。零是一个特殊的常数。事实上,它是唯一可以在这样的语句中使用的整数常量,而无需使用显式转换:

              int *pi = 0;  //ok
              char *pc = 0; //ok
              void *pv = 0; //ok
              A *pa = 0;    //ok
              

              一切都可以编译。

              但是,如果你改用这个:

              int *pi = 1;  //error
              char *pc = 2; //error
              void *pv = 3; //error
              A *pa = 4;    //error
              

              都会给出编译错误。

              在 C++11 中,当你的意思是空指针时,你应该使用 nullptr,而不是 0

              【讨论】:

                【解决方案8】:

                在您的示例中,“p”是 int 的地址。通过将 p 设置为 0,您是说地址 0 处有一个 int。约定是 0 是“不是有效的地址地址”,但它只是一个约定。

                在实践中,地址 0 通常是“未映射的”(即没有支持该地址的内存),因此您将在该地址处遇到错误。但在某些嵌入式系统中并非如此。

                您也可以选择任何随机地址(例如 0xffff7777 或任何其他值)作为“空”地址,但您会违反惯例并使许多阅读您的代码的人感到困惑。通常使用零,因为大多数语言都支持有效地测试 is-zero is-not-zero。

                查看这个相关问题:Why is address zero used for the null pointer?

                【讨论】:

                  猜你喜欢
                  • 2011-09-17
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-07-14
                  • 2011-07-04
                  相关资源
                  最近更新 更多