C++ 一維數(shù)組

一維數(shù)組定義&形式
是一組數(shù)據(jù)類型相同的變量,可以存放一組數(shù)據(jù)
數(shù)組名[下標(biāo)]
?數(shù)組地址
數(shù)組在內(nèi)存中的地址是連續(xù)的
C++將數(shù)組名解釋為數(shù)組首個(gè)元素的地址
?數(shù)組名為常量,不能更改,例如int類型數(shù)組a使用 a++?
指針值可以改變,int *p = a使用 p++?
數(shù)組第0個(gè)元素的地址等價(jià)于數(shù)組首個(gè)元素的地址
數(shù)組第n個(gè)元素的地址:地址首個(gè)元素的地址+n
C++編譯器將
數(shù)組名[下標(biāo)]
解釋為? ??*(數(shù)組首個(gè)地址+下標(biāo))
? ? ? ??
地址[下標(biāo)]
?解釋為?*(地址+下標(biāo))
數(shù)組表示法&指針表示法
1.數(shù)組表示法
形式為 數(shù)組名[下標(biāo)] ?地址形式為 (類型)&數(shù)組名[下標(biāo)]
2.指針表示法
使用指針來(lái)表示數(shù)組地址,定義形式為 *指針名 = 數(shù)組地址(例如a或者a[下標(biāo)])
取值形式為 *(指針名+下標(biāo))
地址形式為 指針名+下標(biāo)
?聯(lián)系
C++編譯器將 數(shù)組名[下標(biāo)] 解釋為 *(數(shù)組首個(gè)地址+下標(biāo))
地址[下標(biāo)] ? ?解釋為 *(地址+下標(biāo))

一維數(shù)組用于函數(shù)的參數(shù)
形式: ??
void func (int * arr , int len);? ?
void func (int ?arr[] , int len);
當(dāng)且僅當(dāng)用于函數(shù)頭或函數(shù)原型中,int arr[]
和int *arr
才都意味著arr為一個(gè)int指針(在操作系統(tǒng)中,int指針為8字節(jié))
?長(zhǎng)度(int len)必須傳入,除非數(shù)組中有最后一個(gè)元素的標(biāo)志
?
動(dòng)態(tài)創(chuàng)建一維數(shù)組
棧內(nèi)存很小,當(dāng)有大量的數(shù)據(jù)需要存儲(chǔ)時(shí),應(yīng)在堆上存儲(chǔ)
語(yǔ)法
創(chuàng)建: 數(shù)據(jù)類型 *指針 = new 數(shù)據(jù)類型[數(shù)組長(zhǎng)度]
釋放: delete [] 指針
?重點(diǎn)
1?動(dòng)態(tài)創(chuàng)建的數(shù)組無(wú)數(shù)組名,不能用sizeof運(yùn)算符(sizeof(指針)==8)
2?可以用數(shù)組表示法(arr[i])和指針表示法(*(arr+i))來(lái)使用動(dòng)態(tài)創(chuàng)建的數(shù)組
3?釋放動(dòng)態(tài)分配的只能用delete [] 數(shù)組名,不能只用delete 數(shù)組名
4?不要用delete釋放不是動(dòng)態(tài)分配的內(nèi)存(例如棧上內(nèi)存、C語(yǔ)言malloc動(dòng)態(tài)分配的內(nèi)存)
5?不要用delete[]釋放同一內(nèi)存2次(第一次正常釋放,第二次相當(dāng)于釋放野指針)
6?對(duì)空指針用delete[]是安全的(釋放內(nèi)存后,指針應(yīng)置為nullptr,防止誤操作)
7?如果內(nèi)存不足,調(diào)用new 會(huì)發(fā)生異常,導(dǎo)致程序中止,如果在new關(guān)鍵詞后面加(std::nothrow),則返回nullptr,不會(huì)產(chǎn)生異常
8?用delete[]釋放數(shù)組時(shí),不需要指定數(shù)組大小,因?yàn)橄到y(tǒng)會(huì)自動(dòng)跟蹤已分配的數(shù)組內(nèi)存
數(shù)組排序qsort()函數(shù)
qsort()函數(shù)用于各種數(shù)據(jù)類型的數(shù)組進(jìn)行排序
函數(shù)的原型為 void qsort(void base,size_t nmemb,size_t size,int (compar)(const void *,const void *))

回調(diào)函數(shù)決定排序的順序
int compar (const void *p1,const void *p2)
如果函數(shù)的返回值<0,那么p1所指向元素會(huì)被排在p2所指向元素的前面。
如果函數(shù)的返回值==0,那么p1所指向元素與p2所指向元素的位置不確定。
如果函數(shù)的返回值>0,那么p1所指向元素會(huì)被排在p2所指向元素的后面。
?其他細(xì)節(jié)
1?size_t是C標(biāo)準(zhǔn)庫(kù)中定義的,在64位操作系統(tǒng)中為8字節(jié)的無(wú)符號(hào)整型(unsigned long long) , typedef unsigned long long size_t
2?形參的地址用void是為了支持所有類型,在回調(diào)函數(shù)中應(yīng)具體化
3?排序的需求除了升序和降序,還有很多不可預(yù)知的情況,只能用回調(diào)函數(shù)。
??舉例
?注意事項(xiàng)
1?當(dāng)直接打印char類型a的地址時(shí),std::cout
會(huì)把&a當(dāng)做字符串來(lái)輸出,導(dǎo)致亂碼
解決辦法:使用強(qiáng)制轉(zhuǎn)換(void*)
明確告訴編譯器&a為地址
2?由于數(shù)組申請(qǐng)內(nèi)存用來(lái)存放某一類型的數(shù)據(jù),可以通過(guò)強(qiáng)制類型轉(zhuǎn)換來(lái)存放其他類型的數(shù)據(jù)
3?在棧上申請(qǐng)內(nèi)存時(shí),注意棧溢出
大多數(shù)Linux發(fā)行版的GCC編譯器,棧上內(nèi)存為8M,即2^23^ 字節(jié) = 8388608字節(jié)
Windows的Visual C++編譯器,棧上內(nèi)存為1M,即2^20^ 字節(jié) = 1048576字節(jié)
在Windows棧上分配int類型的數(shù)組理論上最多有2^20^ 字節(jié)/4字節(jié)=262144個(gè)元素,但是棧上還會(huì)存儲(chǔ)局部變量、函數(shù)參數(shù)、函數(shù)調(diào)用的上下文,所以實(shí)際上應(yīng)少于262144個(gè)元素