2022-11-15數(shù)組與指針

數(shù)組

數(shù)組由數(shù)據(jù)類型相同的一系列元素組成辩撑。 需要使用數(shù)組時伞辛, 通過聲明數(shù)組告訴編譯器數(shù)組中內(nèi)含多少元素和這些元素的類型沮焕。 編譯器根據(jù)這些信息正確地創(chuàng)建數(shù)組。

/* 一些數(shù)組聲明*/

int main(void)

{

?float candy[365]; /* 內(nèi)含365個float類型元素的數(shù)組 */

char code[12]; /*內(nèi)含12個char類型元素的數(shù)組*/

int states[50]; /*內(nèi)含50個int類型元素的數(shù)組 */

...

}

方括號([]) 表明candy模燥、 code和states都是數(shù)組, 方括號中的數(shù)字表明數(shù)組中的元素個數(shù)掩宜。

要訪問數(shù)組中的元素蔫骂, 通過使用數(shù)組下標(biāo)數(shù)(也稱為索引) 表示數(shù)組中的各元素。

初始化數(shù)組

數(shù)組通常被用來儲存程序需要的數(shù)據(jù)牺汤。只儲存單個值的變量有時也稱為標(biāo)量變量(scalar variable)

用以逗號分隔的值列表(用花括號括起來) 來初始化數(shù)組辽旋,各值之間用逗號分隔。 在逗號和值之間可以使用空格慧瘤。

每4年打錯一個月份的天數(shù)(即戴已, 2月份的天數(shù)) 。 該程序用初始化列表初始化days[]锅减, 列表(用花括號括起來) 中用逗號分隔各值糖儡。符號常量 MONTHS 表示數(shù)組大小

使用const聲明數(shù)組有時需要把數(shù)組設(shè)置為只讀。 這樣怔匣, 程序只能從數(shù)組中檢索值握联, 不能把新值寫入數(shù)組。 要創(chuàng)建只讀數(shù)組每瞒, 應(yīng)該用const聲明和初始化數(shù)組金闽。

在使用數(shù)組元素之前,必須先給它們賦初值剿骨。 編譯器使用的值是內(nèi)存相應(yīng)位置上的現(xiàn)有值代芜。

注意 存儲類別警告

數(shù)組和其他變量類似, 可以把數(shù)組創(chuàng)建成不同的存儲類別(storageclass)浓利。

存儲類別的原因是挤庇, 不同的存儲類別有不同的屬性钞速。

初始化列表中的項數(shù)應(yīng)與數(shù)組的大小一致。

當(dāng)初始化列表中的值少于數(shù)組元素個數(shù)時嫡秕, 編譯器會把剩余的元素都初始化為0渴语。 也就是說, 如果不初始化數(shù)組昆咽,數(shù)組元素和未初始化的普通變量一樣驾凶, 其中儲存的都是垃圾值; 但是掷酗, 如果部分初始化數(shù)組调违, 剩余的元素就會被初始化為0。

如果初始化列表的項數(shù)多于數(shù)組元素個數(shù)泻轰,編譯器會毫不留情地將其視為錯誤翰萨。

如果初始化數(shù)組時省略方括號中的數(shù)字, 編譯器會根據(jù)初始化列表中的項數(shù)來確定數(shù)組的大小糕殉。sizeof運(yùn)算符給出它的運(yùn)算對象的大心豆怼(以字節(jié)為單位) 。 所以sizeof days是整個數(shù)組的大邪⒌(以字節(jié)為單位) 雳锋, sizeof day[0]是數(shù)組中一個元素的大小(以字節(jié)為單位) 羡洁。 整個數(shù)組的大小除以單個元素的大小就是數(shù)組元素的個數(shù)玷过。

指定初始化器(C99)

C99 增加了一個新特性: 指定初始化器(designated initializer) 。 利用該特性可以初始化指定的數(shù)組元素筑煮。

而C99規(guī)定辛蚊, 可以在初始化列表中使用帶方括號的下標(biāo)指明待初始化的元素。

對于一般的初始化真仲, 在初始化一個元素后袋马, 未初始化的元素都會被設(shè)置為0。

初始化器的兩個重要特性,第一秸应, 如果指定初始化器后面有更多的值虑凛,那么后面這些值將被用于初始化指定元素后面的元素。第二软啼, 如果再次初始化指定的元素桑谍, 那么最后的初始化將會取代之前的初始化。

編譯器會把數(shù)組的大小設(shè)置為足夠裝得下初始化的值祸挪。

給數(shù)組元素賦值

聲明數(shù)組后锣披, 可以借助數(shù)組下標(biāo)(或索引) 給數(shù)組元素賦值。

C 不允許把數(shù)組作為一個單元賦給另一個數(shù)組, 除初始化以外也不允許使用花括號列表的形式賦值雹仿。

數(shù)組邊界

在使用數(shù)組時榜跌, 要防止數(shù)組下標(biāo)超出邊界。 也就是說盅粪, 必須確保下標(biāo)是有效的值。

創(chuàng)建了一個內(nèi)含4個元素的數(shù)組悄蕾, 然后錯誤地使用了-1~6的下標(biāo)票顾。

在C標(biāo)準(zhǔn)中, 使用越界下標(biāo)的結(jié)果是未定義的帆调。

該編譯器似乎把value2儲存在數(shù)組的前一個位置奠骄, 把value1儲存在數(shù)組的后一個位置(其他編譯器在內(nèi)存中儲存數(shù)據(jù)的順序可能不同)。使用越界的數(shù)組下標(biāo)會導(dǎo)致程序改變其他變量的值番刊。不同的編譯器運(yùn)行該程序的結(jié)果可能不同含鳞, 有些會導(dǎo)致程序異常中止。

數(shù)組元素的編號從0開始芹务。 最好是在聲明數(shù)組時使用符號常量來表示數(shù)組的大小這樣做能確保整個程序中的數(shù)組大小始終一致

指定數(shù)組大小

#define SIZE 4

int main(void)

{

?intarr[SIZE]; // 整數(shù)符號常量

double lots[144]; // 整數(shù)字面常量蝉绷。

....

}

在C99標(biāo)準(zhǔn)之前, 聲明數(shù)組時只能在方括號中使用整型常量表達(dá)式枣抱。 所謂整型常量表達(dá)式熔吗, 是由整型常量構(gòu)成的表達(dá)式。 sizeof表達(dá)式被視為整型常量佳晶, 但是(與C++不同) const值不是桅狠。

C99引入變長數(shù)組主要是為了讓C成為更好的數(shù)值計算語言。

多維數(shù)組

二維視圖有助于幫助理解二維數(shù)組的兩個下標(biāo)轿秧。在計算機(jī)內(nèi)部中跌,這樣的數(shù)組是按順序儲存的, 從第1個內(nèi)含12個元素的數(shù)組開始菇篡, 然后是第2個內(nèi)含12個元素的數(shù)組漩符, 以此類推。

程序使用了兩個嵌套for循環(huán)驱还。 第1個嵌套for循環(huán)的內(nèi)層循環(huán)陨仅, 在year不變的情況下, 遍歷month計算某年的總降水量铝侵; 而外層循環(huán)灼伤, 改變year的值, 重復(fù)遍歷month咪鲜, 計算5年的總降水量狐赡。

初始化二維數(shù)組

初始化二維數(shù)組是建立在初始化一維數(shù)組的基礎(chǔ)上。

如果某列表中的數(shù)值個數(shù)超出了數(shù)組每行的元素個數(shù)疟丙, 則會出錯颖侄, 但是這并不會影響其他行的初始化鸟雏。

初始化時也可省略內(nèi)部的花括號, 只保留最外面的一對花括號览祖。只要保證初始化的數(shù)值個數(shù)正確孝鹊, 初始化的效果與上面相同。 但是如果初始化的數(shù)值不夠展蒂, 則按照先后順序逐行初始化又活, 直到用完所有的值。 后面沒有值初始化的元素被統(tǒng)一初始化為0锰悼。

因為儲存在數(shù)組rain中的數(shù)據(jù)不能修改柳骄, 所以程序使用了const關(guān)鍵字聲明該數(shù)組。

其他多維數(shù)組

處理三維數(shù)組要使用3重嵌套循環(huán)箕般, 處理四維數(shù)組要使用4重嵌套循環(huán)耐薯。 對于其他多維數(shù)組, 以此類推丝里。

指針和數(shù)組

指針提供一種以符號形式使用地址的方法曲初。使用指針的程序更有效率。 尤其是杯聚, 指針能有效地處理數(shù)組复斥。數(shù)組表示法其實是在變相地使用指針。

第2行打印的是兩個數(shù)組開始的地址械媒, 下一行打印的是指針加1后的地址目锭, 以此類推。

在C中纷捞, 指針加1指的是增加一個存儲單元痢虹。 對數(shù)組而言, 這意味著把加1后的地址是下一個元素的地址主儡, 而不是下一個字節(jié)的地址 這是為什么必須聲明指針?biāo)赶驅(qū)ο箢愋偷脑蛑弧?只知道地址不夠奖唯, 因為計算機(jī)要知道儲存對象需要多少字節(jié)(即使指針指向的是標(biāo)量變量, 也要知道變量的類型糜值, 否則*pt 就無法正確地取回地址上的值) 丰捷。

指針的值是它所指向?qū)ο蟮牡刂贰?地址的表示方式依賴于計算機(jī)內(nèi)部的硬件。 許多計算機(jī)(包括PC和Macintosh) 都是按字節(jié)編址寂汇, 意思是內(nèi)存中的每個字節(jié)都按順序編號病往。 這里, 一個較大對象的地址(如double類型的變量) 通常是該對象第一個字節(jié)的地址骄瓣。

在指針前面使用*運(yùn)算符可以得到該指針?biāo)赶驅(qū)ο蟮闹怠?/p>

指針加1停巷, 指針的值遞增它所指向類型的大小(以字節(jié)為單位) 。

數(shù)組和指針的關(guān)系十分密切畔勤, 可以使用指針標(biāo)識數(shù)組的元素和獲得元素的值蕾各。 從本質(zhì)上看, 同一個對象有兩種表示法庆揪。C語言標(biāo)準(zhǔn)在描述數(shù)組表示法時確實借助了指針式曲。

days是數(shù)組首元素的地址, days + index是元素days[index]的地址缸榛, 而*(days + index)則是該元素的值吝羞, 相當(dāng)于days[index]。 for循環(huán)依次引用數(shù)組中的每個元素仔掸, 并打印各元素的內(nèi)容。

函數(shù)医清、數(shù)組和指針

total = sum(marbles); // 可能的函數(shù)調(diào)用

數(shù)組名是該數(shù)組首元素的地址起暮, 所以實際參數(shù)marbles是一個儲存int類型值的地址, 應(yīng)把它賦給一個指針形式參數(shù)会烙, 即該形參是一個指向int的指針

int sum(int * ar); // 對應(yīng)的函數(shù)原型

sum()獲得了該數(shù)組首元素的地址负懦, 知道要在該位置上找出一個整數(shù)。 注意柏腻, 該參數(shù)并未包含數(shù)組元素個數(shù)的信息纸厉。我們有兩種方法讓函數(shù)獲得這一信息。 第一種方法是五嫂, 在函數(shù)代碼中寫上固定的數(shù)組大小

指針表示數(shù)組名颗品, 也可以用數(shù)組名表示指針。 +=運(yùn)算符把右側(cè)運(yùn)算對象加到左側(cè)運(yùn)算對象上沃缘。

注意 聲明數(shù)組形參數(shù)組名是該數(shù)組首元素的地址躯枢, 作為實際參數(shù)的數(shù)組名要求形式參數(shù)是一個與之匹配的指針。

marbles是一個數(shù)組槐臀, ar是一個指向marbles數(shù)組首元素的指針锄蹂, 利用C中數(shù)組和指針的特殊關(guān)系, 可以用數(shù)組表示法來表示指針ar水慨。

使用指針形參

sum()函數(shù)使用一個指針形參標(biāo)識數(shù)組的開始得糜, 用一個整數(shù)形參表明待處理數(shù)組的元素個數(shù)(指針形參也表明了數(shù)組中的數(shù)據(jù)類型) 。 但是這并不是給函數(shù)傳遞必備信息的唯一方法晰洒。 還有一種方法是傳遞兩個指針朝抖, 第1個指針指明數(shù)組的開始處(與前面用法相同) , 第2個指針指明數(shù)組的結(jié)束處谍珊。

指針start開始指向marbles數(shù)組的首元素槽棍, 所以賦值表達(dá)式total += *start把首元素(20) 加給total。 然后, 表達(dá)式start++遞增指針變量start炼七, 使其指向數(shù)組的下一個元素缆巧。 因為start是指向int的指針, start遞增1相當(dāng)于其值遞增int類型的大小豌拙。

因為while循環(huán)的測試條件是一個不相等的關(guān)系陕悬, 所以循環(huán)最后處理的一個元素是end所指向位置的前一個元素。 這意味著end指向的位置實際上在數(shù)組最后一個元素的后面按傅。 C保證在給數(shù)組分配空間時捉超, 指向數(shù)組后面第一個位置的指針仍是有效的指針。

total += *start++;

一元運(yùn)算符*和++的優(yōu)先級相同唯绍, 但結(jié)合律是從右往左拼岳, 所以start++先求值, 然后才是*start况芒。 也就是說惜纸, 指針start先遞增后指向。 使用后綴形式(即start++而不是++start) 意味著先把指針指向位置上的值加到total上绝骚, 然后再遞增指針耐版。 如果使用*++start, 順序則反過來压汪, 先遞增指針粪牲, 再使用指針指向位置上的值。 如果使用(*start)++止剖, 則先使用start指向的值腺阳, 再遞增該值, 而不是遞增指針穿香。 這樣舌狗, 指針將一直指向同一個位置, 但是該位置上的值發(fā)生了變化扔水。

只有(*p3)++改變了數(shù)組元素的值痛侍, 其他兩個操作分別把p1和p2指向數(shù)組的下一個元素

指針表示法和數(shù)組表示法

處理數(shù)組的函數(shù)實際上用指針作為參數(shù), 但是在編寫這樣的函數(shù)時魔市, 可以選擇是使用數(shù)組表示法還是指針表示法主届。使用數(shù)組表示法, 讓函數(shù)是處理數(shù)組的這一意圖更加明顯待德。

C語言君丁, ar[i]和*(ar+1)這兩個表達(dá)式都是等價的。 無論ar是數(shù)組名還是指針變量将宪, 這兩個表達(dá)式都沒問題绘闷。 但是橡庞, 只有當(dāng)ar是指針變量時, 才能使用ar++這樣的表達(dá)式印蔗。

指針表示法(尤其與遞增運(yùn)算符一起使用時) 更接近機(jī)器語言扒最, 因此一些編譯器在編譯時能生成效率更高的代碼。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末华嘹,一起剝皮案震驚了整個濱河市吧趣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耙厚,老刑警劉巖强挫,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異薛躬,居然都是意外死亡俯渤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門型宝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來八匠,“玉大人,你說我怎么就攤上這事诡曙⊥涡穑” “怎么了略水?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵价卤,是天一觀的道長。 經(jīng)常有香客問我渊涝,道長慎璧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任跨释,我火速辦了婚禮胸私,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳖谈。我一直安慰自己岁疼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布缆娃。 她就那樣靜靜地躺著捷绒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贯要。 梳的紋絲不亂的頭發(fā)上暖侨,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音崇渗,去河邊找鬼字逗。 笑死京郑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葫掉。 我是一名探鬼主播些举,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挖息!你這毒婦竟也來了金拒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤套腹,失蹤者是張志新(化名)和其女友劉穎绪抛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體电禀,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡幢码,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了尖飞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片症副。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖政基,靈堂內(nèi)的尸體忽然破棺而出贞铣,到底是詐尸還是另有隱情,我是刑警寧澤沮明,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布辕坝,位于F島的核電站,受9級特大地震影響荐健,放射性物質(zhì)發(fā)生泄漏酱畅。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一江场、第九天 我趴在偏房一處隱蔽的房頂上張望纺酸。 院中可真熱鬧,春花似錦址否、人聲如沸餐蔬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽樊诺。三九已至,卻和暖如春帮匾,著一層夾襖步出監(jiān)牢的瞬間啄骇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工瘟斜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留缸夹,地道東北人痪寻。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓填物,卻偏偏與公主長得像娶桦,于是被迫代替她去往敵國和親缝彬。 傳聞我的和親對象是個殘疾皇子还棱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

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