數(shù)組的學(xué)習(xí)與運(yùn)用
?/********************************************************************************************************
? ? ? ? ? ? ? ? ? ? ?剛開始學(xué)習(xí)C語(yǔ)言,僅代表自己的學(xué)習(xí)理解,不代表觀點(diǎn)一定正確
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 只做學(xué)習(xí)記錄
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?有錯(cuò)誤的麻煩指出,謝謝!
*********************************************************************************************************/
數(shù)組的概念
數(shù)組就是數(shù)據(jù)的集合,簡(jiǎn)單的說(shuō)數(shù)組就是由n個(gè)數(shù)據(jù)組合在一起,數(shù)組的英文是Array。數(shù)組其實(shí)就是用戶向內(nèi)核申請(qǐng)的一塊空間,只不過(guò)內(nèi)核提供的這塊空間的內(nèi)存地址是連續(xù)的,目的就是方便用戶存儲(chǔ)數(shù)據(jù)和訪問(wèn)數(shù)據(jù)。
數(shù)組的規(guī)定
內(nèi)核為了方便管理這塊內(nèi)存,所以規(guī)定這塊內(nèi)存只能存儲(chǔ)相同類型的數(shù)據(jù)。
想要向內(nèi)核申請(qǐng)空間,需要提前說(shuō)明存儲(chǔ)數(shù)據(jù)的類型以及存儲(chǔ)數(shù)據(jù)的數(shù)量
定義格式:數(shù)據(jù)類型 數(shù)組名稱[數(shù)據(jù)個(gè)數(shù)];? ?例? int buffer[10];? char buffer[5];
數(shù)組的定義

由C語(yǔ)言標(biāo)準(zhǔn)可以知道,想要訪問(wèn)數(shù)組中的某個(gè)數(shù)據(jù),C語(yǔ)言標(biāo)準(zhǔn)中把數(shù)組中的數(shù)據(jù)稱為元素(element),用戶需要通過(guò)數(shù)組元素的編號(hào)來(lái)訪問(wèn)數(shù)據(jù),C語(yǔ)言標(biāo)準(zhǔn)把數(shù)組元素的編號(hào)稱為下標(biāo),而數(shù)組元素的下標(biāo)是從0開始的。??
比如:E1假設(shè)是數(shù)組對(duì)象,E2假設(shè)是數(shù)組元素的個(gè)數(shù),假設(shè)存儲(chǔ)整型,定義數(shù)組的時(shí)候 int E1[E2],如果想要訪問(wèn)E1數(shù)組中的第E2個(gè)元素, E1[E2] = 10;? 數(shù)組元素的下標(biāo):0 ~ E2 - 1
int buf[5];? // 一共有5個(gè)元素??
buf[5] = 10; //錯(cuò)誤的 數(shù)組下標(biāo)無(wú)法達(dá)到5,下標(biāo)從0開始!!
?
語(yǔ)義

可以知道,C語(yǔ)言標(biāo)準(zhǔn)中提到數(shù)組名其實(shí)是一個(gè)指向數(shù)組第一個(gè)元素的地址,同時(shí)也指的是一個(gè)數(shù)組
數(shù)組下標(biāo)和轉(zhuǎn)換

可以看到,C語(yǔ)言標(biāo)準(zhǔn)中提到 E1[E2]就表示可以訪問(wèn)名字叫做E1的數(shù)組對(duì)象的第E2個(gè)元素,并且可以用另一種方式進(jìn)行替換 就是 ( * ( (E1) + (E2) ) ),如果E2是一個(gè)常量,則括號(hào)可以省略,如果E1只是一個(gè)數(shù)組名,括號(hào)也可以省略。
( * ( (E1) + (E2) ) )? --->? ( * ( E1 + E2 ) )? ---> 如果只打算訪問(wèn)數(shù)組元素 --->? *( E1 + E2 ) !!!!!

為什么C語(yǔ)言中規(guī)定*( E1 + E2 )可以訪問(wèn)數(shù)組內(nèi)存地址,是什么原理?*有什么作用?
回答:通過(guò)C語(yǔ)言標(biāo)準(zhǔn)可以知道E1是數(shù)組對(duì)象,并且E1也可以表示數(shù)組對(duì)象第一個(gè)元素的地址,所以E1就是E1[0]的地址,E2表示要訪問(wèn)的數(shù)組元素的下標(biāo),可以知道數(shù)組只能相同類型的數(shù)據(jù),所以數(shù)組中的每個(gè)元素的數(shù)據(jù)的寬度是相同的,所以從內(nèi)存的角度理解(E1+E2),就是從E1地址開始向后偏移E2個(gè)元素單位,所以就是向后偏移了E2*type個(gè)字節(jié)。

?(E1+E2)形式只是計(jì)算出數(shù)組元素所對(duì)應(yīng)的地址,但是數(shù)據(jù)是存儲(chǔ)在存儲(chǔ)單元中的,用戶此時(shí)只知道存儲(chǔ)單元對(duì)應(yīng)的地址,但是如果想要把該地址中的數(shù)據(jù)讀取出來(lái),C語(yǔ)言標(biāo)準(zhǔn)是利用 * 實(shí)現(xiàn)的。
*運(yùn)算符
C語(yǔ)言標(biāo)準(zhǔn)中把 * 也作為單目運(yùn)算符,所以只有一個(gè)操作數(shù),這個(gè)操作數(shù)的類型應(yīng)該是指針類型,也就是說(shuō)操作數(shù)應(yīng)該是一個(gè)地址, * 地址就表示得到該地址對(duì)應(yīng)的結(jié)果,簡(jiǎn)單的說(shuō),*地址就可以得到該地址下的值。? *也被稱為間接運(yùn)算符,一般和指針一起使用。

如果用戶定義了一個(gè)整型數(shù)組int buf[5];那么(buf+1)指的是數(shù)組地址向后偏移一個(gè)元素對(duì)應(yīng)的單元大小,也就是地址向后偏移了4字節(jié),請(qǐng)問(wèn)(&buf+1)表示什么意思,應(yīng)該如何解釋?

可以發(fā)現(xiàn),C語(yǔ)言標(biāo)準(zhǔn)中提到數(shù)組名可以用于表示數(shù)組的第一個(gè)元素的地址,但是有兩種例外情況。
第一種:當(dāng)&地址運(yùn)算符和數(shù)組名一起使用時(shí),數(shù)組名就不能表示數(shù)組首元素地址,而是表示數(shù)組本身,所以(&buf+1)向后偏移一個(gè)單位其實(shí)是向后偏移整個(gè)數(shù)組大小的字節(jié),上圖向后偏移了20字節(jié)
第二種:當(dāng)sizeof運(yùn)算符和數(shù)組名一起單獨(dú)使用時(shí),數(shù)組名就不能表示數(shù)組首元素地址而是表示數(shù)組本身,int buf[6];? sizeof(buf) = 24byte。?

對(duì)數(shù)組進(jìn)行初始化
int but[10]={0}; //表示定義數(shù)組的時(shí)候就對(duì)數(shù)組進(jìn)行初始化,每個(gè)數(shù)組元素存儲(chǔ)的值都是0
int buf[10]; buf[10]={0};//是錯(cuò)誤的 只有在定義數(shù)組的時(shí)候?qū)?shù)組賦值的動(dòng)作才叫做初始化
計(jì)算數(shù)組元素個(gè)數(shù)
如果用戶定義數(shù)組時(shí)并未在[]中說(shuō)明數(shù)組元素個(gè)數(shù),但是在定義數(shù)組時(shí)已經(jīng)對(duì)數(shù)組進(jìn)行初始化,所以系統(tǒng)會(huì)自動(dòng)計(jì)算數(shù)組所需要占用的內(nèi)存大小,請(qǐng)問(wèn)系統(tǒng)如何判定數(shù)組的長(zhǎng)度?用戶又如何來(lái)驗(yàn)證數(shù)組元素個(gè)數(shù)是否正確?
回答:可以通過(guò)sizeof運(yùn)算符來(lái)計(jì)算數(shù)組的空間大小,如果用戶想要計(jì)算數(shù)組元素的個(gè)數(shù),應(yīng)該設(shè)計(jì)為? ?sizeof(數(shù)組名稱)/sizeof(數(shù)組類型)
清除數(shù)組之前的元素
用戶定義了一個(gè)數(shù)組,并且也對(duì)數(shù)據(jù)正確進(jìn)行了初始化,但是用戶后面準(zhǔn)備存儲(chǔ)新的元素到數(shù)組中,想要把之前存儲(chǔ)的元素清空,由于定義數(shù)組已經(jīng)做過(guò)初始化,是否意味著只能把數(shù)組中的元素一個(gè)一個(gè)單獨(dú)清空?
方法:調(diào)用庫(kù)函數(shù)bzero()和memset()可以輕松實(shí)現(xiàn)數(shù)組的清除動(dòng)作,兩個(gè)函數(shù)的區(qū)別:bzero函數(shù)只可以把數(shù)組的元素清0,但是memset可以讓數(shù)組中的每個(gè)元素為指定的值,所以memset函數(shù)使用更加靈活
字符數(shù)組
使用字符數(shù)組的目的是存儲(chǔ)字符序列,字符數(shù)組的格式是a[]={‘a(chǎn)’,’b’},字符需要帶’’單引號(hào),C語(yǔ)言規(guī)定用戶也可以使用字符串來(lái)存儲(chǔ)字符序列,字符串需要使用雙引號(hào)””進(jìn)行約束,字符串也表示字符序列的首地址
字符數(shù)組和字符串的區(qū)別

?可以知道,C語(yǔ)言中的字符串會(huì)由系統(tǒng)自動(dòng)在末尾添加轉(zhuǎn)義字符“\0”,目的是作為字符串的結(jié)束標(biāo)志,而定義的字符數(shù)組是由用戶進(jìn)行初始化,所以系統(tǒng)不會(huì)自動(dòng)在字符數(shù)組中添加“\0”