2011-04-14 78 views
2

由於它們都指向無法修改的字符。第一個常量有什麼好處?難道僅僅是告訴編譯器要提防可能做任何代碼類似ptr[1] = 'a'是否必須在聲明char const * ptr =「some characters」時使用'const'?

  1. char const *ptr = "some characters"
  2. char *ptr = "some characters"
+0

在第二種情況下,只能因爲放置「某些字符」的部分爲只讀而無法修改ptr的內容。例如,嘗試修改其內容時,Windows上會發生訪問衝突。也許有一些深奧的平臺可以讓你逃脫這一點。 – Grim 2011-04-14 09:47:56

+0

@Kostya - 是的,謝謝。它是訪問衝突還是未定義的行爲? – dubnde 2011-04-14 09:50:12

+0

@Kostya:許多平臺都有標誌來實際允許這個;如果MSVC沒有,我會感到驚訝。不過,這是一個非常糟糕的主意。 – Potatoswatter 2011-04-14 09:51:14

回答

4

是的,這樣,當你試圖通過指針修改內容在運行時你會得到一個編譯器錯誤,而不是令人討厭的驚喜。

+0

謝謝。在編譯時「捕捉」錯誤的真正優點是一個令人信服的理由,特別是因爲嘗試修改字符導致未定義的行爲。 – dubnde 2011-04-14 09:55:28

1

此建議:

char const *ptr = "some characters"; 

而下面是推薦,因爲你可以嘗試改變常量數據ptr點。

char *ptr = "some characters"; 

好的編譯器應該在第二種情況下給出警告。

GCC(4.3.4)確實給予警告:

prog.cpp:7:警告:從字符串常量 '字符*' 不贊成使用轉換

見自己:http://www.ideone.com/8FqyZ

+0

爲什麼?警告?字符串文字是類型爲char []的值。當在大多數情況下使用時,它會衰減爲指向其第一個元素('char *')的指針。爲'char *'類型的對象賦值'char *'類型的值應該是免費的。 – pmg 2011-04-14 09:46:19

+1

這是合法的,並且已經定義了行爲,因此定義「錯誤」。這幾乎總是一個糟糕的主意,它最終只是爲了兼容前''const'非標準版本的C,它在C++中被棄用,並且它是類型系統中的一個漏洞。但除此之外它沒關係;-) – 2011-04-14 09:48:27

+2

@pmg:C++在這方面與C不同。在C++中,字符串常量的類型爲'const char []',但爲了與C兼容,不贊成隱式轉換爲'char *'。我知道你是一個C人,所以你可以毫不費力地知道關於這些惱人的區別:-) – 2011-04-14 09:49:46

0

這是告訴編譯器注意任何可能會嘗試並更改字符串的代碼。 雖然,你可以很聰明,仍然可以改變字符串,但通常是爲了防止代碼中的意外錯誤。

2

const的使用很少是「必要的」,從純粹的「執行此代碼將會有所期望的結果」的角度來看。

然而,大量使用const對任何閱讀代碼的人來說都是巨大的幫助。這值得很多。我建議在任何地方都可以使用const

以類似的方式,出於幾乎相同的原因,總是聲明旨在嚴格爲本地的函數爲static

+0

是的!是的!是的!太多的編碼器在const上吝嗇,因爲它們「什麼都不做」。但從編譯器檢查的文檔的角度來看......無價! – timday 2011-04-14 22:00:54

3

在C++中,const char[N](它是字符串文字的實際類型)到char *的轉換被棄用,並且不再適用於C++ 11(C++ 11,C++ 03§4.2)。所以,#2是新破碎的。 C++ 98/C++ 03編譯器通常會產生警告;一個C++ 0x/C++ 11編譯器應該完全拒絕。

const的要點是,編譯器可以告訴你什麼時候試圖刪除或違反它。即使你不打算試圖修改這些角色,優點是如果你意外地發生了錯誤。

您可以隨時使用const_cast解決此問題,但在這種情況下,內存可能是隻讀的,物理上的或通過MMU,因此無法解決任何問題。

0

C下面的兩個定義是完全合法和合理的。

char const *ptr1 = "some characters"; 
char *ptr2 = "some characters"; 

C,文字串是char[]類型的值。在大多數情況下,它的衰減值爲char*。對許多人來說,添加const修飾符是一個很好的習慣:如果代碼嘗試更改字符串文字(這是未定義的行爲),它會讓編譯器抱怨。