2014-09-26 81 views
2

我想了解如何以十进制和十六进制显示指针值。下面你可以看到我创建一个值并尝试使用指针来打印出值和值的位置。C指针位置,十进制和十六进制

请正确使代码工作,以便打印出以十进制和十六进制值

double val= 1; 
printf("The value of val : %f\n",val); 


double *ptr; 
ptr= &val; 

printf("dereference *ptr= %f\n", *ptr); 

//Display the location of val with and without pointer use in decimal and hex 


//decimal 
printf("location of val in decimal with ptr is: %p\n",(void *) ptr); 
printf("location of val in decimal without a pointer is: %p\n",(void *) &val); 

//hexadecimal THIS IS NOT WORKING 
printf("location of val in hex with ptr is: %#x\n", (void *) ptr); 
printf("location of val in hex without a pointer is: %#x\n", (void *) &val); 
+4

但是,您的问题是什么? – 2014-09-26 00:21:50

+0

我做了编辑。基本上我需要打印指针位置作为十进制和十六进制,并且十六进制不起作用 – 2014-09-26 00:27:09

回答

5

%p格式需要void *并以实现定义的格式打印。如果你想抓住的控制,使用来自<stdint.h>的类型和格式从<inttypes.h>(第一C99中定义):

#include <inttypes.h> 

printf("Location in decimal: %" PRIuPTR "\n", (uintptr_t)ptr); 
printf("Location in hex:  0x%.8" PRIXPTR "\n", (uintptr_t)ptr); 
printf("Location in octal  %#" PRIoPTR "\n", (uintptr_t)ptr); 

等等

uintptr_t类型(名义上是可选的,但是所有的实际实现应定义它)是一个无符号整数类型,其大小足以容纳一个指向对象(变量;不一定足够大以容纳函数指针)的指针。诸如PRIuPTR这样的名称为uintptr_t类型定义了正确的转换说明符(该值是平台特定的)。

请注意,如果您使用<inttypes.h>,则不需要包含<stdint.h>

0

不要忘了包括#include <inttypes.h>

正如评论所说,这是更好地做到这一点:

//hexadecimal 
printf("Location in hex:  0x%.8" PRIXPTR "\n", (uintptr_t)ptr); 
printf("Location in hex:  0x%.8" PRIXPTR "\n", (uintptr_t)&val); 

如果你觉得与unitptr_t投不舒服,然后想象你是铸造一个unsigned int。这是不一样的,但这是一个开始。

欲了解更多信息,请阅读this的答案。

此外,您可能需要查看%p%x之间的difference

+0

你正确使用'(uintptr_t)'强制转换。不正确的是不使用'PRIxPTR'等。具体来说,在64位Unix系统中,'%x'用于打印32位(无符号)整数,但'uintptr_t'是一个64位无符号整数。 – 2014-09-26 00:30:47

+0

我看到乔纳森,感谢您的建议。乐于学习新事物,这里是我的+1。 – gsamaras 2014-09-26 00:36:26

+1

请注意'__STDC_FORMAT_MACROS'对于标准C而言不应该是C99或C11编译器所必需的。几年前似乎对C++编译器存在一些困惑。 C99标准(但不包括C11标准)有一个脚注182,它表示:_182)只有在包含''之前定义'__STDC_FORMAT_MACROS' 时,C++实现才应该定义这些宏._这不适用于C实现;只要你用'-std = c99'或'-std = c11'或道德等价物进行编译,''中的宏应该被定义。 – 2014-09-26 00:59:49

0

对于小数使用%lu个(长无符号),而不是%P 此外,无需对(无效*)与正常printf函数

喜欢这个铸造:

//decimal 
printf("location of val in decimal with ptr is: %lu\n",ptr); 
printf("location of val in decimal without a pointer is: %lu\n",&val); 

您可以使用以十六进制格式打印指针时%p代替%x。 像这样:

//hexadecimal 
printf("location of val in hex with ptr is: %#x\n", ptr); 
printf("location of val in hex without a pointer is: %p\n", &val); 
+0

从技术上讲,需要将'%*'转换为'void *',因为'%p'用于打印'void *'。现在有几台机器你会注意到一个区别,但是我在一台机器上学习了C,当给定'int i = 0; int * ip =&i; char * cp =(char *)&i;','ip'和'cp'中的值在转换为'int'时(这足够容纳一个地址)并不相同。您的代码在Win64平台上无法正常工作;在那里,指针是一个8字节的数量,但'%lu'需要一个4字节的无符号整数。 – 2014-09-26 00:49:45

+0

是的,对于64位,更好地使用%llu。但是,指针是指针,当值被移除或确定大小时需要进行转换。除此之外,应该工作。 – user3782235 2014-09-26 00:51:21

1

信用证通常返回内存地址为十六进制数字,所以你只需要使用%P。至于十进制表示法,您可以使用类型转换:

int rand1 = 12, rand2 = 15; 

printf("rand1 = %p : rand2 = %p\n\n", &rand1, &rand2); 
// returns hexadecimal value of address 

printf("rand1 = %d : rand2 = %d\n\n", (int) &rand1, (int) &rand2); 
// returns decimal value of address