简体   繁体   English

(Q. 有点错误所以请检查正文) C float *q=NULL; printf(“%f”,q); output 为 0.000000 但在 C++ 中 float *q=nullptr; cout&lt; <q; give output 0?< div><div id="text_translate"><p> <strong>[我的问题有点奇怪,但现在更改它是不对的,因为它得到了很好的解释,但我正在使用 [Update].......[Update End] 标签对其进行编辑,以避免对即将访问我的访问者造成混淆邮政]</strong></p><p> <strong>C</strong></p><pre> #include&lt;stdio.h&gt; int main() { float *q=NULL; printf("%f\n",q); }</pre><p> <strong>OUTPUT</strong></p><pre> 0.000000</pre><ul><li> 在 C output 为 0.000000</li><li> 所以这里 q 是浮点型 null 指针还是 q 是 (void *) 类型 null 指针?</li><li> 我觉得它是 (void *) 类型。</li><li> 因此格式(%f)和参数(void *)不匹配会调用未定义的行为并导致此类错误类型output</li></ul><p> <strong>[更新]</strong><strong>但是你会回答我自己的问题,我问的这么愚蠢的问题</strong></p><p>基本上我很困惑,我觉得我必须打印一些浮点类型或 void 类型,但关键是我正在打印地址,所以使用 %f 来打印地址只是愚蠢的。</p><p> 显然 q 是浮点型指针,只是我觉得完全错误</p><p>通常我们使用 %u 来打印任何类型变量的地址(int,char,float)但是对于指针我们应该使用 %p</p><p> <strong>[更新结束]</strong></p><p> <strong>C++</strong></p><pre> #include&lt;iostream&gt; int main() { float *q=nullptr; std::cout&lt;&lt;q; }</pre><p> <strong>OUTPUT</strong></p><pre> 0</pre><ul><li> 在 C++ 中给出 output 0</li><li> 我认为这很好,因为它将第一个 memory 块的地址指向任何内容</li><li>如果 q 是 nullptr_t 类型,那么 C++11 应该给出歧义错误意味着这里 q 是浮点类型 nullptr。</li></ul><p> <strong>[更新]</strong></p><p> C 和 C++ 标准都指定 null 指针常量比较等于零 - 他们没有说明该地址的内容。</p><p> 显然 q 只是浮点类型 nullptr</p><p> <strong>[更新结束]</strong></p><p> <strong>因此,如果我的两个假设都是正确的,那么为什么在 C++ nullptr 中将其类型从 nullptr_t 更改为浮点类型,但在 C NULL 中将其类型更改为(void <em>)</em>不更改</strong>?</p><p> <strong>[更新]</strong></p><p> 我在 C 的第一个示例中的第一个假设 q 是 (void*) 类型已经是错误的,第二个假设是在第二个例子中。 C++ 的 q 是 nullptr_t 也是错误的。</p><p> 所以在这里总结一下</p><p>我试图比较这发生在 C 和这发生在 c++ 我觉得这些事情是相互矛盾的</p><p>但实际上,在 C 中,我使用 %f 打印第一个错误的指针地址。 In C++ code all I think is all right except One thing that it is wrong to assume that null pointer points to 1st block of memory which is 0th as it is not specify in c standard it just say that nullptr constant compares to 0 when evaluate.</p><p> 这么多的错误只是问题,所以这不是正确的问题</p><p> <strong>[更新结束]</strong></p></div></q;>

[英](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?

[My Question is little weird but it's not right to change it now as it is answered with good explanation but I am Editing it with [Update].......[Update End] tag to avoid confusion to upcoming visitors to my post] [我的问题有点奇怪,但现在更改它是不对的,因为它得到了很好的解释,但我正在使用 [Update].......[Update End] 标签对其进行编辑,以避免对即将访问我的访问者造成混淆邮政]

C C

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

OUTPUT OUTPUT

0.000000
  • In C output is 0.000000在 C output 为 0.000000
  • so here q is float type null pointer or still q is (void *) type null pointer?所以这里 q 是浮点型 null 指针还是 q 是 (void *) 类型 null 指针?
  • I feel it is (void *) type.我觉得它是 (void *) 类型。
  • so mismatch in format(%f) and argument(void*) invoke undefined behaviour and lead to such error type output因此格式(%f)和参数(void *)不匹配会调用未定义的行为并导致此类错误类型output

[Update] But you will fill answer to my own Question such stupid Question I asked [更新]但是你会回答我自己的问题,我问的这么愚蠢的问题

basically I am confused that I feel I have to print something float type or void type but point is I am printing address and so it just foolish to use %f to use to print address.基本上我很困惑,我觉得我必须打印一些浮点类型或 void 类型,但关键是我正在打印地址,所以使用 %f 来打印地址只是愚蠢的。

Obviously q is float type pointer only what I feel is totally wrong显然 q 是浮点型指针,只是我觉得完全错误

generally we use %u to print address of any type of variable(int,char,float) but for pointer we should use %p通常我们使用 %u 来打印任何类型变量的地址(int,char,float)但是对于指针我们应该使用 %p

[Update End] [更新结束]

C++ C++

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

OUTPUT OUTPUT

0
  • In C++ give output 0在 C++ 中给出 output 0
  • I think it's fine as it give address of 1st memory block as pointing to nothing我认为这很好,因为它将第一个 memory 块的地址指向任何内容
  • and if q is nullptr_t type then C++11 should give ambugity error means here q is float type nullptr.如果 q 是 nullptr_t 类型,那么 C++11 应该给出歧义错误意味着这里 q 是浮点类型 nullptr。

[Update] [更新]

The C and C++ standards both specify that a null pointer constant compares equal to zero - they say nothing about what is at that address. C 和 C++ 标准都指定 null 指针常量比较等于零 - 他们没有说明该地址的内容。

obviously q is float type nullptr only显然 q 只是浮点类型 nullptr

[Update End] [更新结束]

So if my both assumptions are correct then why in C++ nullptr changing it's type to float type from nullptr_t but in C NULL is not changing it's type from (void ) to (float ) ?因此,如果我的两个假设都是正确的,那么为什么在 C++ nullptr 中将其类型从 nullptr_t 更改为浮点类型,但在 C NULL 中将其类型更改为(void 不更改

[Update] [更新]

My first assumption in 1st example of C that q is (void*) type is already wrong and 2nd Assumption that in 2nd ex.我在 C 的第一个示例中的第一个假设 q 是 (void*) 类型已经是错误的,第二个假设是在第二个例子中。 of C++ that q is nullptr_t is also wrong. C++ 的 q 是 nullptr_t 也是错误的。

So Summarize all here所以在这里总结一下

I am trying to compare that this is happening in C and this is happening in c++ and I feel these things are contradict to each other我试图比较这发生在 C 和这发生在 c++ 我觉得这些事情是相互矛盾的

but in reality while in C I am using %f to print address of pointer that's first mistake.但实际上,在 C 中,我使用 %f 打印第一个错误的指针地址。 In C++ code all I think is all right except One thing that it is wrong to assume that null pointer points to 1st block of memory which is 0th as it is not specify in c standard it just say that nullptr constant compares to 0 when evaluate. In C++ code all I think is all right except One thing that it is wrong to assume that null pointer points to 1st block of memory which is 0th as it is not specify in c standard it just say that nullptr constant compares to 0 when evaluate.

so tons of mistake in question only so it is not proper question这么多的错误只是问题,所以这不是正确的问题

[Update End] [更新结束]

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

The format specifier %f requires that the type of the passed object is of type double ( float argument will be converted implicitly, so that is OK too).格式说明符 %f 要求传递的 object 的类型是double类型( float参数将被隐式转换,所以也可以)。 You passed a float* which is the wrong type.您传递了一个错误类型的float* Passing argument of wrong type into printf results in undefined behaviour.将错误类型的参数传递给printf会导致未定义的行为。

 printf("%p",q);

This one is a bit more subtle, but %p specifier requires the type of the argument to be void* .这个有点微妙,但是 %p 说明符要求参数的类型是void* float* is still the wrong type, so behaviour is still undefined. float*仍然是错误的类型,因此行为仍未定义。

You should be more careful about using the correct format specifier and type of argument.您应该更加小心使用正确的格式说明符和参数类型。 The C formatted I/O API is very unforgiving. C 格式化的 I/O API 是非常无情的。


In C++ give output 0在 C++ 中给出 output 0

Note that whether you get output of 0 or something else depends on what value the system uses to represent the null pointer.请注意,您获得的 output 是否为 0 或其他值取决于系统用于表示 null 指针的值。

why in C++ nullptr changing it's type to float type from nullptr_t为什么在 C++ nullptr 将其类型从 nullptr_t 更改为浮点类型

nullptr never "changed its type to float type" in your example.在您的示例中, nullptr从未“将其类型更改为浮点类型”。 In float *q=nullptr , the implicit conversion is to the type float* .float *q=nullptr中,隐式转换为float*类型。

but in C NULL is not changing it's type from (void ) to (float)?但是在 C NULL 中没有将其类型从 (void ) 更改为 (float)?

Type of the NULL macro is not void in C. NULL宏的类型在 C 中不void It can be an integer constant 0, or such constant converted to void* .它可以是 integer 常量 0,或者转换为void*的常量。 Both of those could be implicitly converted to any pointer type.这两者都可以隐式转换为任何指针类型。 That's what happens in float *q=NULL .这就是float *q=NULL中发生的情况。

So, in both languages you implicitly converted null to a pointer type.因此,在这两种语言中,您都将 null 隐式转换为指针类型。


Regardless of what types can be implicitly converted to which types, variadic arguments are not implicitly converted to the types required by the format string because those types are unknown to the compiler 1 2 .无论哪种类型可以隐式转换为哪种类型,可变参数 arguments 都不会隐式转换为格式字符串所需的类型,因为编译器不知道这些类型1 2

1 There are conversions such as from float to double that I mentioned, but those are not dependent on the format specifiers. 1 我提到了从 float 到 double 的转换,但这些转换不依赖于格式说明符。

2 If the format string is constant, some compilers do helpfully diagnose your mistakes, but they aren't required to do so. 2 如果格式字符串是常量,一些编译器确实有助于诊断您的错误,但它们不是必须这样做的。

The pointer isn't changing type.指针没有改变类型。 In the cout version, you're letting the system print the pointer value natural.在 cout 版本中,您让系统自然打印指针值。 In the printf version you're forcing a %f.在 printf 版本中,您强制使用 %f。 Change the format string to %ld and you'll get different results.将格式字符串更改为 %ld,您将得到不同的结果。

printf doesn't know a thing about what you're passing as arguments. printf 对您传递的 arguments 一无所知。 It trusts the programmer knows what he's doing.它相信程序员知道他在做什么。

--- Edit here to answer more questions --- --- 在此处编辑以回答更多问题 ---

You're right that %lu is probably better than %ld.你说得对,%lu 可能比 %ld 好。 I suppose it's possible that you'd have an address with the most significant bit set (which would mean %ld would think it's negative).我想您可能有一个设置了最高有效位的地址(这意味着 %ld 会认为它是负数)。

Yes:是的:

float * q = nullptr;

Means q is all-zero.意味着q是全零。

Cout knows what is being printed and (usually) does the right thing. Cout 知道正在打印什么,并且(通常)做正确的事情。 It is rare to use format specifiers unless you're very specifically controlling it (like number of digits to use when printing out floats & doubles).除非您非常明确地控制它(例如打印浮点数和双精度时使用的位数),否则很少使用格式说明符。 I use it to set default output of bools to print true or false instead of 1 or 0 .我用它来设置布尔值的默认 output 以打印truefalse而不是10 But generally speaking, you get sane values when using cout without any extra work or thought necessary.但一般来说,当您使用 cout 时,您会得到理智的值,而无需任何额外的工作或认为是必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM