版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、,,數(shù)組與指針,1.空間分類2.為什么用指針3.指針的定義及使用方式4.指針的訪問方式(即變量操作的本質(zhì))5.數(shù)組同指針的關(guān)系6.數(shù)組和指針作為函數(shù)的參數(shù)和返回值,??臻g堆空間,空間分類,數(shù)組-物理空間存放的本質(zhì),定義數(shù)組就是申請了一塊連續(xù)的內(nèi)存空間。用戶可操作的空間大小等于數(shù)組元素*每個元素所占的空間大小。數(shù)組元素連續(xù)存放在這塊空間中。如: int intarray[5];占用了20個字節(jié),因為每個整型數(shù)占四個字節(jié)。
2、如給intarray[3]賦值為3,如果這塊空間的起始地址為100,那么在內(nèi)存中的情況是:當(dāng)你引用變量intarray[idx]時,系統(tǒng)計算它的地址100+idx*4,對該地址的內(nèi)容進(jìn)行操作。,參照幾何坐標(biāo)系,數(shù)組下標(biāo)超界問題,C/C++語言不檢查數(shù)組下標(biāo)的超界。如定義數(shù)組 int intarray[10]; 合法的下標(biāo)范圍是0 – 9,但如果你引用intarray[10],系統(tǒng)不會報錯。如數(shù)組intarray 的起始地址是100
3、0,當(dāng)引用intarray[10]時,系統(tǒng)對1040號內(nèi)存進(jìn)行操作。而1040可能是另一個變量的地址解決方法(1) 由程序員自己控制。在對下標(biāo)變量進(jìn)行操作前,先檢查下標(biāo)的合法性。 (2) 利用容器等,數(shù)組的缺點,必須知道數(shù)組的確定類型和空間大小,才能定義數(shù)組。數(shù)組的大小受到棧大小的限制。通常棧的大小是2M。,指針的概念,如在某一程序中定義了 int x = 2;如系統(tǒng)給x分配的空間是1
4、000號單元,則指向x的指針是另一個變量p,p中存放的數(shù)據(jù)為10001000號單元的內(nèi)容有兩種訪問方式:訪問變量x (直接訪問)訪問變量p指向的單元的內(nèi)容(間接訪問),定義指針變量,定義指針變量要告訴編譯器該變量中存放的是一個地址。指針變量的主要用途是提供間接訪問,因此也需要知道指針指向的單元的數(shù)據(jù)類型指針變量的定義 類型標(biāo)識符 *指針變量; 如:int *intp; double *doublep;
5、 int *p, x, *q;,類型標(biāo)識符的作用??,指針變量的操作,如何讓指針指向某一變量?因為我們不知道系統(tǒng)分配給變量的真正地址是什么。用取地址運(yùn)算符 “&” 解決。如表達(dá)式 “&x” 返回的是變量 x 的地址。如:intp = &x;& 運(yùn)算符后面不能跟常量或表達(dá)式。如 &2 是沒有意義的,&(m * n + p )。也是沒有意義的如何通過指針變量處理和改變它所指向
6、的單元的值?用地址解析運(yùn)算符 “*” 解決。如 *intp 表示的是 intp 指向的這個單元的內(nèi)容。如:*intp = 5 等價于 x = 5在對 intp 使用引用運(yùn)算之前,必須先對 intp 賦值,指針實例,如有:int X, *intp, Y;X=3;Y=4;intp=&X;,如執(zhí)行:*intp=Y+4;,注意:不能用 intp=100;因為我們永遠(yuǎn)不知道變量存儲的真實地址,而且程序每次運(yùn)行變量地址
7、可能都不同。,指針使用,指針變量可以指向不同的變量。如上例中intp指向x,我們可以通過對intp的重新賦值改變指針的指向。如果想讓intp指向y,只要執(zhí)行intp=&y就可以了。這時,intp與x無任何關(guān)系。同類的指針變量之間可相互賦值,表示二個指針指向同一內(nèi)存空間。空指針指針沒有指向任何空間空指針用常量NULL表示,NULL的值一般賦為0不能引用空指針指向的值野指針(沒有初始化的指針),指針變量的使用,設(shè)有定義
8、 int x, y; int *p1,*p2;,執(zhí)行語句:x=23;y=234;,執(zhí)行語句:p1=&x;p2=&y;,執(zhí)行語句:*p1=34;p2=p1;,指針實例,有以下結(jié)構(gòu),比較執(zhí)行 p1=p2和 *p1= *p2后的不同結(jié)果。,指針的初始化,指針在使用前必須初始化。和別的變量一樣,定義指針不初始化是一個比較普通的錯誤。沒有初始化的指針可能指向任意地址,對這些指針作操作可能會導(dǎo)致程序
9、錯誤(野指針)。NULL是一個特殊指針值,稱為空指針。它的值為0。它可被用來初始化一個指針,表示不指向任何地址。,思考:int *p; *p = 5; 有什么問題?,指針與數(shù)組,在C++中,指針和數(shù)組關(guān)系密切,幾乎可以互換使用數(shù)組名可以看成是常量指針,對一維數(shù)組來說,數(shù)組名是數(shù)組的起始地址,也就是第一個元素的地址如執(zhí)行了p=array,則p與array是等價的,對該指針可以進(jìn)行任何有關(guān)數(shù)組下標(biāo)的操作,數(shù)組實際訪問方式: C+
10、+語言的下標(biāo)運(yùn)算符[ ]是以指針作為操作數(shù)的,fibon[i]被編譯系統(tǒng)解釋為*(fibon+i)即表示為fibon所指(固定不可變)元素向后第i個元素。無論以下標(biāo)方式或指針方式存取數(shù)組元素時,系統(tǒng)都是轉(zhuǎn)換為指針方法實現(xiàn)。,通過指針訪問數(shù)組時,下標(biāo)有效范圍由程序員自己檢查。,數(shù)組元素的指針表示,方法3: for ( p=a; p<a+10; ++p ) cout << *p ;,方法2:
11、 for ( i=0; i<10; ++i ) cout << *(a+i);,方法1: for ( i=0; i<10; ++i ) cout << a[i];,方法4: for ( p=a, i=0; i<10; ++i ) cout << *(p+i);,方法5: for (
12、 p=a, i=0; i<10; ++i ) cout << p[i] ;,下列程序段 有無問題? for ( i=0; i<10; ++i ) { cout << *a ; ++a; },,指針同樣可以進(jìn)行”++”,”--“運(yùn)算,運(yùn)算結(jié)果也是指向后一個或前一個數(shù)組元素。,*但是有”++”和”--”的表達(dá)式往往容易出錯
13、,必須小心使用,如:y=*pfib++;由于后”++”的優(yōu)先級高于”*”,所以該表達(dá)式等效于y=*(pfib++),又因是后”++”,所以y中取值為*pfib,而pfib增1后指向下一個元素。這條語句在C++中是常用的。千萬不可誤解為將pfib所指目標(biāo)增1。,動態(tài)內(nèi)存分配,什么時候需要動態(tài)分配內(nèi)存?實例:順序?qū)σ慌募M(jìn)行解析,但是不知道文件的大小,如何建立緩沖區(qū)?參看一個人臉檢測的Ground Truth文件格式,C語言方
14、法malloc函數(shù)原型:void * malloc(size_t n);n是要分配的內(nèi)存的大小(字節(jié)為單位),返回值是分配內(nèi)存的塊的首地址,關(guān)鍵代碼:int * array;array = (int *)malloc(10 * sizeof(int));注意:單位,內(nèi)存大小不能寫成數(shù)組元素的個數(shù),需要注意的問題(1)malloc函數(shù)是一個庫函數(shù),它并不是C語言中的關(guān)鍵字:需要頭文件才可以使用該函數(shù)并不是所有的
15、平臺都可以使用該函數(shù),尤其是一些單片機(jī)系統(tǒng),free函數(shù)原型:void free(void * p);p是要釋放的已分配內(nèi)存的塊的首地址,釋放一塊動態(tài)分配的內(nèi)存:例如:int *p;p = (int *)malloc(sizeof(int));free(p);,動態(tài)內(nèi)存申請與釋放,C++中由new 和 delete兩個運(yùn)算符替代- 運(yùn)算符new用于進(jìn)行內(nèi)存申請: 申請動態(tài)變量:p = new type; 申
16、請動態(tài)數(shù)組:p = new type[size]; 申請動態(tài)變量并初始化:p = new type(初值) - 運(yùn)算符delete 釋放 new分配的內(nèi)存: 釋放動態(tài)變量:delete p; 釋放動態(tài)數(shù)組:delete [] p;,//為簡單變量動態(tài)分配內(nèi)存,并作初始化int main(){ int *p; p = new int(99); //動態(tài)分配內(nèi)存,并將99作為初始化值賦給它 c
17、out<< *p; delete p; return 0;},動態(tài)內(nèi)存申請與釋放,//動態(tài)字符串的使用int main(){int *p; char *q; p = new int(5); q = new char[10]; strcpy(q, "abcde"); cout << *p << endl; cout << q <<
18、endl; delete p; delete [ ]q; return 0;},輸出結(jié)果:5abcde,動態(tài)分配的檢查,new操作的結(jié)果是記錄申請到的空間的起始地址及大小(隱式)當(dāng)系統(tǒng)空間用完時,new操作可能失敗new操作失敗時,返回空指針/NULL,動態(tài)內(nèi)存申請與釋放,//動態(tài)分配檢查int main(){ int *p; p = new int; if( p== NULL ) //if (
19、 NULL == p ) { cout << "allocation failure\n"; return 1; } *p = 20; cout << *p; delete p; return 0;},assert宏,assert()宏在標(biāo)準(zhǔn)頭文件cassert中 assert()有一個參數(shù),表示斷言為真的表達(dá)式,預(yù)處理器產(chǎn)生測試
20、該斷言的代碼。如果斷言不是真,則在發(fā)出一個錯誤消息后程序會終止。,#include #include //包含assert宏的頭文件int main(){ int *p; p = new int; assert ( p != 0 ); //p等于0,則退出程序 *p=20; cout << *p; delete p; return 0;},內(nèi)存分配的進(jìn)一步介紹,靜態(tài)分配:對全局
21、變量和靜態(tài)變量,編譯器為它們分配空間,這些空間在整個程序運(yùn)行期間都存在自動分配:函數(shù)內(nèi)的局部變量空間是分配在系統(tǒng)的棧工作區(qū)。當(dāng)函數(shù)被調(diào)用時,空間被分配;當(dāng)函數(shù)執(zhí)行結(jié)束后,空間被釋放動態(tài)分配:在程序執(zhí)行過程中需要新的存儲空間時,可用動態(tài)分配的方法向系統(tǒng)申請新的空間,當(dāng)不再使用時用顯式的方法還給系統(tǒng)。這部分空間是從被稱為堆的內(nèi)存區(qū)域分配。,內(nèi)存泄漏,動態(tài)變量是通過指針間接訪問的。如果該指針被修改,這個區(qū)域就被丟失了。堆管理器認(rèn)為你在繼續(xù)
22、使用它們,但你不知道它們在哪里,這稱為內(nèi)存泄露。為了避免出現(xiàn)孤立的區(qū)域,應(yīng)該明白地告訴堆管理器這些區(qū)域不再使用。可以采用delete操作,它釋放由new申請的內(nèi)存。當(dāng)釋放了內(nèi)存區(qū)域,堆管理器重新收回這些區(qū)域,而指針仍然指向堆區(qū)域,但不能再使用指針指向的這些區(qū)域。要確保在程序中同一個區(qū)域釋放一次。釋放內(nèi)存對一些程序不重要,但對有些程序很重要。如果你的程序要運(yùn)行很長時間,而且存在內(nèi)存泄漏,這樣程序會耗盡所有內(nèi)存,直至崩潰。,動態(tài)空間
23、分配示例,輸入一批數(shù)據(jù),計算它們的和。數(shù)據(jù)個數(shù)在設(shè)計程序時尚無法確定。存儲一批數(shù)據(jù)應(yīng)該用數(shù)組,但C++語言的數(shù)組大小必須是固定的。該問題有兩個解決方案:開設(shè)一個足夠大的數(shù)組,每次運(yùn)行時只使用一部分。缺點:浪費(fèi)空間用動態(tài)內(nèi)存分配根據(jù)輸入的數(shù)據(jù)量申請一個動態(tài)數(shù)組,#include int main(){ int *p, i, n, sum=0; cout > n; p = new int[n]; if
24、 ( p == NULL ) return 1; for ( i=0; i> p[i]; for( i=0; i<n; ++I ) sum += p[i]; cout << "Number of elements:" << n << endl; cout << "Sum of the elements:" &l
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 指針和數(shù)組區(qū)別
- 使用數(shù)組和指針統(tǒng)計成績
- 指針數(shù)組模型中數(shù)據(jù)劃分技術(shù)的研究及其實現(xiàn).pdf
- 用指針和數(shù)組解決矩陣多項式加減法課程設(shè)計
- 數(shù)組的基本概念一維數(shù)組二維數(shù)組字符數(shù)組數(shù)組的應(yīng)用舉例
- perl 數(shù)組
- 函數(shù)名與函數(shù)指針
- 指針總結(jié)讓你不再害怕指針
- 數(shù)組典型例題分析與解答
- 指針的深入研究指針進(jìn)階
- 超強(qiáng)指針
- 指針典型例題分析與解答
- 數(shù)組去重復(fù)
- 數(shù)組編程練習(xí)
- 數(shù)組函數(shù)講座
- 指針邏輯的擴(kuò)展與應(yīng)用.pdf
- 再再論指針
- c指針總結(jié)
- 實驗6數(shù)組的使用
- 第五章 數(shù)組
評論
0/150
提交評論