2013-04-29 163 views
3

考慮的碼兩個下列行:const char * const和const char []之間有區別嗎?

const char *ptr = "Hello"; 
char arr[] = "Hello"; 

有關指針定義,"Hello"字符串文字基本上不可改變,但ptr變量本身可以改變並保持不同的地址。

對於陣列定義,"Hello"字符串文字是複製到陣列的位置,但arr不能點到不同的位置;然而,由數組保持的字符串是可變的,因此可以改變。

現在考慮的代碼如下兩行:

const char * const ptr = "Hello"; 
const char arr[] = "Hello"; 

這裏,兩個字符串不變const char預選賽的結果 - 更有趣,但:有ptr定義爲一個常量指針,它不能指向一個不同的地址。

這兩行代碼是否會導致相同的行爲?如果最終效果是相同的,那麼在實現中是否存在理論上的差異 - 例如,指針方法是否爲匿名數組分配內存以保存除指針本身外的字符串,而數組方法僅爲內存分配陣列?

+8

差異:1.數組不是指針,2.指針不是數組,3.'sizeof()' – 2013-04-29 21:21:11

回答

4

這裏有一些差異。

首先,這可以在某些實施保持爲真作爲指針可以指向相同的存儲器:

const char * const ptr1 = "Hello"; 
const char * const ptr2 = "Hello"; 

ptr1 == ptr2; 

但使用陣列形式它不能是真實的。

無論如何,真正的區別在於它們的類型是不同的。特別是,char[]版本保留其數組類型的大小。所以sizeof(arr)給你的數組的大小,而不是一個指針,你也可以創建指向arr的數組的指針。

+0

關於「某些實現」,在Visual Studio中有一個「字符串池」選項(/ GF編譯器參數) 。它通常默認是關閉的,但如果啓用它,編譯器會在程序中找到所有相同的字符串文字,並將它們轉換爲單個常量,從而節省一些內存。 這將平衡ptr1和ptr2。 – 2014-06-30 12:17:28

2

那麼,&ptr&arr會產生不同的類型 - 一個是指向指針的指針,另一個是指向數組的指針。是否重要任何地方當然取決於你如何使用它們。檢查編譯器輸出的機器代碼以獲取具體結果。

+0

我很難理解*指針指針*和指針*之間的區別 - 陣列*。 sizeof(*(&arr))會產生數組的大小嗎? – 2013-04-30 12:42:47

+1

是的,我認爲是。你應該能夠嘗試並看到。我建議查看[comp.lang.c FAQ的第6節](http://c-faq.com/aryptr/index.html)開始。 – 2013-04-30 13:56:55

+0

是的,我認爲這部分完美地解釋了它:http://c-faq.com/aryptr/ptrtoarray.html – 2013-04-30 14:02:41

3

兩者之間存在差異:他們的地址。所有具有相同內容的字符串文字可能(但不一定)指向相同的地址。數組定義(如果它在函數範圍內)定義了一個新的對象,它不同於字符串字面值,也與其他具有相同內容的對象不同。因此地址必須不同。

如果你的函數是遞歸的,這將是特別的情況。然後,函數的所有嵌套調用將定義一個新變量,每個變量都有一個不同的地址。

3
const char *ptr = "Hello"; 

這聲明PTR作爲一個const指針到字符,在初始化字符串文字「你好」來點。指向不是有一個const類型,雖然允許實現將它放在只讀存儲器中。

char arr[] = "Hello"; 

這將arr聲明爲char的數組[6],初始化爲{'H', 'e', 'l', 'l', 'o', '\0'}

const char * const ptr = "Hello"; 

這將ptr聲明爲一個const指針指向const-char,初始化爲指向字符串文字「Hello」。雖然這個指針被聲明爲指向const內存,但字符串文字本身仍然沒有const類型,儘管實現仍然被允許將它放在只讀存儲器中。

const char arr[] = "Hello"; 

將arr聲明爲char的const數組[6],再次初始化爲{'H', 'e', 'l', 'l', 'o', '\0'}

所有不同,但我看到其他人已經提供了更好的答案給你的問題。

+0

如果我使用'const char * ptr',理論上我可以使用第二個指針訪問相同的內存位置來修改內存?這對於const char arr []'也是如此嗎? – 2013-04-30 12:38:02

+1

您總是可以使用第二個指針來拋棄類型限定,比如'const'。不過,這是一種違規行爲,有時候指出的確實是不可修改的(導致程序崩潰),任何中途可行的編譯器都會對此提出警告。 – 2013-04-30 12:49:40

1

對於陣列定義,"Hello"字符串文字複製到陣列的位置,但ARR不能指向不同的位置

的字符串不被複制到陣列中,這是不創建並存儲在像字符串文字只讀位置(可隱式轉換爲指針),但它只是

char arr[] = { 'H', 'e', 'l', 'l', 'o', '\0' }; 

作爲標準的簡寫說:

字符類型的數組可以通過字符串文字或UTF-8字符串文字初始化,可選擇括在花括號。

並且陣列不「點」,arrays are not pointers

這兩行代碼是否會導致相同的行爲?

不,因爲同樣的原因,它們具有完全不同的類型。

指針方法是否爲匿名數組分配內存以保存除指針本身外的字符串,而數組方法只爲數組分配內存?

是,與「匿名」創建陣列可以再次在另一個地方,如果相同的字符串文字使用(但在一般情況下,你可以不知道什麼編譯器實際上沒有)使用:

只要它們的元素具有適當的值,那麼這些數組是否不同是未指定的。

再說一遍,第二行只是用於初始化數組的synctactic糖。