2016-04-21 104 views
0

我一直試圖通過一些C基礎最近嘗試和建立一個基本的低級語言的理解。 在我遇到的文件之一(A tutorial on pointers and arrays in C) 筆者採用的是空指針在printf聲明:鑄造指針無效時打印

int var = 2; 
printf("var has the value %d and is stored at %p\n", var, (void *) &var); 

和狀態的原因:

我投的指向整數成void 指針使它們與%p轉換規範兼容。

然而,省略(void *)不會導致錯誤或警告,無論是編譯和運行,或通過valgrind運行。

int var = 2; 
printf("var has the value %d and is stored at %p\n", var, &var); 

這裏被認爲是無效的,被認爲是一種最佳實踐或標準,還是有什麼更險惡的事情發生?

+0

不可能通過實驗檢查你是否寫下了正確的答案C.程序是正確的C如果遵循規則,那就是你所能做的。 –

+0

這只是顯而易見的,劇組字面上說「我正在用這個具體的方式解釋這個值」。在你的例子中,你將'int *'強制轉換爲'void *'。所以把我的整數指針解釋爲一個通用指針。就個人而言,對於這樣的微不足道的情況來說,如此冗長並不是很好的做法。 – SGM1

+1

允許不同類型的指針具有不同的表示和對齊限制。 'printf()'是一個可變參數函數,它不會自動將其參數轉換爲其參數類型,因此使用錯誤類型的參數調用會導致未定義的行爲。 – EOF

回答

4

由於printf是一個可變參數函數,其聲明僅指定第一個參數(格式字符串)的類型。任何剩餘參數的數量和類型都需要與格式字符串匹配,但這取決於程序員,以確保它們實際匹配。如果他們不這樣做,行爲是不確定的,但編譯器沒有義務向您發出警告。 (如果格式字符串是文字,某些編譯器(包括gcc)可以執行一些檢查。)

%p格式說明符需要參數類型爲void*。如果你傳遞了一個不同類型的指針,你就有未定義的行爲。在許多實現中,所有指針類型都具有相同的大小和表示形式,並且以與函數參數相同的方式傳遞 - 但語言不能保證。通過明確地將指針轉換爲void*,可以保證它能正常工作。通過省略演員陣容,您的代碼可能會可能按照您所期望的幾乎所有實施方式工作。

100%正確率優於99%正確率,特別是如果額外1%的唯一成本只輸入幾個字符。