2016-10-30 167 views
1

糾正我,如果我錯了,但我本以爲這行代碼:爲什麼const char * foo =「Hello」;編譯但不是const int * foo = 5;?

const char *foo = "Hello"; 

意味着充滿了「你好」的地方創建堆棧上字符數組,和Foo是一個指向它。在這種情況下,我不明白爲什麼這行代碼給出了從‘詮釋’到‘const int的*’

const int *foo = 5; 

「無效的轉換將不會只是在棧上創建5的整數某處並具有FOO指向它?

+0

'5'是一個整數文字,它的類型是'int'。 '「hello」'是一個字符串文字,它的類型是'const char *'。所以'int!= int *'。 – DeiDei

+0

像「Hello」這樣的const char *字符串通常會放在堆上,而不是放在堆棧上。 –

+1

@squeamishossifrage像這樣的字符串文字不會堆積在大多數編譯器上(也不會堆疊)。它將作爲只讀數據嵌入到二進制文件中。 –

回答

5

由於"Hello"char [N]類型(C)和const char[N](在C++),它衰減到類型char*(在C)或const char*(在C++)的string literal,相同另一方面,5是一個右值,它的類型是int,所以你不能將它綁定到類型爲的指針。

您可能會感興趣this有用。

+0

爲什麼它衰變爲const char *? – Goldname

+0

@Goldname因爲這些是從C繼承的規則。這就是爲什麼你可以將字符數組傳遞給帶有字符指針的函數。原因在於C(以及隨後的C++)沒有數組的複製語義(出於效率的原因),並且在傳遞數組時,您將指針有效地傳遞給它的第一個元素。假如它有複製語義,那麼所有的數組在被傳遞時被複制,這被認爲是低效的。你可以使用['std :: array'](http://en.cppreference.com/w/cpp/container/array)(這是一個圍繞C風格數組的薄包裝)來按值傳遞數組。 – vsoftco

+0

它在C中是'char [6]'類型,在C++中是'const char [6]'。 (這個問題有兩個標籤。) –

0

首先,您正在使用字符串文字來初始化foo的值。

在第一,FOO本身是一個常量字符指針,其在某些方面的「特殊」相對於其他指針。

對於大多數指針,如在你的第二個例子,你聲明富作爲一個常量指針爲int,你初始化它的地址您希望爲指針來。

換句話說,下面的代碼:

const int *foo = 5; 

是錯誤的,因爲你是在告訴編譯器foo的地址爲5的時候你真的想爲foo指向的5

您可以使用取消引用操作符訪問存儲在foo中的值;你想說的是:

const int *foo = malloc(sizeof(int)); 
*foo = 5; 

字符串文字是一種特殊情況:它們是經過特殊處理的,因爲C表示字符串由「\ 0」終止字符數組。

const char *foo = "Hello"; 

在 「你好\ 0」 設置的foo在字母 'H' 爲指向的地址。以這種方式使用的所有字符串文本都存儲在特定的內存部分,這部分內容往往是隻讀的;試圖像這樣修改foo:

foo[0] = 'W'; 

將導致未定義的行爲。

字符串文字在初始化上下文中的特殊行爲與數組偶爾衰變爲指針的方式有關;當一個數組被分配給一個指針時,你確實聲明你想要指向指向給定數組的第一個元素。

最後一點:

你可以編譯器使用強制解釋5作爲存儲器地址:

// In C: 
const int *foo = (const int*) 5; 
// In C++: 
const int *foo = reinterpret_cast<const int *>(5); 

但是,你的程序可能會崩潰,因爲無論是存儲在內存位置5可能無法通過您的程序訪問。

0
// const char* c = 5; 
// const char* c = '5'; 
// const int* i = 7; 

只要沒有接受轉換,上面的三行就會產生編譯時錯誤。所以c需要一個文字字符串,並傳遞一個字符或整數值。

這就像傳遞給它當單個字符不是字符串的strcmp發生什麼:

char* name = "name"; 
char c = 'a'; 

if(strcmp(c, name));// error cannot convert first parameter from char to const char* 
相關問題