C语言 为什么我们不能在 C 语言中使用 "%d" 而不是 "%u" 带指针?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16726105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't we use "%d" in C language instead of "%u" with pointers?
提问by BlueFlame
%uis used for unsigned numbers.
I get the same results if I use %dinstead of %uto display the address of a variable.
We use %ujust for ethics or does it make any real difference too.
Have a look:
%u用于无符号数。
如果我使用%d而不是%u显示变量的地址,我会得到相同的结果。
我们%u只是为了道德而使用它,或者它也有任何真正的不同。
看一看:
int i=5;
printf("Address of i: %d", &i);
is same as:
与:
printf("Again, address: %u" ,&i);
[EDIT] An example where it generates different output would be appreciated.
[编辑] 生成不同输出的示例将不胜感激。
回答by David Schwartz
You can cross the street without looking both ways many times and you might not get hit by a car. That doesn't mean it's a good idea.
您可以多次过马路而不必左右看,而且您可能不会被汽车撞到。这并不意味着这是个好主意。
回答by kgraney
%dwill show a negative value for addresses with the most significant bit set (high addresses)%uwill always show the positive interpretation of the bits%pis the best, since it's explicitly reserved for printing addresses.
%d将显示具有最高有效位设置的地址(高地址)的负值%u将始终显示位的正面解释%p是最好的,因为它明确保留用于打印地址。
Consider this, supposing an address of 0xffffffff.
考虑这一点,假设地址为0xffffffff。
#include <stdio.h>
int main () {
void* val = 0xffffffff;
printf("d = %d\n", val);
printf("u = %u\n", val);
printf("p = %p\n", val);
return 0;
}
And, it's output:
而且,它的输出:
d = -1
u = 4294967295
p = 0xffffffff
回答by Matteo Italia
Actually, even "%u"is wrong; for pointers you have to use "%p"
实际上,即使"%u"是错误的;对于您必须使用的指针"%p"
Still, %d-instead-of-%uworks because on your architecture signed and unsigned numbers have the same representationas far as we are looking at positive numbers. So, if you pass a pointer to %d, printfwill try to interpreter the parameter as a signed integer, and you'll get the same result of %uas long as the high bit of the pointer is not set (which is usually the norm for user-mode pointers); otherwise, you'll get a negative number with %dand a positive one with %u(assuming your machine employs 2's complement arithmetic).
尽管如此, -%d代替 -%u有效,因为在您的体系结构上,有符号数和无符号数具有相同的表示形式,就我们正在查看的正数而言。因此,如果您将指针传递给%d,printf将尝试将参数解释为有符号整数,并且%u只要未设置指针的高位(这通常是用户的规范),您就会得到相同的结果模式指针);否则,您将得到一个负数 with%d和一个正数 with %u(假设您的机器使用 2 的补码算法)。
Interestingly, the biggest error is not mismatching the signedness, but using integer specificators (%dand %u) instead of the pointer specificator (%p); in facts, on most 64 bit architectures intis 32 bit, but void *is 64 bit, thus using %uinstead of %pwill only print half of the address (the lower half on little-endian architectures, like x86_64).
有趣的是,最大的错误不是符号不匹配,而是使用整数说明符(%dand %u)而不是指针说明符(%p);事实上,在大多数 64 位架构上int是 32 位,但是void *是 64 位,因此使用%u而不是%p只会打印地址的一半(小端架构上的下半部分,如 x86_64)。
Notice: all this explanation comes from "typical implementations" of the C language; as far as the standard is concerned, if you mismatch the type of the format specificator and of the actual data you go into "undefined behavior" (=anything from a crash to pink unicorns flying out of your printer).
注意:所有这些解释都来自C语言的“典型实现”;就标准而言,如果格式说明符的类型与实际数据的类型不匹配,则会进入“未定义行为”(=从崩溃到粉红色独角兽飞出打印机的任何事情)。
回答by Jerome
When printing pointers in C, you should use %p, not %uor %d. %uand %dare intended to display integer values. You are implicitly casting your pointers to integers when you use those flags to print out pointers and there are quite a few architectures were this can cause a lot of trouble (especially in 64bit architectures).
在 C 中打印指针时,您应该使用%p, not%u或%d。%u并且%d旨在显示整数值。当您使用这些标志打印出指针时,您隐式地将指针转换为整数,并且有很多架构会导致很多麻烦(尤其是在 64 位架构中)。
The difference between %dand %uis like you mentioned, %utreats the value as unsigned and %das signed. The results will be different if the highest order bit is 1. You can see this easily when using -1.
%d和之间的区别%u就像你提到的那样,%u将值视为无符号和%d有符号。如果最高位为 1,结果会有所不同。使用 -1 时可以很容易地看到这一点。
printf("%d, %u\n", -1, -1);
Output:
输出:
-1,4294967295
回答by markgz
There are unusual CPU architectures where a pointer has a different representation or size than an unsigned number.
有一些不寻常的 CPU 体系结构,其中指针具有与无符号数不同的表示或大小。
One common example is 32-bit x86 code written in segmented mode, where an address consists of a 16-bit segment number with a 32-bit segment offset. (Disclaimer: it's been years since I looked at this, so I may have forgotten the details.)
一个常见的例子是以分段模式编写的 32 位 x86 代码,其中地址由 16 位段号和 32 位段偏移量组成。(免责声明:我已经好几年没看过这个了,所以我可能忘记了细节。)
Another case is a 64-bit machine set up to use 64-bit pointers, and 32-bit ints.
另一种情况是设置为使用 64 位指针和 32 位整数的 64 位机器。

