【问题标题】:Two equality comparisons with NULL in CC中与NULL的两个相等比较
【发布时间】:2012-03-03 05:12:10
【问题描述】:

这是关于在将 C++ 中的指针与 NULL 进行比较时的一个小混淆。 这是代码:

struct node
{
  int data;
  struct node *left;
  struct node *right;
}
int main()
{
  struct node *p;
  if(p!= NULL)
     printf("line1\n");
   else
     printf("line2\n");
   struct node *temp;
   if(temp == NULL)
     printf("line3\n");
} 

输出:

line2
line3

而对于下面的一段代码:

struct node
{
  int data;
  struct node *left;
  struct node *right;
}
int main()
{
  struct node *p;
  if(p!= NULL)
     printf("line1\n");
   else
     printf("line2\n");
   struct node *temp;
} 

这是输出:

line1

谁能解释一下发生这种情况的原因?

【问题讨论】:

  • 我会编辑您的代码,但它充满了 HTML,我没有 10 分钟的时间来摆脱它。要格式化代码,只需将其缩进四个空格。
  • 您的代码无法编译。对于printf,您需要#include <stdio.h>,对于NULL,您需要#include <stddef.h>,并且您在结构定义中缺少分号。几乎总是最好复制并粘贴您的实际代码。
  • @Keith:实际上<stdio.h> 也定义了NULL 宏。
  • @KeithThompson:我大体上同意,但对于这个示例,我认为我们可以放心地假设任何回答这个问题的人都会熟悉printfNULL

标签: c pointers null null-pointer


【解决方案1】:

你声明了一个指针,但你没有初始化它。它可以采用 any 值,即不保证为 NULL。当然,它可能NULL (0),但同样不能指望它。

未初始化变量的值是不确定的,除非它具有静态存储持续时间。

【讨论】:

    【解决方案2】:

    您需要提供 ptemp 值 - 因为您没有它们可以包含任何内容。

    【讨论】:

      【解决方案3】:

      您正在读取一个未初始化的变量。那是未定义的行为。基本上,任何事情都可能发生。如果您打开编译器警告,编译器会准确地告诉您。

      我怀疑你相信你的局部变量会被自动初始化。事实并非如此。您必须在读取它们之前对其进行初始化。

      【讨论】:

      • 我在这里没有看到任何 UB。他并没有取消对指针的引用,只是读取指针变量本身的(未初始化的)值,这不是UB。
      • @EdS。请参阅此处的第 10 项:securecoding.cert.org/confluence/display/seccode/…
      • @EdS。标准是这样说的:“如果左值指定了一个可以用寄存器存储类声明的具有自动存储持续时间的对象(从未使用过它的地址),并且该对象未初始化(未使用初始化程序声明并且没有分配给它已在使用前执行),行为未定义。”
      • 哦,哇,我不知道,谢谢。我想我是从实际经验中说的,而不是标准的话。我知道该标准确实将其价值定义为不确定的,我只是不知道阅读它在技术上是 UB。再次感谢,学到了一些新东西 +1。
      【解决方案4】:

      auto 变量(即未声明 static 的局部变量)如 ptemp 未初始化,因此它们的值是不确定的(本质上,无论从以前的操作,它可能是也可能不是给定类型的有效值)。切勿尝试取消引用未初始化的指针。

      在文件范围(任何功能块之外)或使用static 关键字声明的变量初始化如下:

      • 指针被初始化为NULL;
      • 算术类型(整数或浮点数)初始化为 0
      • 结构体按照前面两条规则递归初始化
      • 联合根据前两条规则递归初始化其第一个命名成员

      如果将p的声明改为

      static struct node *p;
      

      然后p 将被初始化为 NULL。如果您想将p 声明为static,那么您必须将其初始化为声明的一部分:

      struct node *p = NULL;
      

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2012-02-09
        • 2013-08-18
        • 2015-10-26
        • 2011-05-05
        • 1970-01-01
        • 2021-09-14
        • 2010-12-05
        • 2016-03-06
        相关资源
        最近更新 更多