(Q.有点不对所以请检查正文) C float *q=NULL; printf("%f",q) ;输出是 0.000000 但在 C++ 中 float *q=nullptr;输出<<q;给输出0?

(Q. is little wrong So please check body) C float *q=NULL; printf("%f",q) ; output is 0.000000 but in C++ float *q=nullptr; cout<<q; give output 0?

[我的问题有点奇怪,但现在更改它是不对的,因为它有很好的解释,但我正在用[更新]编辑它......[更新结束] 标签以避免混淆我的 post]

即将到来的访问者

C

#include<stdio.h>
int main()
{
    float *q=NULL;
    
    printf("%f\n",q);
}

输出

0.000000

[更新] 但是你会填写我自己的问题的答案,我问了这么愚蠢的问题

基本上我很困惑,我觉得我必须打印一些浮点类型或空类型,但重点是我正在打印地址,所以使用 %f 来打印地址是愚蠢的。

明明q是float型指针只是我觉得完全错误

通常我们使用 %u 来打印任何类型变量(int、char、float)的地址,但是对于指针我们应该使用 %p

[更新结束]

C++

#include<iostream>
int main()
{
    float *q=nullptr;
    std::cout<<q;
}

输出

0

[更新]

C 和 C++ 标准都指定空指针常量比较等于零 - 它们没有说明该地址的内容。

显然 q 只是 float 类型的 nullptr

[更新结束]

因此,如果我的两个假设都是正确的,那么为什么在 C++ nullptr 中将其类型从 nullptr_t 更改为 float 类型,但在 C NULL 中并未将其类型从 (void ) 到 (浮动) ?

[更新]

我在第一个 C 示例中的第一个假设 q 是 (void*) 类型已经是错误的 和第二个假设在第二个例子中。 C++ 的 q 是 nullptr_t 也是错误的。

所以在这里总结一下

我正在尝试比较这是在 C 中发生的情况还是在 C++ 中发生的情况,我觉得这些事情相互矛盾

但实际上在 C 中我使用 %f 来打印第一个错误的指针地址。在 C++ 代码中,我认为一切都是正确的,除了一件事是假设空指针指向第 0 个内存块是错误的,因为它没有在 c 标准中指定它只是说 nullptr 常量在评估时与 0 比较。

问题中有很多错误,所以这不是正确的问题

[更新结束]

printf("%f\n",q);

格式说明符 %f 要求传递的对象类型为 double 类型(float 参数将被隐式转换,因此也可以)。您传递的 float* 是错误的类型。将错误类型的参数传递给 printf 会导致未定义的行为。

printf("%p",q);

这个有点微妙,但是 %p 说明符要求参数的类型是 void*float* 仍然是错误的类型,因此行为仍未定义。

您应该更加小心使用正确的格式说明符和参数类型。 C格式的I/OAPI很不宽容


In C++ give output 0

请注意,是否输出 0 或其他内容取决于系统使用什么值来表示空指针。

why in C++ nullptr changing it's type to float type from nullptr_t

nullptr 在您的示例中从未“将其类型更改为浮点类型”。在 float *q=nullptr 中,隐式转换为 float*.

类型

but in C NULL is not changing it's type from (void ) to (float) ?

NULL宏的类型不是C中的void,它可以是整型常量0,也可以是转换为void*的常量。这两者都可以隐式转换为任何指针类型。这就是 float *q=NULL.

中发生的事情

因此,在这两种语言中,您都将 null 隐式转换为指针类型。


无论哪些类型可以隐式转换为哪些类型,可变参数都不会隐式转换为格式字符串所需的类型,因为编译器不知道这些类型1 2.

1 我提到了从 float 到 double 的转换,但这些不依赖于格式说明符。

2 如果格式字符串是常量,一些编译器确实有助于诊断您的错误,但他们并不是必须这样做。

指针没有改变类型。在 cout 版本中,您让系统自然打印指针值。在 printf 版本中,您强制使用 %f。将格式字符串更改为 %ld,您将得到不同的结果。

printf 对您作为参数传递的内容一无所知。它相信程序员知道他在做什么。

--- 在这里编辑以回答更多问题---

你说得对,%lu 可能比 %ld 好。我想您可能有一个设置了最高有效位的地址(这意味着 %ld 会认为它是负数)。

是:

float * q = nullptr;

表示 q 为全零。

Cout 知道正在打印什么并且(通常)做正确的事情。很少使用格式说明符,除非你非常具体地控制它(比如打印浮点数和双精度数时使用的位数)。我用它来设置 bools 的默认输出以打印 truefalse 而不是 10。但一般来说,使用 cout 时您会获得合理的值,而无需任何额外的工作或认为有必要。