【问题标题】:Is there a difference between initialiazing variables and pointers with NULL or 0?用 NULL 或 0 初始化变量和指针之间有区别吗?
【发布时间】:2016-04-17 16:49:26
【问题描述】:

以下哪种方法是更正确的初始化变量的方法?

int x = 0;
int x = NULL;

指针呢?有人告诉我关于NULL 的一些不和谐的事情,比如:“NULL 最适合初始化指针”或“不要使用NULL,而是使用 0 来初始化变量”等等……现在,我继续阅读NULL 等于 0 的互联网,我自己测试过。那么有什么意义呢?为什么有些人说使用 NULL 不是一个好的选择?有什么我遗漏的吗?

【问题讨论】:

  • NULL 不等于 0
  • @iharob 你说if ( 0 == NULL )不是真的?
  • 我说的不是这个,不一定是0
  • @wallyk: Yes true - N1570, 6.3.2.3/3 和脚注 66。空指针 constant(定义为 NULL)总是零值。翻译后,对应的空指针value可能是零值,也可能不是零值。
  • @ClaudioCortese:来自 C 标准 (C11 n1570):“参数应为指向 void 的指针。指针的值被转换为打印字符序列,在实现中-定义的方式。” (强调我的)。仅供参考:NIL 表示“不在列表中”。对于像 LISP(“ListProcessing”)这样的基于列表的语言,名称会立即变得清晰。请注意,这些库可能不仅被 C 或 C++ 语言使用,而且还被例如 C 或 C++ 语言使用。通过 Pascal 程序。一些库可能只打印值,例如0x0,其他例如(null)。 AFAIK none 打印大写 NULL - 可能有充分的理由。

标签: c variables pointers initialization null-pointer


【解决方案1】:

NULL 是一个指针常量。您可以使用它来初始化一个指向一个值的指针,该值表示它不指向任何东西。

在大多数 C 实现中,它被定义为:

#define NULL ((void *)0)

但不能保证这一点。

【讨论】:

  • 也许这就是为什么很多人告诉我使用 NULL 不是一个好主意的原因?这可以解释我的奥秘
  • @ClaudioCortese 没错。在实践中,它们通常是相同的,但是如果您依赖这种行为,然后将代码移动到没有这种行为的平台上,您就会遇到各种问题。
  • @ClaudioCortese 对。始终使您的代码可移植,除非您有非常具体的理由不这样做。
  • @ClaudioCortese 不,您总是用 NULL 初始化指针,即 int *pointer = NULL
  • 正如我之前提到的,NULL通常为 0,但并非总是如此。所以总是使用 NULL 作为指针。
【解决方案2】:

以下哪种方法是更正确的初始化变量的方法?

// int x = NULL;  `NULL` implies pointer
int x = 0;        // 0 implies integer value and x is an integer.

指针呢?

void *p = NULL;  // `NULL` implies pointer and p is a pointer.
//void *p = 0;   // 0 implies integer value

NULL 等于 0

它的值相等,但可能不是位模式。见下文+0.0, -0.0 示例。


如果NULL 总是等于 0,那么在 C 中就不需要它了。

NULLa 空指针辅音 - 它经常,但并不总是具有零位模式。具有NULL 值的指针将始终与0 进行同等比较:相同的值,不同的位模式。

请记住,== 比较的是值,而不是位模式。

void *a = NULL;
if (a == NULL) Always_True();
if (a == 0) Always_True();

可能有帮助的示例。 +0.0-0.0 具有相同的值、相同的类型,但位模式不同。指针也可能发生类似的情况。

int main(void) {
  double pz = +0.0;
  double nz = -0.0;
  printf("=:%d  bits:%d\n", pz == nz, memcmp(&pz, &nz, sizeof pz) == 0);  // =:1  bits:0
  return 0;
}

【讨论】:

    【解决方案3】:

    NULL 是一个空指针常量。您应该使用它来初始化指针类型。

    来自C11,第 7.19 章,stddef.h

    NULL
    它扩展为实现定义的空指针常量。

    对于 C 中的 空指针常量,第 6.3.2.3 章

    具有值0 的整数常量表达式,或转换为类型的此类表达式 void *,被称为空指针常量。[...]

    所以,类型是指针的类型。

    对于其他非指针变量,您应该使用 0。

    【讨论】:

    • 这背后有真正的原因还是只是“个人喜好”?
    • @ClaudioCortese 哪一个是个人喜好?类型很重要。也许在大多数情况下,实现是等效的,但它只是不相同。希望很清楚。 :)
    • 我的意思是,如果 NULL == 0,为什么可以用 NULL 初始化指针,为什么不能用 NULL 初始化变量?
    • @ClaudioCortese 最有可能 NULL == 0,但这并不能保证。请注意我回答中的 "implementation-defined" 部分。
    【解决方案4】:

    不要使用NULL 来初始化非指针类型,因为它可能扩展为(void *) 0 之类的东西,具体取决于实现。对整数类型使用普通的0(或计算结果为普通0 的宏或const 限定变量)。

    【讨论】:

      【解决方案5】:

      在初始化(或比较)指针时一定要使用NULL;风格不错。

      在处理整数时绝对不要使用 NULL;它的风格很差(而且很可能不起作用。)

      不要听任何人建议你不应该将NULL 与指针一起使用;他们可能很困惑。

      有关更多信息,请参阅http://c-faq.com/null/index.html 的 C 常见问题解答列表。

      【讨论】:

        【解决方案6】:

        理论上NULL 可以是指向不同于0 的地址的指针。但在实践中,这样的定义会导致大部分软件崩溃。在 99.99% 的情况下,它是 0(或 (void *)0)。

        【讨论】:

          【解决方案7】:

          部署了一些架构,其 NULL 为零:Prime 50、Honeywell-Bull、CDC Cyber​​ 180 系列等。在这些情况下,NULL 绝对不能与零互换。

          有关受影响机器的详细信息,请参阅 this answer 另一个问题。

          【讨论】:

          • 我们说的是空指针constant还是空指针value?就 C 而言,空指针常量总是为零值。
          • @JohnBode:是的,区分NULL(宏)、空指针空指针常量总是一个好主意>.
          • 切中要害:wallyk 的回答具有误导性; NULL 通常被定义为 0 even on 那些空指针不是 0 的巴洛克式旧机器的某个版本。请参阅 C 常见问题解答列表,问题 5.5。
          猜你喜欢
          • 1970-01-01
          • 2018-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-23
          • 1970-01-01
          • 2013-11-10
          相关资源
          最近更新 更多