C语言 & address和指针地址之间的区别-十六进制和指针类型数据[重复]

z31licg0  于 2023-05-16  发布在  其他
关注(0)|答案(3)|浏览(163)

此问题已在此处有答案

Correct format specifier to print pointer or address?(6个回答)
7天前关闭
我使用以下代码作为指针的学习练习:

int a=8;

int *ptr=&a;

printf("\nThe & address of a is: %x\n",&a);
printf("\nThe value of the pointer ptr is: %p \n",ptr);

我这样做是为了识别&aptr给出的地址值,我注意到输出中存在以下差异:

The & address of a is: a6bff9c4

The value of the pointer ptr is: 000000f5a6bff9c4

我可以看到ptr的值是&的值,在开头附加了000000f5。我知道%x以十六进制输出&地址值。指针值的格式是什么,它与十六进制&值有何不同?
尝试理解&和指针变量输出的内存地址之间的差异,并理解它们的格式。

3zwtqj6y

3zwtqj6y1#

使用%x说明符会截断您试图显示的部分数据。%x本质上被设计为将int化为十六进制形式,通常有4个字节的空间,但是被要求表示一个指针,在这种情况下(但不总是),该指针占用的空间比int多。
%p是专门设计来适应指针的描述。取决于系统的地址指针引用,它将是4字节(32位)或8字节(64位)
因此,a6bff9c4被错误地描述为%x

hgqdbh6s

hgqdbh6s2#

转换规范%x需要一个unsigned int类型的对象。sizeof( unsigned int )通常等于4。而sizeof( int * )等于48字节,具体取决于所使用的系统。
使用无效的转换规范会导致未定义的行为。
来自C标准(7.21.6.1 fprintf函数)
9如果转换规范无效,则行为未定义。275)如果任何参数不是相应转换规范的正确类型,则行为未定义。
使用转换规范%x来代替带有指针的此调用

printf("\nThe & address of a is: %x\n",&a);

你应该写

#include <inttypes.h>

//...

printf("\nThe & address of a is: %08" PRIXPTR "\n", ( uintptr_t ) ( void * )&a);

你需要写
在第二次调用printf时,需要将指针转换为void *类型。
这是一个演示程序。

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

int main( void )
{
    int a = 8; 

    int *ptr = &a;

    printf( "\nThe & address of a is: %08" PRIXPTR "\n", ( uintptr_t )( void * )&a );
    printf( "\nThe value of the pointer ptr is: %p \n", ( void * )ptr );
}

程序输出可能如下所示

he & address of a is: 0116F9BC

The value of the pointer ptr is: 0116F9BC

printf的调用

printf( "\nThe & address of a is: %08" PRIXPTR "\n", ( uintptr_t )( void * )&a );

可以更灵活,如果重写它的方式如下

printf( "\nThe & address of a is: %0*" PRIXPTR "\n", 2 * ( int )( sizeof( &a ) ), ( uintptr_t )( void * )&a );
8qgya5xd

8qgya5xd3#

在你的例子中,&aptr-它们具有相同的数值。
根据规范,要打印地址(使用&variable生成,或存储在指针变量中),始终使用%p说明符,并将参数转换为(void *)。其他的,都是不确定的行为。

相关问题