-3

%u用于无符号数。
如果我使用%d而不是%u显示变量的地址,我会得到相同的结果。
我们%u只是为了道德而使用,还是它也有任何真正的区别。
看一看:

int i=5;
printf("Address of i: %d", &i);

等同于:

printf("Again, address: %u" ,&i);

[编辑] 一个它产生不同输出的例子将不胜感激。

4

5 回答 5

7

你可以过马路而不必多次看两边,而且你可能不会被车撞到。这并不意味着这是一个好主意。

于 2013-05-24T00:37:58.163 回答
4
  • %d对于设置了最高有效位的地址(高地址),将显示负值
  • %u将始终显示位的积极解释
  • %p是最好的,因为它明确保留用于打印地址。

考虑一下,假设地址为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;
}

而且,它的输出:

d = -1
u = 4294967295
p = 0xffffffff
于 2013-05-24T00:41:27.947 回答
2

实际上,甚至"%u"是错误的;对于您必须使用的指针"%p"


尽管如此,%d-instead-of-仍然%u有效,因为在您的架构中,有符号数和无符号数在我们查看正数时具有相同的表示形式。因此,如果您将指针传递给%dprintf将尝试将参数解释为有符号整数,并且%u只要未设置指针的高位(这通常是用户的规范) ,您就会得到相同的结果-模式指针);否则,您将得到一个负数%d和一个正数%u(假设您的机器使用 2 的补码算法)。

有趣的是,最大的错误不是符号不匹配,而是使用整数说明符(%d%u)而不是指针说明符(%p);事实上,在大多数 64 位架构int上是 32 位,但是void *是 64 位,因此使用%u而不是%p只会打印地址的一半(小端架构上的下半部分,如 x86_64)。

注意:所有这些解释都来自C语言的“典型实现”;就标准而言,如果您不匹配格式说明符的类型和实际数据的类型,您将进入“未定义行为”(=从崩溃到粉红色独角兽飞出打印机的任何事情)。

于 2013-05-24T00:43:42.787 回答
2

在 C 中打印指针时,您应该使用%p, not%u%d. %u%d旨在显示整数值。当您使用这些标志打印出指针时,您将指针隐式转换为整数,并且有很多架构会导致很多麻烦(尤其是在 64 位架构中)。

%d和之间的区别%u就像您提到的那样,%u将值视为无符号和%d有符号。如果最高位为 1,则结果会有所不同。使用 -1 时可以轻松看到这一点。

printf("%d, %u\n", -1, -1);

输出:

-1,4294967295
于 2013-05-24T00:45:10.407 回答
0

有一些不寻常的 CPU 体系结构,其中指针具有与无符号数不同的表示或大小。

一个常见的例子是以分段模式编写的 32 位 x86 代码,其中地址由 16 位段号和 32 位段偏移量组成。(免责声明:我看过这个已经好几年了,所以我可能已经忘记了细节。)

另一种情况是 64 位机器设置为使用 64 位指针和 32 位整数。

于 2013-05-24T00:47:26.380 回答