C/C++編程筆記:C/C++中數(shù)組名的含義,不同數(shù)組名有不同的含義!
C/C++中的數(shù)組名是個(gè)很奇怪的東西,它到底代表什么呢?

對(duì)于char array[n](n是一個(gè)常數(shù)),大概有這么幾種語義:
<1> char* const(注意不是const char*)?? <2> char [n]
舉例如下:
<1> char *p = array; //array表示char* const,p得到的是數(shù)組的首地址
??? size_t size = sizeof(char [n]); // size等于n
<2> char (*p)[n] = &array; // array表示char [n],
// p得到的仍然是數(shù)組的首地址
char (*q)[n] = array;? // 編譯錯(cuò)誤
??? char (*r)[n] = (char (*)[n])array; // r得到的是array數(shù)組的首地址
<3> char (&p)[n] = array;? // array表示 char [n]
<4> void foo(char a[n])
{
int size = sizeof(a);? // size == 4(32位系統(tǒng)),
// 因?yàn)閍實(shí)際上表示的是char*
};
??? foo(array);??????????? // array表示char* const
<5> void foo(char (&a)[n]);
{
int size = sizeof(a);?? // size == n
};
??? foo(array);?????????? // array表示char [n]
<6> void foo(char (*a)[n]);
{
int size = sizeof(*a);?? // size == n
};
??? foo(&array);?????????? // array表示 char [n]
<7> char *p;
array = p;??
// 編譯錯(cuò)誤"error C2440,無法從char*轉(zhuǎn)化為char [n]",因此array表示char [n]

<8> char other[n];
array = other;?? // 編譯錯(cuò)誤"error C2106, '='左操作數(shù)必須為L值",
// 因此array表示char [n]
(char (&)[n])array = other;
// 執(zhí)行完后array的頭4個(gè)元素表示的32位數(shù)與other代表的數(shù)組首地址相同,
// 在這里other被解釋成char* const
(char (&)[n])array = (char [n])other;
// 執(zhí)行完后array的頭4個(gè)元素表示的32位數(shù)與other代表的數(shù)組首地址相同
(char (&)[n])array = (char (&)[n])other;
// 執(zhí)行完后array數(shù)組與other數(shù)組的頭四個(gè)元素相等
(char (*&)[n])array = (char (*)[n])other;
// (char (*&)[n])表示的是一個(gè)引用類型,
// 這個(gè)引用關(guān)聯(lián)到一個(gè)指向char[n]數(shù)組的指針,
// 執(zhí)行完后array的頭4個(gè)元素表示的32位數(shù)與other代表的數(shù)組首地址相同
(__int64&)array = (__int64&)other;
// 執(zhí)行完后array數(shù)組與other數(shù)組的頭8個(gè)元素相等
<9> long i = 0;
(long &)array = i;??
// 實(shí)際改變的不是array本身的值, 而是它代表的數(shù)組中的頭4個(gè)元素(32位),因此array代表的是char [n]
<10> long i = 0;
(char (&)[n])i = array;
?// 假設(shè)array數(shù)組首地址為0x0012feac, 則指令執(zhí)行后i == 0x0012feac
<11> long i = 0;
(char (&)[n])i = (char (&)[n])array;
// 執(zhí)行后i的值等于array頭4個(gè)元素代表的32位數(shù)(32位系統(tǒng))

<12> (char *&)array = "string";
// 執(zhí)行后array頭4個(gè)元素代表的32位數(shù)與 "string"常量字符串在內(nèi)存中的地址相同
<13> (char (&)[n])array = (char (&)[n])"string";
// array數(shù)組的頭4個(gè)元素依次為's','t','r','i'
? ? ? ?當(dāng)我們進(jìn)行(char [n])array這樣的強(qiáng)制轉(zhuǎn)換時(shí),效果與(char* const)array轉(zhuǎn)換相當(dāng),都被解釋成表示數(shù)組首地址的指針。但是兩者還是有微妙區(qū)別的:sizeof(char [n])等于n,sizeof(char* const)等于4(32位系統(tǒng)),而且象(char [m])array這樣的轉(zhuǎn)換就不允許,其中m不等于n。如果我們用某種引用類型強(qiáng)制轉(zhuǎn)換數(shù)組名時(shí),編譯系統(tǒng)會(huì)將轉(zhuǎn)換結(jié)果(引用類型)自動(dòng)關(guān)聯(lián)到從數(shù)組首地址開始的內(nèi)存區(qū),而非數(shù)組名本身所在的內(nèi)存區(qū)(它是否真的存在于內(nèi)存中都是個(gè)未知數(shù))。

? ? ? ?當(dāng)我們用這樣強(qiáng)制轉(zhuǎn)換過的數(shù)組名做賦值操作的左操作數(shù)時(shí),改變的就是數(shù)組名代表的數(shù)組內(nèi)存區(qū)了,而被改變的內(nèi)存區(qū)的大小就要視引用類型而定,比如__int64&,那么大小就是8字節(jié),其余類推。因?yàn)?char [n])與(char* const)效果基本相當(dāng),結(jié)果都被解釋成指針,所以(char (&)[n])與(char* const &)也基本相當(dāng),結(jié)果就被解釋成關(guān)聯(lián)到指針的引用。當(dāng)用(char (&)[n])array做賦值操作的右操作數(shù)時(shí),實(shí)際上會(huì)從array數(shù)組首地址開始的內(nèi)存區(qū)讀sizeof(char* const)大小的數(shù)據(jù),然后賦值給左操作數(shù)。這就可以解釋為什么(char (&)[n])array = (char (&)[n])other執(zhí)行后array與other的頭4個(gè)元素相等了。
希望對(duì)大家有幫助~

學(xué)習(xí)C/C++編程知識(shí),提升自己的C/C++編程能力,歡迎關(guān)注UP一起來成長~
UP上傳了一些C/C++的學(xué)習(xí)教程,如果有興趣可以去看一下,會(huì)持續(xù)更新的!