2016-08-12 130 views
5

這爲什麼有效? (即如何被傳遞到int結果printf()在打印字符串)將字符串賦值給int並將該int傳遞給printf如何正確打印字符串?

#include<stdio.h> 

int main() { 
    int n="String"; 
    printf("%s",n); 
    return 0; 
} 

警告:初始化將指針整數,未作施放[默認啓用]
INT N =「字符串」;
警告:格式'%s'需要'char *'類型的參數,但參數2的類型爲'int'[-Wformat =]
printf(「%s」,n);

輸出:字符串

編譯器:GCC 4.8.5

回答

8

在你的代碼,

int n="String"; //conversion of pointer to integer 

是高度依賴於實現注1

printf("%s",n); //passing incompatible type of argument 

調用undefined behaviornote 2 不要那樣做

道德故事:警告是有原因的,請注意他們。


注1:

引用C11,章§6.3.2.3

任何指針類型可以被轉換爲整數類型。除了先前指定的以外, 結果是實現定義的。如果結果不能用整數類型表示,則 的行爲未定義。 [....]

注2:

章§7.21.6.1

[....]如果任何參數是 對於相應的轉換規範而言不是正確的類型,則行爲是 未定義。

以及自變量的用於%s格式說明與printf()

s如果沒有l長度改性劑存在的類型,參數應爲指針字符的陣列的初始 元件類型。 [...]

5

你的程序的行爲是未定義

本質上,您將const char*分配給intprintf將其轉換回來。但是確實認爲這完全是巧合:你不能像這樣施放無關的類型。

C讓你有能力在腳下自己射擊。

+2

這讓我想起了Bjarne Stroustrup引用的一些東西:_C可以很容易地將自己拍攝下來。 C++使它更難,但是當你這樣做時,它吹走你的整個腿._ :) –

1

int類型可以存儲在當今大多數的計算機的4張字節數(從-2147483647到2147483647)

這意味着它「」可以「」存儲一些地址爲好,唯一的問題是當你的地址大於2147483647它會導致溢出,你將無法獲得地址,(這對你的程序顯然是非常不利的)

地址是一個數字,指的是內存空間, 指針是用於存儲地址,它們更大(64位系統上的8個字節,32位系統上的4個字節)a第二,他們也未簽名(僅正)

這意味着,當你影響int n="String";如果地址"String" 2147483647下它不會造成問題,你的代碼將運行(DONT做到這一點)

http://www.tutorialspoint.com/c_standard_library/limits_h.htm

現在如果你仔細想想,你能猜到爲什麼會出現在32位系統4GB的RAM限制

(抱歉可能英語的錯誤,我爲法語)

+1

「int類型可以在當今大多數系統上存儲4個字節的數字」。我不同意。如果包含嵌入式系統,我相信-32768到+32767仍然是最常見的。 – Bathsheba

+0

編輯@Bathsheba – mou

0

使用像-Wall -Wextra -Werror -Wint-to-pointer-cast -pedantic(GCC)這樣的選項進行編譯會很快顯示您不應該依賴此行爲。