注:這篇文章中涉及的很多內(nèi)容,都跟自己的硬件直接相關(guān)喷舀,所以砍濒,讀者如果自行嘗試,可能會(huì)得到不一致的結(jié)果硫麻。不過針對本文爸邢,一般結(jié)果應(yīng)該是一致的。
在C語言中拿愧,類型轉(zhuǎn)換是一件很惱人的事情杠河。我們必須理解到底是如何進(jìn)行類型轉(zhuǎn)換的,以及各種計(jì)算機(jī)內(nèi)部的操作浇辜,才能在出現(xiàn)各種稀奇古怪的事件時(shí)券敌,做到處之泰然。
一般的變量之間的類型的相互轉(zhuǎn)換柳洋,倒也還好說待诅。然而,指針變量之間的類型轉(zhuǎn)換熊镣,卻有些麻煩卑雁。
下面我以一個(gè)例子說明,指針變量之間進(jìn)行類型轉(zhuǎn)換時(shí)轧钓,其內(nèi)部到底都發(fā)生了什么序厉。
先上代碼:
這段代碼是干什么用的呢?它會(huì)打印出65所對應(yīng)的ASCII碼毕箍,也就是"A".如果只是單純的想進(jìn)行這個(gè)轉(zhuǎn)換弛房,我們使用普通變量之間的類型轉(zhuǎn)換,就完全足夠而柑。這里我們?yōu)榱肆私馄渲羔樧兞恐g的類型轉(zhuǎn)換的過程文捶,所以使用指針來做。
我們首先驗(yàn)證一下結(jié)果:
從上圖中媒咳,我們可以看到粹排,結(jié)果確實(shí)是"A"。與ASCII碼表中一致涩澡。
那么其背后到底發(fā)生了什么呢?為什么會(huì)轉(zhuǎn)換成"A"?
首先顽耳,我們都知道,指針變量實(shí)際上存儲(chǔ)的是內(nèi)存中的一塊地址妙同,也就是說射富,這里指針變量a實(shí)際上c這個(gè)變量的地址,假設(shè)其邏輯內(nèi)存地址為0x7ffd0d8824ec粥帚,則有下圖:
要明白為什么其會(huì)被轉(zhuǎn)換成"A",我們需要了解c這個(gè)變量胰耗,也就是0x7ffd0d8824ec這個(gè)內(nèi)存地址上,65是如何存放的芒涡。在我的機(jī)器上柴灯,int類型的長度為4卖漫,所以65轉(zhuǎn)換成四個(gè)字節(jié)的十六進(jìn)制形式為:0x00000041.我們還需要了解機(jī)器上,是按小端存儲(chǔ)還是大端存儲(chǔ)的方式來存儲(chǔ)的赠群。在上面的代碼中羊始,被注釋的那幾行就是用來測試機(jī)器上的存儲(chǔ)方式。這里我得到我機(jī)器上的存儲(chǔ)方式為小端存儲(chǔ)乎串。所以店枣,實(shí)際的存儲(chǔ)方式如下圖:
然后,我們將a這個(gè)int類型的指針變量叹誉,經(jīng)過類型轉(zhuǎn)換后,賦值給b這個(gè)變量闷旧,現(xiàn)在a,b,c三個(gè)變量之間的關(guān)系长豁,就如下圖所示:
指針變量的類型,就好比一個(gè)標(biāo)簽忙灼,用于讀取實(shí)際的值時(shí)匠襟,判斷如何進(jìn)行解析。a這個(gè)指針變量该园,其類型為int,所以其在解析時(shí)酸舍,會(huì)讀取0x7ffd0d8824ec之后的四個(gè)字節(jié)。而b這個(gè)指針變量里初,因?yàn)槠漕愋蜑閏har,其長度為1個(gè)字節(jié)啃勉,所以其在解析時(shí),會(huì)讀取地址為0x7ffd0d8824ec這一個(gè)字節(jié)双妨。
因?yàn)槭前葱《舜鎯?chǔ)的方式淮阐,所以b在解析時(shí),讀取一個(gè)字節(jié)刁品,正好讀到0x41,其對應(yīng)的字符就是A.
你可以嘗試一下泣特,如果c這個(gè)變量的值是321,則b對應(yīng)哪個(gè)字符。答案是挑随,還是A.
從上面的解釋中状您,我們可以看到,關(guān)鍵就在于解析時(shí)指針變量的類型的長度兜挨,所以膏孟,不同類型的指針變量之間,不能胡亂轉(zhuǎn)換暑劝,否則會(huì)因?yàn)轭愋偷拈L度不一致骆莹,出現(xiàn)奇怪的結(jié)果。比如担猛,你可以嘗試一下幕垦,把上面的程序換成char類型的指針變量轉(zhuǎn)換成int類型的指針變量丢氢。結(jié)果會(huì)出乎意料。