2015-12-30 164 views
0

當我編譯下面的代碼時,Visual Studio顯示C4477的警告。爲什麼這個警告是由visual studio產生的?我該如何解決這個問題?Visual Studio 2015中的警告C4477

警告:警告C4477:「printf」式:格式字符串「%d」,需要類型「詮釋」的說法,但可變參數參數1有因爲使用不正確鍵入「詮釋*」

#include <stdio.h> 

int main(void) { 
    int num = 0; 
    int *pi = &num; 

    printf("Address of num: %d Value: %d\n", &num, num); 
    printf("Address of pi: %d Value: %d\n", &pi, pi); 

    return 0x0; 
} 
+0

'%d'需要一個'int'參數。要打印指針,請使用'%p'。請閱讀'printf'的手冊頁或搜索「printf格式字符串」! – Olaf

回答

6

格式說明符。 %d是打印int。要打印指針使用%p和轉換爲void*

printf("Address of num: %p Value: %d\n", (void*)&num, num); 
printf("Address of pi: %p Value: %p\n", (void*)&pi, (void*)pi); 

因爲需要%p可變參數的功能不做任何類型轉換,從type *void *需要演員來void*。引用標準:

7.21.6格式的輸入/輸出函數(C11草案)

P上的參數應是無效的指針。指針的值是 轉換爲打印字符序列,採用 實現定義的方式。

1

換句話說,你的說法& NUM(或形式(無效*)& NUM)告訴您希望在傳遞給函數的num的地址,NUM的不是值的編譯器。帶有%d格式說明符的printf函數應該是一個值,而不是一個地址。抱怨是編譯器意識到這種差異。

注意:在32位工作中,地址和int都是32位,所以事情(即%d)就可以工作。但是,在64位世界中,int仍然是32位長,但地址是64位。 I.E.你不能準確地用%d來表示指針的值。這就是%p創建的原因。它(編譯器)足夠聰明,能夠在編譯32位時將32位數量的%p參數處理爲%p參數,對64位進行編譯時,該參數爲64位數量。

閱讀計算機體系結構,硬件堆棧和它們的位大小。當你處於這種狀態時,你可能也希望瞭解小端和大端之間的區別。