復(fù)雜數(shù)據(jù)及運(yùn)算—指針_第1頁
復(fù)雜數(shù)據(jù)及運(yùn)算—指針_第2頁
復(fù)雜數(shù)據(jù)及運(yùn)算—指針_第3頁
復(fù)雜數(shù)據(jù)及運(yùn)算—指針_第4頁
復(fù)雜數(shù)據(jù)及運(yùn)算—指針_第5頁
已閱讀5頁,還剩58頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、C+教程第四章 復(fù)雜數(shù)據(jù)及運(yùn)算清華大學(xué) 鄭 莉4.2指針 為了操作地址!一點忠告! C/C+可以直接操作內(nèi)存地址。 指針就是為了地址操作而存在的。 指針是復(fù)雜又容易出錯的。 在不是必須不是必須使用指針的場合,不推薦用指針。 我們學(xué)習(xí)指針不是為了到處用指針,而是在需要用的時候使用。 我們自己寫程序的時候,在確保程序?qū)崿F(xiàn)功能的在確保程序?qū)崿F(xiàn)功能的前提下,前提下,代碼是越簡單越好,而不是技巧越多,越復(fù)雜越好!本節(jié)的學(xué)習(xí) 本節(jié)除了動態(tài)內(nèi)存分配,其余所有程序例題,其實都可以不需要指針。 只所以用指針是為了幫助我們理解指針的用法。 本節(jié)的學(xué)習(xí),一定要了解一點內(nèi)存的知識。 內(nèi)存單元的地址 C+各種基本數(shù)據(jù)類

2、型的長度(字節(jié))4.2.1 數(shù)據(jù)在內(nèi)存中的地址 內(nèi)存空間的訪問方式 通過變量名訪問通過變量名訪問 通過地址訪問通過地址訪問5程序中: int i; 內(nèi)存中每個字節(jié)有一個編號-地址地址.20012002內(nèi)存0 i 編譯或函數(shù)調(diào)用時為其分配內(nèi)存單元變量是對程序中數(shù)據(jù)存儲空間的抽象變量與地址2000如何獲得變量的地址 地址運(yùn)算 取地址運(yùn)算符:& 數(shù)組的起始地址 數(shù)組名字既是數(shù)組的起始地址,因此數(shù)組名是地址常量。7例4-5:觀察變量在內(nèi)存中的地址#includeusing namespace std;int main()int intVal=1;double dVal=2.0;int inta

3、rray3=0,1,2;cout&intVal:intValendl;cout&dVal:dValendl;coutintarray:endl;cout&intarray0:intarray0endl;return 0;84.2 數(shù)組4.2.1數(shù)據(jù)在內(nèi)存中的地址運(yùn)行結(jié)果:運(yùn)行結(jié)果:0013FF7C:10013FF74:20013FF68:0013FF68:0例4-5(續(xù))4.2 數(shù)組4.2.1數(shù)據(jù)在內(nèi)存中的地址對例4_5的分析:如何獲得變量的地址1intVal地址:&intVal2dVal地址:&dVal102intArray intArray是數(shù)組名,

4、代表的是數(shù)組的起始地址,也就是第一個元素的地址。 intArrayi,用下標(biāo)法訪問數(shù)組的元素。 intArray0是數(shù)組的第一個元素,該元素的地址是&intArray0。 所以intArray, &intArray0,所存放的地址是一樣的。&intArray0 一旦定義了一個數(shù)組,數(shù)組名存放的就是數(shù)組的起始地址,也就是一個地址類型的數(shù)據(jù)。 在生存期內(nèi),整個數(shù)組在內(nèi)存中的所占用的存儲空間是不變的,地址是不變的,所以數(shù)組名是一個地址類型的常量常量。對一維數(shù)組的再探討 一維數(shù)組有個關(guān)鍵問題:下標(biāo)不可以越界。但是下標(biāo)不可以越界。但是如果越界編譯器并不能檢查出錯誤。如果越界編譯器

5、并不能檢查出錯誤。 從地址的角度來考慮這個問題。102intArray&intArray0&intArray1&intArray2&intArray3超出數(shù)組范圍可能對其他數(shù)據(jù)產(chǎn)生破壞例4-6:觀察一維數(shù)組在內(nèi)存中的存儲#include #include using namespace std;const int size=5; int main() int arraysize; int i;for (i=0; isize; i+) arrayi=i;for (i=0; isize; i+) coutsetw(10)arrayi;coutendl;for (i=

6、0; isize; i+) coutsetw(10)&arrayi;coutendl; cout&array5: &array5endl; 144.2 數(shù)組4.2.1數(shù)據(jù)在內(nèi)存中的地址運(yùn)行結(jié)果:運(yùn)行結(jié)果: 0 1 2 3 4 0012FF6C 0012FF70 0012FF74 0012FF78 0012FF7C &array5: 0012FF80例4-6(續(xù))對例4_6的分析 通過本例的輸出,可以看出數(shù)組元素是順序存儲的。 &array5,其實已經(jīng)不是array數(shù)組中的元素的地址了。 增加語句:array5=100; 在編譯時不會出現(xiàn)錯誤信息; 運(yùn)行后

7、得到的錯誤信息,是操作系統(tǒng)發(fā)出的。例4-7:觀察多維數(shù)組在內(nèi)存中的存儲#include #include using namespace std;const int nrow=3;const int ncol=2; int main() int arraynrowncol; int i;for (i=0; inrow; i+) for (int j=0; jncol; j+) arrayij=i+j;for ( i=0; inrow; i+) for (int j=0; jncol; j+) coutsetw(3)arrayijsetw(10)&arrayij;coutendl;174

8、.2 數(shù)組4.2.1數(shù)據(jù)在內(nèi)存中的地址運(yùn)行結(jié)果:運(yùn)行結(jié)果: 0 0012FF68 1 0012FF6C 1 0012FF70 2 0012FF74 2 0012FF78 3 0012FF7C例4-7(續(xù))4.2 數(shù)組4.2.1數(shù)據(jù)在內(nèi)存中的地址對例4_7的分析 通過本例的輸出,可以看出多維數(shù)組元素是按行存儲的。二維數(shù)組在內(nèi)存中的存儲 占據(jù)一片連續(xù)存儲區(qū) int a43a00 a01 a02a10 a11 a12a20 a21 a22a30 a31 a32按行存放按行存放第第0 行行a00a01a02a10a11a12第第 1 行行a30a31a32第第 3 行行.內(nèi)存內(nèi)存4.2.1 結(jié)束語 這

9、個部分通過3個例子,展示了數(shù)據(jù)在內(nèi)存中如何存放,特別強(qiáng)調(diào)了數(shù)組的存放。 普通變量:用取地址運(yùn)算符&獲得地址。 數(shù)組:數(shù)組名就是數(shù)組的起始地址。 那么,地址取出來做什么?剛學(xué)過的3個例子中,地址取出來只是做了輸出。 問題1:為什么要使用地址? 問題2:如何使用地址?問題1:為什么要使用地址?在C+中,除了用變量名,還可以直接使用地址來訪問內(nèi)存單元。這樣做的原因:1 有些場合更高效2 動態(tài)分配內(nèi)存時必須用地址訪問3 有效的表示復(fù)雜數(shù)據(jù)結(jié)構(gòu)。問題2:如何使用地址? 用于存放地址的變量就是指針類型的變量。4.2.2 指針及指針運(yùn)算定義指針 * Name; T為類型,表示指針?biāo)笇ο蟮念愋停?*

10、表示此變量類型為指/針; Name為定義指針的名稱。指針變量賦初值 1. 在聲明指針的同時進(jìn)行初始化賦值; 2. 在聲明之后,使用賦值表達(dá)式語句為指針賦值。244.2 數(shù)組程序中: int i; 內(nèi)存中每個字節(jié)有一個編號-地址地址.20012002內(nèi)存0 i 編譯或函數(shù)調(diào)用時為其分配內(nèi)存單元變量是對程序中數(shù)據(jù)存儲空間的抽象1 變量與地址2000.2000整型變量i10變量i_pointer2004v指針:一個變量的地址。v指針變量:專門用來存放地址的變量叫指針變量,它的值也可以是數(shù)組或函數(shù)的地址 。2000指針指針變量 變量的內(nèi)容 變量的地址2. 指針與指針變量.1. 指針變量與其所指向的變量

11、之間的關(guān)系2. 指針變量的定義v一般形式: 數(shù)據(jù)類型 *指針名;3變量i2000i_pointer*i_pointeri*i_pointer&ii_pointeri=3;*i_pointer=3合法標(biāo)識符指針的目標(biāo)變量的數(shù)據(jù)類型表示定義指針變量不是乘法運(yùn)算符*例 int *p1,*p2; float *q ; char *name;注意:1、int *p1, *p2; 與 int *p1, p2;不一樣。2、指針變量名是p1,p2 ,不是*p1,*p2。3、指針變量只能指向定義時所規(guī)定類型的變量。4、指針變量定義后,變量值不確定,應(yīng)用前必須先賦值。3. 指針變量的定義含義: 取變量的地

12、址單目運(yùn)算符結(jié)合性:自右向左含義: 從某個地址中獲取數(shù)據(jù)單目運(yùn)算符結(jié)合性:自右向左兩者關(guān)系:互為逆運(yùn)算4. 取地址運(yùn)算符&與指針運(yùn)算符* *.20002010整型變量i10變量i_pointer20042000指針變量i_pointer-指針變量,它的內(nèi)容是地址量20002000*i_pointer-指針的目標(biāo)變量i,它的內(nèi)容是數(shù)據(jù)10&i_pointer-指針變量占用內(nèi)存的地址:20102010i_pointer &i &(*i_pointer)i *i_pointer *(&i)指針運(yùn)算符示例=.例 main( ) int i=10; int *p;

13、 *p=i; cout*p; 不可不可以危以危險!險!例 main( ) int i=10,k; int *p; p=&k; *p=i; cout*p; .20002010整型變量i10指針變量p2004隨機(jī)值5. 指針變量必須先賦值,再使用!.空指針:v定義:指針變量值為零 例如: int * p=0; p指向地址為0的內(nèi)存單元;系統(tǒng)保證該單元不作它用;表示指針變量的值沒有意義。lP為空指針與未對p賦值不同u避免指針變量的非法引用6. 空指針例4-8:定義指針并通過指針訪問變量#include using namespace std; int main() int num(23);i

14、nt* P_num=0;P_num=# coutthe integer is: numendl;coutthe number that is pointed to is: *P_numendl;coutthe address of the number is: P_numendl;324.2 數(shù)組4.2.2指針及指針運(yùn)算運(yùn)行結(jié)果:運(yùn)行結(jié)果:the integer is: 23the number that is pointed to is: 23the address of the number is: 0012FF7C例4-8(續(xù))4.2 數(shù)組4.2.2指針及指針運(yùn)算對例4_

15、8的分析 通過本例的,學(xué)習(xí) 定義指針 給指針賦值 使用指針 空指針指針初始化 int* P_num=0; P_num=# 先定義指針,再賦值 int* P_num=# 定義指針同時初始化將地址值賦給指針變量例 int i; int *p=&i;變量必須已說明過;并要求兩者類型一致。例 int *p=&i; int i;例 int i; int *p=&i; int *q=p;用已初始化指針變量作初值一般形式: 數(shù)據(jù)類型 *指針名=初始地址值;7. 指針變量的初始化例 i=3; -直接訪問指針變量.20002010整型變量i10變量i_po

16、inter200420003例 *i_pointer=20; -間接訪問20v 直接訪問v 間接訪問8. 直接訪問與間接訪問.9.對指針變量的操作C+語言程序設(shè)計清華大學(xué) 鄭莉指針變量的算術(shù)運(yùn)算指針變量的算術(shù)運(yùn)算l指針與整數(shù)的加減運(yùn)算指針與整數(shù)的加減運(yùn)算指針p加上或減去n,其意義是指針當(dāng)前指向位置的前方或后方第n個數(shù)據(jù)的地址。這種運(yùn)算的結(jié)果值取決于指針指向的數(shù)據(jù)類型。l指針加一,減一運(yùn)算指針加一,減一運(yùn)算指向下一個或前一個數(shù)據(jù)。例如:y=*p+ 相當(dāng)于 y=*(p+) 指 針p-1pp+1p+2*(p-1)或者p-1*p或者p-0*(p+1)或者p1*(p+2)或者p2intint * *p;

17、p;40C+語言程序設(shè)計清華大學(xué) 鄭莉注意:注意:l指針做算術(shù)運(yùn)算指針做算術(shù)運(yùn)算l有意義的場合:訪問連續(xù)數(shù)據(jù)序列,有意義的場合:訪問連續(xù)數(shù)據(jù)序列,例如數(shù)組。例如數(shù)組。l其他情況不要用,不僅沒意義,還容其他情況不要用,不僅沒意義,還容易帶來危險操作。易帶來危險操作。C+語言程序設(shè)計清華大學(xué) 鄭莉l關(guān)系運(yùn)算關(guān)系運(yùn)算指向相同類型數(shù)據(jù)的指針之間可以進(jìn)行各種關(guān)系運(yùn)算。指向不同數(shù)據(jù)類型的指針,以及指針與一般指向不同數(shù)據(jù)類型的指針,以及指針與一般整數(shù)變量之間的關(guān)系運(yùn)算是無意義的。整數(shù)變量之間的關(guān)系運(yùn)算是無意義的。指針可以和零之間進(jìn)行等于或不等于的關(guān)系運(yùn)算。例如:p=0或p!=0,判斷是否為空指針l賦值運(yùn)算賦

18、值運(yùn)算向指針變量賦的值必須是地址常量或變量地址常量或變量,不能是普通整數(shù)不能是普通整數(shù)。但可以賦值為整數(shù)0,表示空指針。例4-9:通過指針訪問有序的批量數(shù)據(jù)#include #include using namespace std;const int size=6; int main() int arraysize=2,4,13,7,9,21;int *P_array=array;coutthe sequence is:endl;while (P_array array+size) coutsetw(4)*P_array;P_array+;coutendl;P_array=array;cout

19、the forth number of the sequence is: endl;cout*(P_array+3)endl;return 0;434.2 數(shù)組4.2.2指針及指針運(yùn)算運(yùn)行結(jié)果:運(yùn)行結(jié)果:the sequence is: 2 4 13 7 9 21the forth number of the sequence is:7例4-9(續(xù))4.2 數(shù)組4.2.2指針及指針運(yùn)算對例4_9的分析 指針可以和整數(shù)進(jìn)行加減運(yùn)算,運(yùn)算規(guī)則比較特殊。 指針加減運(yùn)算的結(jié)果與指針類型密切相關(guān)。 指針加1的效果是使指針指向下一個完整數(shù)據(jù)的起始地址。 利用指針的這個特性,通過指針的不斷增值,依次順序訪問

20、有序的批量數(shù)據(jù)。指針的算術(shù)運(yùn)算 一般來講,指針的算術(shù)運(yùn)算是和數(shù)組的使用相聯(lián)系的,因為只有在使用數(shù)組時,才會得到連續(xù)分布的可操作內(nèi)存空間。 常用的比較運(yùn)算: 如果兩個同類型的指針相等,表示這兩個指針是指向同一個地址的。 如果一個指針等于0,表示這個指針是空指針。C+語言程序設(shè)計清華大學(xué) 鄭莉指向數(shù)組元素的指針指向數(shù)組元素的指針l聲明與賦值聲明與賦值例:int a10, *pa; pa=&a0; 或 pa=a;l通過指針引用數(shù)組元素通過指針引用數(shù)組元素經(jīng)過上述聲明及賦值后:*pa就是a0,*(pa+1)就是a1,. ,*(pa+i)就是ai.ai, *(pa+i), *(a+i), pai

21、都是等效的。不能寫不能寫 a+a+,因為因為a a是數(shù)組首地址是常量。是數(shù)組首地址是常量。 指 針C+語言程序設(shè)計清華大學(xué) 鄭莉為什么用指針處理數(shù)組為什么用指針處理數(shù)組l與后面要學(xué)習(xí)的動態(tài)內(nèi)存分配數(shù)組有與后面要學(xué)習(xí)的動態(tài)內(nèi)存分配數(shù)組有關(guān)。關(guān)。l下面的例子,用了三種方法,對比,下面的例子,用了三種方法,對比,大家可以發(fā)現(xiàn):大家可以發(fā)現(xiàn): 完成了同樣的功能,使用指針也并沒有更方便。l包括例包括例4_9,完全可以不用指針,大,完全可以不用指針,大家思考如果不用指針,此題怎么寫。家思考如果不用指針,此題怎么寫。C+語言程序設(shè)計清華大學(xué) 鄭莉設(shè)有一個設(shè)有一個int型數(shù)組型數(shù)組a,有有10個元素。用個元素

22、。用三種方法輸出各元素:三種方法輸出各元素: 使用數(shù)組名和下標(biāo) 使用數(shù)組名和指針運(yùn)算 使用指針變量 指 針intint main() main() int a10; int a10; int i; int i; for(i=0; i10; i+) for(i=0; iai;ai; coutcoutendlendl; ; for(i=0; i10; i+) for(i=0; i10; i+) coutcoutaiai; ; 使用數(shù)組名和下標(biāo)使用數(shù)組名和下標(biāo)51intint main() main() int a10; int a10; int i; int i; for(i=0; i10; i+

23、) for(i=0; iai;ai; coutcoutendlendl; ; for(i=0; i10; i+) for(i=0; i10; i+) coutcout* *(a+i)(a+i); ; 使用數(shù)組名指針運(yùn)算使用數(shù)組名指針運(yùn)算52使用指針變量使用指針變量intint main() main() int a10; int a10; int int * *p,ip,i; for(i=0; i10; i+)for(i=0; iai;ai; coutcoutendlendl; ; for(p=a; p(a+10); p+) for(p=a; p(a+10); p+) coutcout* *p

24、 p; ; 53動態(tài)分配與釋放內(nèi)存空間 以靜態(tài)方式定義的數(shù)組,其大小必須定義好,而且不可改變大小。 在運(yùn)行時動態(tài)分配內(nèi)存空間,一旦空間不再被使用,應(yīng)該在程序中及時釋放。 但是動態(tài)分配的內(nèi)存空間,不可以命名,也就不能通過變量名來訪問了,只能使用地址操作。4.2.2 指針及指針運(yùn)算(續(xù))內(nèi)存的動態(tài)分配 動態(tài)分配單個變量的語法形式為:new T(初值列表); 動態(tài)分配一維數(shù)組的語法形式為:new T元素個數(shù);內(nèi)存的動態(tài)釋放 釋放單個變量空間的語法形式為:delete 指針名; 釋放動態(tài)數(shù)組空間的語法形式為:delete 指針名;554.2 數(shù)組運(yùn)算結(jié)果是為新分配空間的起始地址例4-10:實現(xiàn)一個在運(yùn)行時確定大小的一維數(shù)組#include #include using namespace std; int main() int size;coutplease enter the number of the sequence: si

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論