數(shù)組、指針、字符串字面量、以及數(shù)組到指針的隱式轉(zhuǎn)換
數(shù)組名就是指向其首元素的指針。
你可能聽說過,甚至在你的教材上看見過這樣的說法。但這種說法十分不嚴(yán)謹(jǐn),甚至可以說是大錯(cuò)特錯(cuò)。正式的說法是:“發(fā)生了數(shù)組到指針的隱式轉(zhuǎn)換,數(shù)組隱式轉(zhuǎn)換為指向其首元素的指針”。
隱式轉(zhuǎn)換非常常見,甚至很多場景你都沒有意識到發(fā)生了隱式轉(zhuǎn)換。例如:
double d=1;
在這里,字面量1的類型是int,在初始化d的時(shí)候會發(fā)生隱式轉(zhuǎn)換,從int轉(zhuǎn)換到double。
隱式轉(zhuǎn)換還有一點(diǎn)值得注意的是,隱式轉(zhuǎn)換得到的值可能和原來的值不同。例如浮點(diǎn)轉(zhuǎn)換到整數(shù)的時(shí)候會舍棄小數(shù),大整數(shù)類型轉(zhuǎn)換到小整數(shù)類型可能會發(fā)生截?cái)唷?/span>
隱式轉(zhuǎn)換有很多細(xì)節(jié),并且C和C++之間也有很多差異,建議大家參考cppreference中關(guān)于隱式轉(zhuǎn)換的說明。而數(shù)組到指針轉(zhuǎn)換是其中的一條規(guī)則,具體如下:
除了下列語境,任何數(shù)組類型的左值表達(dá)式都會轉(zhuǎn)換為指向其首元素的指針右值:? ? ? ?
? ? ? ?

1、以字符串字面量初始化字符數(shù)組:
這等價(jià)于:
注意末尾包含一個(gè)結(jié)束符。
這是專屬于字符串字面量的特殊規(guī)則。所以用一個(gè)數(shù)組初始化另一個(gè)數(shù)組也是不行的:
并且這僅適用于初始化。數(shù)組不能作為賦值運(yùn)算符的左操作數(shù)——它會隱式轉(zhuǎn)換為一個(gè)指針右值,而右值是不能被賦值的。
此外,在C++中,被初始化的這個(gè)字符數(shù)組的長度不能小于字符串的長度加一,也就是必須能放得下字符串字面量末尾的結(jié)束符,而C語言允許丟棄結(jié)束符:
這里提到字符串字面量,是因?yàn)樽址置媪吭贑和C++中都是左值表達(dá)式,并且指代一個(gè)數(shù)組。例如"Hello world"在C語言中的類型是char[12]而C++中則是const char[12](注意const的區(qū)別,雖然C語言中沒有const限定,但是試圖修改它卻是未定義行為。不要嘗試"Hello world"[0] = 'B')。
2、用作取地址運(yùn)算符&的操作數(shù):
上面提到,字符串字面量是指代數(shù)組的左值表達(dá)式,因此可以對它取地址。&"Hello world"在C中會得到char(*)[12],C++中則是const char(*)[12]。注意這和隱式轉(zhuǎn)換得到的指針類型是不同的,對于數(shù)組T array[N],取地址得到的是T(*)[N],而隱式轉(zhuǎn)換得到的是T*。
3、用作sizeof運(yùn)算符的操作數(shù):
sizeof用在數(shù)組上會得到數(shù)組的總字節(jié)大小,例如上圖sizeof(str)會得到12,而sizeof(char*)則根據(jù)系統(tǒng)不同可能是4(32位)或者8(64位)甚至別的值。
4、用作alignof/_Alignof運(yùn)算符的操作數(shù):
獲取對齊要求可能比較少見,alignof用在數(shù)組上得到的是其元素類型的對齊,由于alignof只接受類型名作為實(shí)參,通常不會造成歧義。?
5、綁定到對應(yīng)類型的數(shù)組引用:
這是C++特有的語法,可以將引用綁定到數(shù)組,需要注意的是類型和長度必須匹配才能綁定,否則會報(bào)錯(cuò)。
6、用作decltype說明符的實(shí)參:?
這是C++特有的語法,用于獲取某個(gè)對象或表達(dá)式的類型與值類別。當(dāng)表達(dá)式的類型為數(shù)組時(shí),不會發(fā)生隱式轉(zhuǎn)換。例如圖中decltype(str) str2,str2的類型推導(dǎo)為char[12]。?
也就是說,對于某個(gè)數(shù)組 T array[N],在除了上述語境中,array都會被轉(zhuǎn)換為&array[0]。這也是開頭那句話的來源。在程序中使用array這個(gè)名字時(shí),array永遠(yuǎn)都指代一個(gè)數(shù)組,但是很多語境都不接受數(shù)組,于是發(fā)生了隱式轉(zhuǎn)換,T[N]變成了T*。這個(gè)過程有時(shí)也稱為數(shù)組到指針的退化,因?yàn)閿?shù)組的長度信息在隱式轉(zhuǎn)換的過程中丟失了。
QQ頻道【std::forward編程社區(qū)】歡迎各位前來交流。
頻道號:wxj6l1350o
入頻鏈接:https://pd.qq.com/s/alapspris