移植的 c header 中的 NULL 与 nullptr

NULL vs nullptr in a ported c header

我在我的代码中使用 std::getenv 调用,我不确定这三个选择 -

const char *env_p = std::getenv("SOME_ENV");

if(env_p == NULL){
    std::cout << "NULL caught";
}

if(env_p == 0){
    std::cout << "0 caught";
}

if(env_p == nullptr){
    std::cout <<"nullptr caught";
}

我应该使用其中的哪一个?我更倾向于 nullptr 版本,因为 c++ 推荐它,但由于 cstdlib 最初是一个 c header,我不确定检查 NULL0nullptr.

我 运行 一个要检查的程序,所有三个程序都被捕获,因为没有具有上述名称的环境变量。所以这让我可以选择使用其中任何一个,甚至 if(!env_p) 对吧?

但我不太确定,因为这可能仅适用于此示例或依赖于机器或我可能缺少的东西。所以有人可以确认这个案例吗?

谢谢

简答:它们都是一样的,可以互换使用。

稍长的回答:

std::getenv returns 如果失败,一个 NULL 指针:

Character string identifying the value of the environmental variable or null pointer if such variable is not found.

如果你想检查函数是否失败,你可以使用其中之一:

  • if (env_p == NULL) 定义为 0 (#define NULL 0)
  • if (env_p == 0)也是一样
  • if (env_p == nullptr) 是一种 C++ 方式 - 安全(只能与指针进行比较)
  • env_pfalse时,
  • if (!env_p)只是true,所以和检查env_p == 0
  • 是一样的

如果您使用的是现代 C++,我会坚持使用 nullptr

在你的情况下,它们都是一样的。空指针是一个具有魔法值的指针,不会匹配任何指向实际数据的指针。通常,我们将其视为地址 0,大多数实现实际上使用地址 0 来表示空指针,但这是一个实现细节。

if (env_p == 0)

此文字 0 正在与指针进行比较,因此编译器会将其转换为指针。转换为指针的文字零会导致空指针,因为标准是这样说的。

if (env_p == NULL)

这实际上是同一件事,因为在几乎所有实现中,NULL 是定义为 0 的宏。 (有一段时间,C 将 NULL 定义为 (void*)0 并不少见,但由于此处不重要的原因,这种做法不再流行。)

if (env_p == nullptr)

nullptr 是一个 C++ 关键字,它为您提供具有特殊类型的空指针。但它仍然只是一个空指针,所以它完全符合你的要求。

在 C++ 中有一些情况(比如完美转发),你必须使用 nullptr 而不是 NULL0 来保证你有一个空指针(而不是一个 int恰好是 0) 为了确保类型推导选择写入模板实例化或重载。

最后,检查指针的常用习语是:

if (env_p) { ... } // true if not a null pointer
if (!env_p) { ... } // true if a null pointer

之所以有效,是因为存在不等式与 0 的隐式比较。也就是说,它们的处理方式与您编写的完全一样:

if ((env_p) != 0) { ... }
if ((!env_p) != 0) { ... }

由于上述原因,它起作用了。

在 C++ 中,我使用 nullptr 作为空指针。在 C 或可以在任一模式下编译的代码中,我通常使用 NULL 因为它比使用 0.

的意图更清晰一点