2014-09-26 85 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