格式说明符:%u vs%d在C中

发布于 2025-02-14 02:13:49 字数 249 浏览 0 评论 0原文

#include<stdio.h>

int main(){
    int a = 3;
    printf("%u\n",&a);
    printf("%d\n",&a);
    return 0;
}

我试图打印变量的地址,“ a”。现在,使用两个不同格式指定符“%u”和“%d”,打印了两个不同的内存地址,我觉得这是Wierd的。

所以我的问题是两种格式指定符之间有什么区别?

#include<stdio.h>

int main(){
    int a = 3;
    printf("%u\n",&a);
    printf("%d\n",&a);
    return 0;
}

I was trying to print address of Variable, "a". Now with usage of two different format specifier, "%u" and "%d", two different memory address is printed which I find it wierd.

So My Question is what difference between two format specifier?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

定格我的天空 2025-02-21 02:13:49

使用两个转换说明器输出地址都调用不确定的行为。

从C标准(7.21.6.1 FPRINTF函数)

9如果转换规范无效,则行为为
275)如果任何参数不是正确的类型
相应的转换规范,行为不确定。

相反,您应该使用转换规范<代码> p ,例如

printf( "%p\n", ( void * )&a );

另一种方法是使用整数类型intptr_tuintptr_t在标题&lt; stdint.h&gt;中声明并使用说明器pridptrpriuptr或例如prixptr在标题中声明&lt; inttypes.h&gt; to type 的指数的输出值分配的值void *

这是一个演示程序。

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main( void )
{
    int a = 3;
    intptr_t p1 = ( intptr_t )( void * )&a;
    uintptr_t p2 = ( uintptr_t )( void * )&a;

    printf( "&a = %p\n", ( void * )&a );
    printf( "&a = %"PRIdPTR "\n", p1 );
    printf( "&a = %"PRIuPTR "\n", p2 );
    printf( "&a = %#"PRIxPTR "\n", p2 );
}

程序输出是

&a = 0x7ffc220b16ec
&a = 140720879638252
&a = 140720879638252
&a = 0x7ffc220b16ec

Using the both conversion specifiers to output an address invokes undefined behavior.

From the C Standard (7.21.6.1 The fprintf function)

9 If a conversion specification is invalid, the behavior is
undefined.275) If any argument is not the correct type for the
corresponding conversion specification, the behavior is undefined.

Instead you should use the conversion specifier p as for example

printf( "%p\n", ( void * )&a );

Another approach is to use integer types intptr_t or uintptr_t declared in the header <stdint.h> and to use specifiers PRIdPTR or PRIuPTR or, for example, PRIxPTR declared in the header <inttypes.h> to output assigned values of pointers of the type void *.

Here is a demonstration program.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main( void )
{
    int a = 3;
    intptr_t p1 = ( intptr_t )( void * )&a;
    uintptr_t p2 = ( uintptr_t )( void * )&a;

    printf( "&a = %p\n", ( void * )&a );
    printf( "&a = %"PRIdPTR "\n", p1 );
    printf( "&a = %"PRIuPTR "\n", p2 );
    printf( "&a = %#"PRIxPTR "\n", p2 );
}

The program output is

&a = 0x7ffc220b16ec
&a = 140720879638252
&a = 140720879638252
&a = 0x7ffc220b16ec
北城挽邺 2025-02-21 02:13:49

%d用于签名整数,%u用于无符号整数。

因此,当您使用%d%u打印出相同的值时,您可能会得到不同的值,因为您要打印的字节的解释方式有所不同。 (一旦作为签名的整数,一次是无符号整数。)

最终说明,您应该使用%p(“ p”作为“指针”)来打印地址。

%d is for signed integers, %u is for unsigned integers.

So, when you print the same value out with %d and with %u, you may get different values, since the bytes you're printing out are being interpreted differently. (Once as a signed integer, once as an unsigned integer.)

Final note, you should use %p ("p" for "pointer") to print out addresses.

2025-02-21 02:13:49

当然,“%u \ n”的地址不同于“%d \ n”,因为这些是一个接一个地创建的不同值。查看ASM:

“在此处输入图像描述”

rdx寄存器都有相同的值printf呼叫由于LEA指令,将相同的地址放入其中。

但是您可能看到的是rcx寄存器的值,其中包含不同的printf格式值地址printf呼叫。

现在答案:

%d已签署了十进制整数。

%u是未签名的十进制整数。

当有一个printf调用时,就会发生问题。此功能更改RDX寄存器的值,RDX寄存器是a变量的内存地址。

Well of course "%u\n" has different address than "%d\n" because these are different values created one after another. Look at ASM:

enter image description here

RDX register will have the same value for both printf calls because of LEA instruction is putting the same address into it.

But what you probably see are the values of RCX register which contains different printf format value address for each printf call.

Now the answer:

%d is signed decimal integer.

%u is unsigned decimal integer.

The problem occurs when there is a printf call. This function changes the value of RDX register which is the memory address of a variable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文