【问题标题】:Understanding null pointers in C理解 C 中的空指针
【发布时间】:2015-10-06 19:05:04
【问题描述】:

所以想象一下我有这个

main() {
    int a = 5;
    int *p;
    printf("p: %d", (void*)p);
}

为什么我必须在 printf 语句中强制转换 *p?但如果我这样做......

p = &a;
printf("p: %d", *p);

这次我不用投了?

所以我的问题是我是否需要每次都将 void 转换为空指针?

【问题讨论】:

  • 我对 C 生疏了,但我要试一试,说因为你用 p= &p; 语句隐式初始化了指针?
  • 我的意思是 p = &a;
  • 要打印指针的地址,您应该使用 %p 而不是 %d%p 格式需要转换 (void *)
  • 您可能想阅读void 类型、如何定义指针、解引用运算符*printf() 以及它的转换说明符,如果那时任何问题仍然存在,请随时回来。选角也可能是您的兴趣所在。
  • 顺便说一句,我在你的问题中没有看到任何空指针。

标签: c pointers


【解决方案1】:

在第一个示例中,您正在打印指针本身的值,但使用了错误的格式说明符。

printf("p: %d", (void*)p);

应该是

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

原因是,%d 指定的 int 可能与指针大小不同。强制转换的原因是因为%p 打印了void* 指针的值。但请注意:在您的示例中,int *p 未初始化,因此打印其值是无用的。

在第二个示例中,您正在打印指针指向的值,并且不需要强制转换,因为类型是一致的。

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

【讨论】:

  • 我想要的是存储在内存中的内容..而不是内存地址。我正在尝试取消引用它...你是说我不能取消引用空指针?
  • @YusufJama 是的。 void* 指针指向一个不确定的对象,因此您不能取消引用它。诸如malloc() 之类的函数返回一个void* 指针,以便可以将其分配给任何数据类型。但相反,printf 使用格式规范 %p 需要一个 void* 指针,根据定义。
  • 如果指针设置为p = &a怎么办?为什么我不需要演员阵容?
  • "Deferencing" 一个指针正在获取它指向的东西。如果它没有指向任何东西(由于是 void * 类型或具有 NULL 值),那么您无法获取不存在的内容。
  • @YusufJama 正如解释的那样,如果您使用的是int,则所有类型都是一致的,不需要强制转换。但是要打印指针地址值本身,它必须被转换为void*,尽管您可能“侥幸”不这样做,或者使用不同的格式说明符,这样可能“有效” " 在你的平台上,很高兴,但不是设计使然。
【解决方案2】:

要打印出指针值(NULL 或其他),您必须使用 %p 转换说明符,它期望其对应参数的类型为 void *

printf("p = %p\n", (void *) p );  

这可能是 C 语言中唯一一次需要显式将指针值强制转换为void *(如果它还不是void *,无论如何)。原因是 printf 如何读取其参数、可变参数函数中的默认类型提升以及其他一些我尚未弄清楚如何解释的事情的组合。

请注意,您正在转换p(指针)的值,而不是它指向的东西。

在第二个打印语句中,

printf("*p = %d\n", *p );

您正在打印p 指向的事物的值,它是一个整数。 表达式 *p 的类型为int,这是%d 转换说明符所期望的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    相关资源
    最近更新 更多