第四章 指針與數(shù)組

一說(shuō)到指針和數(shù)組,很多人都會(huì)潛意識(shí)的認(rèn)為它們是等同的鳄炉,但事實(shí)上指針和數(shù)組只在某些前提下等同。本篇將詳細(xì)介紹這些知識(shí)。

4.1 指針等同于數(shù)組的情況

ANSI C中關(guān)于什么時(shí)候數(shù)組和指針時(shí)相同的障癌,定義了如下規(guī)則:

規(guī)則1.表達(dá)式中的數(shù)組名被編譯器當(dāng)作一個(gè)指向該數(shù)組第一個(gè)元素的指針(具體見ANSI C標(biāo)準(zhǔn)第6.2.2.1節(jié))。
規(guī)則2.下標(biāo)總是與指針的偏移量相同(具體見ANSI C標(biāo)準(zhǔn)第6.3.2.1節(jié))辩尊。
規(guī)則3.在函數(shù)參數(shù)的聲明中涛浙,數(shù)組名被編譯器當(dāng)作指向該數(shù)組第一個(gè)元素的指針(具體見ANSI C標(biāo)準(zhǔn)第6.7.2.1節(jié))。

根據(jù)規(guī)則1和規(guī)則2摄欲,我們可以知道轿亮,對(duì)數(shù)組下標(biāo)的引用總是可以寫成“一個(gè)指向數(shù)組的起始地址的指針加上偏移量”。

例如胸墙,我們聲稱:int a[10]; int *p,i=2;則我注,我們可以通過(guò)以下的方式來(lái)訪問a[i]:

int a[10]; int *p,i=2;
p=a;  p[i];
p=a;  *(p + 1);
p=a+i;  *p;

根據(jù)規(guī)則1、2迟隅,對(duì)數(shù)組的引用如a[i]在編譯時(shí)總是被編譯器改寫成(a+i)但骨。不管你是人為的顯示用(a+i)表達(dá)式還是a[i],最終在編譯器那都是*(a+i)玻淑。這也是人們常說(shuō)指針和數(shù)組相同的原因之一嗽冒。因?yàn)榇藭r(shí),不管是真的指針還是數(shù)組补履,都可以用指針\數(shù)組表示方法來(lái)取值添坊。

根據(jù)規(guī)則3,我們可以知道箫锤,在函數(shù)的形參中贬蛙,不管你是寫數(shù)組還是指針,最后編譯器都會(huì)按照指針的方式進(jìn)行解釋谚攒,也就是說(shuō)以下幾種方式是等價(jià)的:

int Func(int *pNow);
int Func(int Now[]);
int Func(int Now[200]);

因?yàn)檫@幾種聲明方式的最終結(jié)果都是int Func(int*)阳准;

C語(yǔ)言之所以把數(shù)組形參解釋成指針的主要原因是為了提高參數(shù)傳遞的效率。因?yàn)榘褦?shù)組名解釋成指向數(shù)組第一個(gè)元素的指針后馏臭,在參數(shù)傳遞的時(shí)候只需要把第一個(gè)元素的地址賦值給形參就行了野蝇,而不必將整個(gè)數(shù)組的值都賦值給形參。和這個(gè)道理類似,函數(shù)的返回值也不能是數(shù)組绕沈,而應(yīng)用指針代替锐想。但不同的是,在語(yǔ)法上函數(shù)的參數(shù)可以是數(shù)組(實(shí)質(zhì)是指針)而函數(shù)的返回值不能是數(shù)組乍狐。

由于C語(yǔ)言并不提供對(duì)數(shù)組邊界的檢查赠摇,而且這種檢查即費(fèi)時(shí)也沒有必要。所以浅蚪,上述第二中寫法和第三種寫法是相同的藕帜。只有在定義數(shù)組時(shí),數(shù)組的長(zhǎng)度才是必要的惜傲,其他的情況下有沒有數(shù)組的長(zhǎng)度都無(wú)關(guān)緊要洽故。

注:由于形參中的數(shù)組總是被轉(zhuǎn)換為指向數(shù)組第一個(gè)元素的指針,所以用sizeof取的數(shù)組的大小始終是4操漠。因?yàn)橹羔樀拇笮【褪?收津。

4.2 指針和數(shù)組的區(qū)別

如果指針和數(shù)組沒有區(qū)別,那么就不需要這兩種基本數(shù)據(jù)類型了浊伙。由于撞秋,指針和數(shù)組是常見的數(shù)據(jù)類型,我只簡(jiǎn)要的羅列下它們的區(qū)別嚣鄙。

區(qū)別1:指針只占4個(gè)字節(jié)吻贿,而數(shù)組將根據(jù)其長(zhǎng)度占據(jù)一定的連續(xù)的空間。
區(qū)別2:雖然在表達(dá)式中數(shù)組名解釋為指向數(shù)組中第一個(gè)元素的指針哑子,但是用sizeof(數(shù)組名)得到的是整個(gè)數(shù)組的大小而不是4舅列。
區(qū)別3:指針是可以修改的左值,而數(shù)組名是不可以修改的左值卧蜓。
  例:int a[10],b[10]; a=b;(非法)
  注:左值是指編譯時(shí)可知的用于存儲(chǔ)結(jié)果的地方帐要。右值是指直到運(yùn)行時(shí)才知道的某個(gè)地址的內(nèi)容。
區(qū)別4:定義一個(gè)字符指針并初始化一個(gè)字符串和定義一個(gè)數(shù)組并初始化一個(gè)字符串是不一樣的弥奸。
  例:char a[]=”abcdefg”; 和char *a=”abcdefg”;不一樣榨惠。
     前者是局部/全局(取決于定義的位置),后者存儲(chǔ)于常量區(qū)盛霎,不能再修改赠橙。兩者都以’\0’結(jié)束。
  注:只有字符串常量才能在定義時(shí)給char *p賦值愤炸,其他類型的不行期揪,例如int *p = 1; 錯(cuò)誤
區(qū)別5:數(shù)組和指針訪問元素的過(guò)程不一樣。
  由于數(shù)組的名字就是數(shù)組第一個(gè)元素的地址规个,而指針的名字是指針的地址凤薛,指針地址里的內(nèi)容是數(shù)組首元素的地址姓建,所以再用指針訪問時(shí)會(huì)多一次間接尋址。
  例:char a []="abcdefg"; char *p = a;則:
    a[i]的訪問方式是:先取i的值枉侧,再加上a引瀑,再在此地址中取值。
    p[i]的訪問方式是:先通過(guò)p的值取出a的值榨馁,再取i的值,再加上a帜矾,再在此地址中取值翼虫。

當(dāng)我們把某個(gè)變量聲明為數(shù)組時(shí),它就會(huì)按照數(shù)組的方式存儲(chǔ)屡萤,當(dāng)我們?cè)诒磉_(dá)式中用到此數(shù)組名時(shí)珍剑,雖然它總是被解釋為*(a+i)的形式,但此時(shí)編譯知道a是數(shù)組名死陆,它的值就是數(shù)組首元素的地址了招拙,此時(shí)不需要間接尋址的。而對(duì)于指針措译,則會(huì)多一次間接尋址别凤。

注:通過(guò)區(qū)別5,我們知道指針和數(shù)組在取值時(shí)的過(guò)程不一樣领虹。那么我們就不要指望在定義和使用時(shí)分別用指針和數(shù)組了规哪。(此處不是只形式,而是指實(shí)質(zhì))比如塌衰,在一個(gè)文件中定義int a[20];而在另一個(gè)文件中聲明extern int *a;不要指望后面這個(gè)a指針就是前面的數(shù)組诉稍,因?yàn)榇藭r(shí)在前面一個(gè)文件中對(duì)a的引用時(shí)數(shù)組方式,而在后一個(gè)文件中對(duì)a的引用是指針方式最疆,這兩種方式不可能相等杯巨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市努酸,隨后出現(xiàn)的幾起案子服爷,更是在濱河造成了極大的恐慌,老刑警劉巖蚊逢,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件层扶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡烙荷,警方通過(guò)查閱死者的電腦和手機(jī)镜会,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)终抽,“玉大人戳表,你說(shuō)我怎么就攤上這事桶至。” “怎么了匾旭?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵镣屹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我价涝,道長(zhǎng)女蜈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任色瘩,我火速辦了婚禮伪窖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘居兆。我一直安慰自己覆山,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布泥栖。 她就那樣靜靜地躺著簇宽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吧享。 梳的紋絲不亂的頭發(fā)上魏割,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音耙蔑,去河邊找鬼见妒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛甸陌,可吹牛的內(nèi)容都是我干的须揣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼钱豁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耻卡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起牲尺,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤卵酪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谤碳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溃卡,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年蜒简,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘸羡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搓茬,死狀恐怖犹赖,靈堂內(nèi)的尸體忽然破棺而出队他,到底是詐尸還是另有隱情,我是刑警寧澤峻村,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布麸折,位于F島的核電站,受9級(jí)特大地震影響粘昨,放射性物質(zhì)發(fā)生泄漏垢啼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一雾棺、第九天 我趴在偏房一處隱蔽的房頂上張望膊夹。 院中可真熱鬧,春花似錦捌浩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至助币,卻和暖如春浪听,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背眉菱。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工迹栓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俭缓。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓克伊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親华坦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子愿吹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容