【问题标题】:printing pointer value NULL打印指针值 NULL
【发布时间】:2019-08-06 10:02:13
【问题描述】:

为什么我不能打印值为 NULL 的指针? 这是我的代码:

#include <stdio.h>
int main(void)
{
    int * p = 0;

    printf("%p %p ", p, *p);

    getchar();
    return 0;
}

错误是:“抛出异常:读取访问冲突。 p 是 nullptr。” 我想了解错误...

【问题讨论】:

  • p 的值为 NULL,p 的类型为int *int 指针),指针本身将以%p 格式打印。但是*p 正在尝试访问(取消引用)地址 NULL。这很糟糕,因为 NULL 不是有效地址。你为什么要打印*p%p*p 的类型是 int
  • 因为你不能取消引用一个无效的指针,这是一个未定义的行为
  • 也应该是"%p %d "而不是"%p %p ",第二个参数是和int,而不是int*

标签: c visual-studio pointers null


【解决方案1】:

pNULL,这是一个 无效 指针值 - 该地址没有对象。 printf 调用中的表达式*p 尝试取消引用该无效指针,这样做的行为是未定义。在这种特殊情况下,它会导致您的代码崩溃。

记住声明

int * p = 0;

创建一个类型为“指向int”的对象(* 仅用于指示类型),并将该指针对象的值初始化为0NULL)。 根据定义p 不指向任何对象或函数,因此表达式*p 没有意义。

更不用说,表达式*p的类型是int,所以你会使用%d来打印它,而不是%p

注意 - 有一个空指针 constant 和一个空指针 value。指针上下文中的零值常量表达式(例如0(void*) 0)是一个空指针constantNULL 宏)。在翻译过程中,该空指针constant 被转换为一个空指针value,它可能是也可能不是0。空指针值只是一些定义明确的地址值,它保证与任何对象或函数的地址比较不相等。

【讨论】:

  • 有点语义,但我认为NULL(或者更确切地说是一个空指针值)是一个有效指针值。但是对空指针值允许的操作是有限的。
  • @IanAbbott: 6.5.3.3, 脚注 102: "...在由一元 * 运算符取消引用指针的无效值中,有一个空指针,一个地址与指向的对象,以及对象在其生命周期结束后的地址。” NULL 按定义 不指向任何东西,因此试图取消引用它会导致未定义的行为,因此它是一个无效的指针值。这是一个定义明确的无效指针值,但仍然无效。
  • 值是否有效取决于上下文。例如,浮点值 1.1 在可以使用浮点值的许多情况下都是有效的,但不是全部; (例如,作为acos函数的参数无效)。
【解决方案2】:

指针指向一个变量。试试这个:

#include <stdio.h>
int main(void)
{

    int a = 0;
    int * p = &a;

    printf("%p %p ", p, *p);

    getchar();
    return 0;
}

【讨论】:

  • 您的printf 调用将调用未定义的行为。
  • 它应该是"%p %d ",因为*p是一个int。严格来说,printf的第二个参数应该是(void *)p,而不是p(这是一个@987654329 @)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-10
  • 2013-12-02
相关资源
最近更新 更多