使用%u和C中的%d打印内存地址之间的区别?

ipk*_*iss 12 c unsigned

我读了一本C书.要打印出变量的内存地址,有时书籍会使用:

printf("%u\n",&n);
Run Code Online (Sandbox Code Playgroud)

有时,作者写道:

printf("%d\n",&n);
Run Code Online (Sandbox Code Playgroud)

结果总是一样,但我不明白两者之间的差异(我知道%u表示无符号).

有人可以详细说明吗?

非常感谢.

Ada*_*eld 38

%u将整数视为无符号,而%d将整数视为有符号.如果整数介于0 an INT_MAX(在32位系统上为2 31 -1),则两种情况下的输出都相同.

如果整数为负(对于有符号输入)或在INT_MAX+1和之间UINT_MAX(例如在2 31和2 32 -1 之间),则只会产生差异.在这种情况下,如果你使用说明%d符,你会得到一个负数,而如果你使用%u,你会得到一个大的正数.

地址仅作为无符号数字有意义,因此从来没有任何理由将它们作为带符号的数字打印出来.此外,当它们打印出来时,它们通常以十六进制(具有%x格式说明符)打印,而不是十进制.

您应该只使用%p地址的格式说明符,但它保证适用于所有有效指针.如果你用32位整数,但64位指针的系统上,如果您尝试打印与任何一个指针%d,%u或者%x没有ll长度修改,你会得到的是和其他任何可能得到错误的结果稍后打印(因为printf只读取指针参数的8个字节中的4个); 如果添加ll长度修饰符,则无法移植到32位系统.

底线:始终%p用于打印指针/地址:

printf("The address of n is: %p\n", &n);
// Output (32-bit system): "The address of n is: 0xbffff9ec"
// Output (64-bit system): "The address of n is: 0x7fff5fbff96c"
Run Code Online (Sandbox Code Playgroud)

确切的输出格式是实现定义的(C99§7.19.6.1/ 8),但它几乎总是打印为无符号十六进制数,通常带有前导0x.

  • 在C99中,还有一些在`inttypes.h`中定义的宏,它们在打印指针时为您提供了更大的灵活性.`%p`始终打印十六进制地址.但是假设您想以十进制(或八进制!)打印它.`printf("十进制:%"PRIuPTR",八进制:%"PRIoPTR"\n",(uintptr_t)p,(uintptr_t)p);` (2认同)