2017-09-16 135 views
-2

在C中,字符*使變量成爲指針。因此,人們會假定某些變量char *是一個指向char的指針,但不知何故它可以成爲一個char數組。這怎麼可能?char *如何映射到字符串

+2

在任何C書說明。 –

+0

它不限於'char *'。一個'int *'可以很好地指向int數組中的一個元素。 –

+0

@BoPersson:是的。但'char *'更突出,因爲有幾十個標準庫函數將'char *'指針指向字符串作爲參數。 –

回答

1

與許多語言相比,C有一個相當弱的類型系統。即使存在更強類型的可能性,例如enum,它們通常不被使用。因此,在處理C庫時,您需要弄清楚給定的API使用的約定,而不僅僅是其簽名。許多圖書館在內部至少保持一致。

編譯器將​​語法轉換爲對某個未命名數組的引用,如char __anonymous[] = {'a', 'b', 'c', '\0'};。所以這是一個非常普遍的慣例。

請注意,適當使用const將使許多約定更容易遵循。字符串文字不是const的唯一原因是因爲該關鍵字在C的早期不存在;它仍然是未定義的行爲來修改它們。

+0

這不是事實。它們是常量,因爲它們保存在內存/磁盤的RO部分中。 –

+0

@ PeterJ_01:它們可能會也可能不會,具體取決於實現。 –

+0

您在匿名數組聲明中使用了'const'。正如你指出的那樣,C字符串文字不是'const'。字符串文字「hello」指的是類型爲char [6]的匿名對象。 –

4

術語「串」和「指針爲字符串」中的C standard定義,7.1.1第1段:

是通過和包括該終止字符 的連續序列第一個空字符。 術語多字節字符串有時用於代替 強調對包含在字符串中的多字節字符 進行特殊處理,或者避免與寬字符串 混淆。 A 指向字符串的指針是指向其最初的 (最低地址)字符的指針。所述長度的字符串 的是一個空字符, 字符串的值之前的字節數是 所包含的字符的值的序列,爲了。

(鏈接是n1570.pdf,2011年的ISO C標準的最新公開可用草案)

中有C.沒有字符串類型的字符串是一種數據格式,而不是數據類型。字符串通常存儲在char的數組中。

至於指向字符串的指針,因爲標準說這是指向其第一個字符的指針。 C通常通過指向數組單個元素的指針處理數組。指針運算讓我們通過數組中的連續元素前進一個指針。 (某些語言可以讓你將數組作爲整個對象來處理;你不能輕易地在C中做到這一點)。

有些來源會告訴你數組實際上是指針,或者char*是一個字符串。這些來源是錯誤的。數組不是指針,指針也不是數組。造成這種混淆的原因是數組通常使用指針進行操作,特殊語言規則指出數組表達式被「轉換」爲指向數組初始元素的指針。但是,該轉換(實際上是編譯時調整)僅適用於數組表達式,而不適用於數組或指針對象。另一個混淆的原因是數組參數被「調整」爲指針類型;例如void foo(int n[10])的確表示int foo(int *n)

char*甲從未「變成」對需要處理的char秒的陣列的char秒的陣列,但代碼將通過char*指針可以被推進到指向該陣列的連續元素這樣做。並且char[]數組可能包含或不包含字符串,具體取決於它是否包含所需的終止空字符'\0'

推薦閱讀:comp.lang.c FAQ,特別是第6節

+1

我認爲造成混淆的另一個原因可能是數組類型在函數聲明中被調整爲合適的指針類型,所以'void func(char arr []);','void func (char arr [10]);'和'void func(char * arr);'都是等價的。 –

+0

@DavidBowling:好點,我已經更新了我的答案。 –