版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
C++程序設(shè)計及項目實踐1第9章 指針及引用
指針是C和C++中重要的技術(shù),許多重要的函數(shù)及功能都是建立在指針基礎(chǔ)上。有一些功能必須通過指針才能實現(xiàn),比如先前在定義數(shù)組的時候需要使用常量來定義數(shù)組的長度,也就是使用數(shù)組的時候必須提前分配一個固定長度的空間,這在程序運(yùn)行過程中,可能會導(dǎo)致程序占用多余的內(nèi)存而浪費(fèi),若使用指針相關(guān)技術(shù),則程序可以動態(tài)分配內(nèi)存:程序需要多大數(shù)組空間則分配相應(yīng)容量的空間,不再使用這部分空間的時候則可以進(jìn)行回收,那么程序運(yùn)行的性能會顯著提升。C++程序設(shè)計及項目實踐第9章 指針及引用
29.1指針基礎(chǔ)9.2指針與函數(shù)9.3指針與數(shù)組9.4內(nèi)存動態(tài)分配9.5單項鏈表9.6引用9.7const對指針及引用的寫保護(hù)9.8應(yīng)用9.9本章小結(jié)C++程序設(shè)計及項目實踐39.1指針基礎(chǔ)9.1.1內(nèi)存地址及指針9.1.2指針變量定義9.1.3指針變量使用9.1.4void指針9.1.5NULL指針9.1.6指向指針的指針C++程序設(shè)計及項目實踐49.1.1內(nèi)存地址及指針程序中定義的變量在編譯及運(yùn)行時會分配一個內(nèi)存單元,該內(nèi)存單元的容量根據(jù)變量類型占有一定數(shù)量的字節(jié)(使用sizeof運(yùn)算符即可以獲得該變量的字節(jié)數(shù))。所以每一個變量都擁有一個內(nèi)存地址,該地址可以用取值運(yùn)算符”&”獲得。比如,程序中若定義了整型變量i:inti=3;則i將會被分配一個4字節(jié)的空間,該空間內(nèi)存儲的值為3,其地址可以用&i獲得,對于其他類型的變量,也可以用類似的方法獲得其內(nèi)存地址。變量的內(nèi)存地址稱為該變量的指針。C++程序設(shè)計及項目實踐5例9.1內(nèi)存地址顯示示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06floatf=4.5f;07doubled=6.7;08cout<<"i="<<i<<"\taddress="<<&i<<"\tsize="<<sizeof(i)<<endl;09cout<<"f="<<f<<"\taddress="<<&f<<"\tsize="<<sizeof(f)<<endl;10cout<<"d="<<d<<"\taddress="<<&d<<"\tsize="<<sizeof(d)<<endl;11return0;12}C++程序設(shè)計及項目實踐69.1.2
指針變量定義可以將某個變量的內(nèi)存地址,也即是某個變量的指針存放在另外一個專門定義的用來存放指針的變量中,這種可以存放指針的變量稱為指針變量。定義指針變量的語法形式:數(shù)據(jù)類型*指針變量名;若有指針變量定義語句:int*pt;表示定義了一個指針變量pt,*表示該變量pt為指針類型變量,int表示該變量pt中存放的是整型變量的地址,也就是說盡管不同類型變量的內(nèi)存地址形式上都是十六進(jìn)制整數(shù),但在定義指針變量時,需要根據(jù)指針變量中所預(yù)備指向的內(nèi)存地址存放的數(shù)據(jù)類型來確定指針變量的數(shù)據(jù)類型,不能混用,比如,若需要一個指針變量pt存放指向double類型變量的指針(內(nèi)存地址),則需要定義:double*pt;C++程序設(shè)計及項目實踐7例9.2指針變量定義示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06floatf=4.5f;07doubled=6.7;08int*pti=&i;09float*ptf=&f;10double*ptd=&d;11cout<<"pti="<<pti<<endl;12cout<<"ptf="<<ptf<<endl;13cout<<"ptd="<<ptd<<endl;14return0;15}&i3ptii*ptiC++程序設(shè)計及項目實踐89.1.3
指針變量使用
定義指針變量,對指針變量賦地址值后,可以通過對指針變量的操作實現(xiàn)一系列復(fù)雜功能,其中最經(jīng)常使用的操作就是通過指針變量讀寫所指向的原始變量內(nèi)存空間。通過指針變量訪問所指向的內(nèi)存空間的語法形式如:*指針變量名。其中*運(yùn)算符形式上是乘法符號,在這里表示指針運(yùn)算符,也稱為間接訪問運(yùn)算符。
使用*指針變量名操作后,可以認(rèn)為就獲得了指針?biāo)赶虻淖兞?內(nèi)存空間),那么將其作為左值可以對指向變量進(jìn)行賦值,將其作為右值即從指向變量讀取值。C++程序設(shè)計及項目實踐9例9.3指針運(yùn)算符示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=1;06int*pti;07pti=&i;08cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;09*pti=2;10cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;11i=i+3;12cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;13i=*pti+4;14cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;15*pti=i+5;16cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;17*pti=*pti+6;18cout<<"i="<<i<<"\tpti="<<pti<<"\t*pti="<<*pti<<endl;19return0;20}C++程序設(shè)計及項目實踐109.1.4
void指針
可以聲明一個數(shù)據(jù)類型為void的指針變量,void表示數(shù)據(jù)類型不確定,定義這種類型的指針變量的語法形式為:void*p;
該類型的指針變量可以理解成通用類型的指針,也就是任何數(shù)據(jù)類型的指針均可以直接賦給void指針,不過當(dāng)需要使用*p的方式訪問指針指向內(nèi)存值的時候,需要首先轉(zhuǎn)換void指針為具體的數(shù)據(jù)類型指針方可。C++程序設(shè)計及項目實踐11例9.4void指針示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06int*pi=&i;07void*vpi=pi;08int*ipi=(int*)vpi;09cout<<*ipi<<endl;10doubled=4.5;11void*vpd=&d;12cout<<*(double*)vpd<<endl;13return0;14}C++程序設(shè)計及項目實踐129.1.5
NULL指針聲明指針變量的時候,如果指針還沒有初始化指向需要的變量時,可以將其賦NULL值,表示空指針。大多數(shù)編譯軟件中定義名稱常量NULL為0,如果將指針賦為NULL,相當(dāng)于指針指向地址為0的內(nèi)存單元,而0地址的內(nèi)存單元在大多數(shù)操作系統(tǒng)中是由操作系統(tǒng)管理,不允許應(yīng)用程序訪問,如果指針指向0,則意味著該指針不指向任何有意義的單元。C++程序設(shè)計及項目實踐13例9.5NULL指針示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06int*pi;07cout<<"notassignaddress:"<<pi<<endl;08pi=NULL;09cout<<"assignNULLaddress:"<<pi<<endl;10pi=&i;11cout<<"assignusefuladdress:"<<pi<<endl;12return0;13}C++程序設(shè)計及項目實踐149.1.6
指向指針的指針可以將變量或某個內(nèi)存的地址存放在指針里,同樣的,可以將某個指針的地址存放在另一個指針里,這樣就可以構(gòu)成一個指針的鏈條,如下圖所示。指針的地方變量的地址數(shù)值指向指針的指針指針變量定義變量時,內(nèi)存分配了一個空間,該空間內(nèi)可以存放該變量對應(yīng)的數(shù)值;聲明指針時,可以將該變量的地址存放在指針的內(nèi)存空間;聲明指向指針的指針后,指針的地址可以存放在指針的指針內(nèi)存空間。這樣可以通過對指向指針的指針的二次間接尋址操作,獲得原始變量的值。定義指向指針的指針的語法形式為:數(shù)據(jù)類型**p;C++程序設(shè)計及項目實踐15例9.6指向指針的指針示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06int*pi=NULL;07int**ppi=NULL;08pi=&i;09ppi=π10cout<<"i="<<i<<endl;11cout<<"*pi="<<*pi<<endl;12cout<<"**pi="<<**ppi<<endl;13return0;14}C++程序設(shè)計及項目實踐169.2
指針與函數(shù)函數(shù)的參數(shù)可以為基礎(chǔ)的整型,浮點(diǎn)型等,也可以是指針類型的。同樣,函數(shù)的返回值類型也可以為指針類型。另外,由于函數(shù)名和變量名類似,在編譯之后也擁有一個地址,所以函數(shù)也具有指針,可以定義一個函數(shù)指針,在某些情況下使用函數(shù)指針來調(diào)用函數(shù)。C++程序設(shè)計及項目實踐179.2.1
指針作為函數(shù)參數(shù)在使用整型,浮點(diǎn)型,字符型等數(shù)據(jù)作為函數(shù)參數(shù)時,參數(shù)從實參傳遞給形參按照”按值單向傳遞”規(guī)則進(jìn)行,也就是在函數(shù)中對形參作任何修改操作,也不會影響實參。而若通過指針類型數(shù)據(jù)作為函數(shù)參數(shù)時,實參傳遞給形參的是實參的地址,那么對形參的指針運(yùn)算本質(zhì)上就是對實參空間的運(yùn)算。C++程序設(shè)計及項目實踐18例9.7指針作為函數(shù)實參交換數(shù)據(jù)程序代碼:01#include<iostream>02usingnamespacestd;0304voidswap_value(inta,intb)05{06inttmp=a;07a=b;08b=tmp;09}1011voidswap_address(int*pa,int*pb)12{13int*tmp=pa;14pa=pb;15pb=tmp;16}1718voidswap_pointer(int*pa,int*pb)19{20inttmp=*pa;21*pa=*pb;22*pb=tmp;23}2425intmain(){26intx=3;27inty=4;28int*px=&x;29int*py=&y;30cout<<"begin:\t\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;31swap_value(x,y);32cout<<"swapvalue:\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;33swap_address(px,py);34cout<<"swapaddress:\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;35swap_pointer(px,py);36cout<<"swappointer:\t&x="<<px<<"\tx="<<x<<"\t&y="<<py<<"\ty="<<y<<endl;37return0;38}C++程序設(shè)計及項目實踐19C++程序設(shè)計及項目實踐209.2.2
指針作為函數(shù)返回值函數(shù)返回值類型可以為整型,浮點(diǎn)型和用戶自定義的類型,比如結(jié)構(gòu)體,枚舉,聯(lián)合體類型等,也可以為指針類型。由于函數(shù)中的局部變量隨著函數(shù)的退出而釋放,所以返回局部變量的地址并沒有意義,因此,返回的指針必須是能夠不受函數(shù)退出而影響的指針變量,主要包括全局指針變量,static變量的指針,函數(shù)內(nèi)new分配的指針變量。C++程序設(shè)計及項目實踐21例9.8指針作為函數(shù)返回值示例程序代碼:01#include<iostream>02usingnamespacestd;0304int*getStatic(inta,intb)05{06staticintmul=0;07mul=a*b;08return&mul;09}1011int*getNew(inta,intb)12{1314int*sum=newint;15*sum=a+b;16returnsum;17}1819intmain(){20intx=3,y=4;21int*rStatic=getStatic(x,y);22cout<<*rStatic<<endl;23int*rNew=getNew(x,y);24cout<<*rNew<<endl;25deleterNew;26return0;27}C++程序設(shè)計及項目實踐229.2.3 函數(shù)指針函數(shù)在編譯之后被分配了相應(yīng)的空間,函數(shù)名可以作為這個空間的入口地址看待,因此可以定義函數(shù)指針變量,并將該變量指向函數(shù)的入口地址,在使用的時候通過函數(shù)指針調(diào)用函數(shù)。定義函數(shù)指針的語法如下:函數(shù)類型(*函數(shù)指針)(函數(shù)形參表);這里的函數(shù)類型,函數(shù)形參表必須和預(yù)備指向的函數(shù)完全一致。在定義了函數(shù)指針之后,需要將函數(shù)指針指向特定的函數(shù)。函數(shù)指針=函數(shù)名;在指向函數(shù)之后,可以用如下方式調(diào)用函數(shù):返回值=函數(shù)指針(函數(shù)實參);C++程序設(shè)計及項目實踐23例9.9函數(shù)指針示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmymax(inta,intb)05{06returna>b?a:b;07}0809intmymin(inta,intb)10{11returna<b?a:b;12}1314intmyfun(intc,intd,int(*pf)(inta,intb))15{16returnpf(c,d);17}1819intmain(){20int(*pfunction)(int,int);21pfunction=mymax;22cout<<pfunction(3,4)<<endl;23inty1=myfun(30,40,mymax);24cout<<y1<<endl;25inty2=myfun(50,60,mymin);26cout<<y2<<endl;27return0;28}C++程序設(shè)計及項目實踐249.3.1 數(shù)組指針數(shù)組在內(nèi)存中被分配了連續(xù)的內(nèi)存空間,數(shù)組名代表了這個空間的起始地址,同時數(shù)組中的每個元素也分別對應(yīng)這個空間的某個地址,所以,數(shù)組及數(shù)組元素均可以用對應(yīng)的指針指向它們。具體來說:(1)數(shù)組的指針就是指向數(shù)組的起始地址。(2)數(shù)組元素的指針就是指向具體數(shù)組元素的地址,數(shù)組的指針同時也是指向數(shù)組中第一個元素的指針。(3)當(dāng)用某個指針指向數(shù)組中元素時候,可以對指針變量進(jìn)行自增,自減,加,減,比較等運(yùn)算。C++程序設(shè)計及項目實踐25例9.10數(shù)組指針遍歷程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05constintLEN=5;06inta[LEN];07int*p=a;08for(inti=0;i<LEN;i++)09{10*p=2*i+1;11p++;12}13p=&a[LEN-1];14while(p>=a)15{16cout<<*p<<'\t';17p--;18}19return0;20}C++程序設(shè)計及項目實踐269.3.2 指針數(shù)組數(shù)組的元素也可以是指針,這種數(shù)組稱為指針數(shù)組,聲明指針數(shù)組的語法形式: 數(shù)據(jù)類型*指針變量[常量];常量為表示數(shù)組長度的常量,定義之后,則該數(shù)組中的每一個元素都表示為指向該數(shù)據(jù)類型數(shù)據(jù)的指針。C++程序設(shè)計及項目實踐27例9.11指針數(shù)組示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05constintLEN=5;06inta[LEN]={1,3,5,7,9};07int*pa[LEN];08for(inti=0;i<LEN;i++)09{10pa[i]=&a[i];11}12for(inti=LEN-1;i>=0;i--)13{14cout<<*pa[i]<<'\t';15}16return0;17}C++程序設(shè)計及項目實踐289.3.3 字符指針當(dāng)數(shù)組的元素為字符時,可以定義一個指向字符數(shù)組的指針,在使用過程中,字符指針和字符數(shù)組名有許多類似的地方,尤其是系統(tǒng)提供的一些字符串處理相關(guān)的函數(shù),其參數(shù)既可以用字符數(shù)組名,也可以用字符指針。C++程序設(shè)計及項目實踐29例9.12字符指針示例,將字符串轉(zhuǎn)化為大寫程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05constintLEN=80;06charstr1[LEN]={0};07char*pstr1=str1;08constchar*str2="iloveC++";09for(inti=0;*(str2+i)!='\0';i++)10{11if(*(str2+i)<='z'12&&*(str2+i)>='a')13{14*pstr1=*(str2+i)-32;15}16else17{18*pstr1=*(str2+i);19}20pstr1++;21}22pstr1=str1;23cout<<pstr1<<endl;24return0;25}C++程序設(shè)計及項目實踐309.4 內(nèi)存動態(tài)分配指針變量可以指向已定義的變量,也可以指向動態(tài)分配的內(nèi)存空間,這種技術(shù)在需要動態(tài)使用內(nèi)存的程序中非常有用,它可以使得運(yùn)行程序精確控制自己所需要耗費(fèi)的內(nèi)存空間。C++程序設(shè)計及項目實踐319.4.1 基礎(chǔ)類型內(nèi)存動態(tài)分配對于常用的整型、浮點(diǎn)型等變量,分配一個單獨(dú)的內(nèi)存空間可以用new運(yùn)算符,語法形式如下:數(shù)據(jù)類型*指針變量=new數(shù)據(jù)類型([初始值]);分配的時候?qū)⒃摽臻g的內(nèi)存地址賦給指針變量,可以同時賦予分配空間的初始值,初始化值的操作是可選的。對于使用new分配的空間,最后需要將空間釋放給系統(tǒng),釋放指針變量需要使用delete運(yùn)算符,語法形式如下:delete指針變量;C++程序設(shè)計及項目實踐32例9.13基礎(chǔ)指針變量分配與釋放示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05int*pi=newint;06float*pf=newfloat(3.5f);07double*pd=newdouble;08*pi=3;09*pd=5;10cout<<*pi<<endl11<<*pf<<endl12<<*pd<<endl;13deletepi;14deletepf;15deletepd;16return0;17}C++程序設(shè)計及項目實踐339.4.2 可變長數(shù)組動態(tài)分配先前定義數(shù)組的時候需要首先確定數(shù)組長度,數(shù)組一旦分配,在程序執(zhí)行全過程中,即使不再需要使用到該數(shù)組,數(shù)組的空間也不能釋放,這會導(dǎo)致內(nèi)存浪費(fèi)、影響程序的性能。使用new運(yùn)算符同樣可以對數(shù)組的空間進(jìn)行分配,動態(tài)分配數(shù)組的語法如下:數(shù)據(jù)類型*指針變量=new數(shù)據(jù)類型[長度];這里長度可以是常量,也可以是變量,分配后,得到的指針變量指向數(shù)組的開始地址,在訪問數(shù)組元素時,可以將指針變量名當(dāng)作數(shù)組名來使用。不再使用new分配的數(shù)組后,需要使用delete運(yùn)算符進(jìn)行釋放:delete[]指針變量;這里delete的后面需要有中括號,表示對數(shù)組空間的釋放。C++程序設(shè)計及項目實踐34例9.14動態(tài)分配數(shù)組的示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05intm,n;06cin>>m>>n;07//一維數(shù)組動態(tài)分配08int*pa=newint[n];09for(inti=0;i<n;i++)10{11pa[i]=3*i+1;12}13//二維數(shù)組動態(tài)分配14//分配所有行15int**pb=newint*[m];16for(intr=0;r<m;r++)17{18//分配某一行的所有列19pb[r]=newint[n];20for(intc=0;c<n;C++)21{22pb[r][c]=(r+1)*(c+1);23}24}25cout<<"firstarray:"<<endl;26for(inti=0;i<n;i++)27{28cout<<pa[i]<<'\t';29}30cout<<endl<<"secondarray:"<<endl;31for(intr=0;r<m;r++)32{33for(intc=0;c<n;C++)34{35cout<<pb[r][c]<<'\t';36}37cout<<endl;38}39//一維數(shù)組釋放40delete[]pa;41//二維數(shù)組所有列釋放42for(intr=0;r<m;r++)43{44delete[]pb[r];45}46//二維數(shù)組所有行釋放47delete[]pb;48return0;49}C++程序設(shè)計及項目實踐35C++程序設(shè)計及項目實踐369.4.2 結(jié)構(gòu)體類型內(nèi)存動態(tài)分配結(jié)構(gòu)體指針變量同樣可以賦予某個結(jié)構(gòu)體變量的內(nèi)存地址,也可以動態(tài)分配一個內(nèi)存空間。動態(tài)分配的語法形式如下:結(jié)構(gòu)體類型名*指針變量=new結(jié)構(gòu)體類型名;在擁有結(jié)構(gòu)體指針后,可以將*結(jié)構(gòu)體變量看成普通的結(jié)構(gòu)體變量,并使用點(diǎn)”.”成員訪問符對結(jié)構(gòu)體中的成員進(jìn)行讀寫,也可以直接用結(jié)構(gòu)體指針配合箭頭”->”成員訪問符對結(jié)構(gòu)體指針中的成員進(jìn)行讀寫。在結(jié)構(gòu)體指針使用完成后,使用new動態(tài)分配的結(jié)構(gòu)體指針,也需要使用delete進(jìn)行釋放。C++程序設(shè)計及項目實踐37例9.15結(jié)構(gòu)體指針分配示例程序代碼:01#include<iostream>02#include<cstring>03usingnamespacestd;0405intmain(){06structStudent07{08intnum;09charname[10];10};11Studentstu{1000,"zhang"};12Student*pstu1,*pstu2;13pstu1=&stu;14pstu2=newStudent;15pstu2->num=2000;16strcpy(pstu2->name,"li");17cout<<"Student1:"<<endl18<<pstu1->num<<'\t'19<<pstu1->name<<endl;20cout<<"Student2:"<<endl21<<pstu2->num<<'\t'22<<pstu2->name<<endl;23deletepstu2;24return0;25}C++程序設(shè)計及項目實踐389.5 單向鏈表
當(dāng)程序需要使用大量相同數(shù)據(jù)類型數(shù)據(jù)時,可以使用數(shù)組來管理,數(shù)組在內(nèi)存中的連續(xù)存儲,這對于數(shù)據(jù)的檢索相關(guān)的操作非常方便,但是對于需要更新數(shù)據(jù)的場景就非常不遍,比如若要在數(shù)組中間增加或者刪除一項時,為了保證數(shù)組存儲的連續(xù)性,需要對數(shù)據(jù)項進(jìn)行移動,這就增加了系統(tǒng)的時空消耗,而且,當(dāng)增加的數(shù)據(jù)項過多超過數(shù)組長度時,可能會導(dǎo)致數(shù)組不能增加。
數(shù)組中存在的缺點(diǎn),使用鏈表可以克服,鏈表從邏輯上看也是數(shù)據(jù)在內(nèi)存中線性排列,不過在內(nèi)存中不一定是連續(xù)存放,所以它可以靈活地支持動態(tài)增加或刪除數(shù)據(jù)項。
下面是一個包含四個節(jié)點(diǎn)的單向鏈表的圖示,單向指鏈表節(jié)點(diǎn)中包含的指針只指向一個方向,即從頭到尾。數(shù)據(jù)中間節(jié)點(diǎn)(第二個節(jié)點(diǎn))下一節(jié)點(diǎn)地址數(shù)據(jù)頭節(jié)點(diǎn)(第一個節(jié)點(diǎn))下一節(jié)點(diǎn)地址數(shù)據(jù)尾節(jié)點(diǎn)(最后一個節(jié)點(diǎn))NULL數(shù)據(jù)中間節(jié)點(diǎn)(第三個節(jié)點(diǎn))下一節(jié)點(diǎn)地址C++程序設(shè)計及項目實踐39例9.16一個簡單鏈表的示例程序代碼:01#include<iostream>02#include<cstring>03usingnamespacestd;0405structStudent06{07intid;08charname[20];09Student*pNext;10};1112intmain(){13Student*pHead,*pSecond,*pThird,*pTail;14//單獨(dú)建立各個節(jié)點(diǎn)15pHead=newStudent;16pHead->id=1000;17strcpy(pHead->name,"zhao");18pSecond=newStudent;19pSecond->id=2000;20strcpy(pSecond->name,"qian");21pThird=newStudent;22pThird->id=3000;23strcpy(pThird->name,"sun");24pTail=newStudent;25pTail->id=4000;26strcpy(pTail->name,"li");27//將各個節(jié)點(diǎn)串聯(lián)起來成為一個鏈表28pHead->pNext=pSecond;29pSecond->pNext=pThird;30pThird->pNext=pTail;31pTail->pNext=NULL;32//利用循環(huán)語句顯示鏈表33cout<<"showlist:"<<endl;34Student*pTemp=pHead;35while(pTemp!=NULL)36{37cout<<pTemp->id<<'\t'<<pTemp->name<<endl;38pTemp=pTemp->pNext;39}40//刪除第二個節(jié)點(diǎn),不破壞鏈表41pHead->pNext=pThird;42deletepSecond;43//利用循環(huán)語句顯示刪除了第二個節(jié)點(diǎn)之后的鏈表44cout<<"deletethesecondnode,showlist:"<<endl;45pTemp=pHead;46while(pTemp!=NULL)47{48cout<<pTemp->id<<'\t'<<pTemp->name<<endl;49pTemp=pTemp->pNext;50}51deletepHead;52deletepThird;53deletepTail;54return0;55}C++程序設(shè)計及項目實踐40數(shù)據(jù)pSecond下一節(jié)點(diǎn)地址數(shù)據(jù)pHead下一節(jié)點(diǎn)地址數(shù)據(jù)pTailNULL數(shù)據(jù)PThird下一節(jié)點(diǎn)地址C++程序設(shè)計及項目實踐419.6 引用引用(reference)是一個現(xiàn)有變量的別名,一旦對已有的變量建立一個引用,則可以認(rèn)為原始變量名和引用名是等價的,均代表同樣的內(nèi)存空間。C++程序設(shè)計及項目實踐429.6.1 引用聲明及使用聲明一個引用必須同時對其進(jìn)行初始化,一旦聲明引用之后,不能再將該引用名修改為其他變量的引用。聲明應(yīng)用的語法形式如下:數(shù)據(jù)類型&引用名=變量名;&表示引用,注意和取址運(yùn)算符區(qū)分開,這里是放在賦值表達(dá)式的左側(cè)。使用該表達(dá)式聲明之后,引用名和變量名都代表了同樣的內(nèi)存空間。C++程序設(shè)計及項目實踐43例9.17引用示例程序代碼:01#include<iostream>02usingnamespacestd;0304intmain(){05inti=3;06floatf=4.5f;07doubled=6.7;08int&ri=i;09float&rf=f;10double&rd=d;11i++;12cout<<ri<<endl;13rf*=rf;14cout<<f<<endl;15rd=rd*d;16cout<<rd<<endl;17return0;18}C++程序設(shè)計及項目實踐449.6.2 引用作為函數(shù)參數(shù)引用可以作為函數(shù)的參數(shù),此時在函數(shù)內(nèi)部對形式參數(shù)的任何操作,就相當(dāng)于對主調(diào)函數(shù)中實際參數(shù)的操作,這種特性往往比先前使用指針傳遞參數(shù)來改變實參更加方便。C++程序設(shè)計及項目實踐45例引用作為函數(shù)參數(shù)交換值程序代碼:01#include<iostream>02usingnamespacestd;0304structStudent05{06intid;07charname[20];08};09voidmyswap(Student&stu1,Student&stu2)10{11Studentstu=stu1;12stu1=stu2;13stu2=stu;14}15voidmyswap(int&x,int&y)16{17inttemp=x;18x=y;19y=temp;20}2122intmain(){23inti=3,j=4;24myswap(i,j);25cout<<i<<'\t'<<j<<endl;26Studentstu1={1,"zhang"},stu2={2,"li"};27myswap(stu1,stu2);28cout<<"student1:"<<stu1.id<<'\t'<<<<endl;29cout<<"student2:"<<stu2.id<<'\t'<<<<endl;30return0;31}C++程序設(shè)計及項目實踐463變量i別名x4變量j別名y(1)4變量i別名x3變量j別名y(2)1,”zhang”變量stu1別名stu12,”li”變量stu2別名stu2(1)2,”li”
變量stu1別名stu11,”zhang”
變量stu2別名stu2(2)C++程序設(shè)計及項目實踐479.6.3 引用作為函數(shù)返回值引用同樣可以作為函數(shù)的返回值,由于函數(shù)內(nèi)部的局部變量會隨著函數(shù)的退出而被釋放,所以如果要能返回某個變量的引用,則該變量需要為全局變量、局部靜態(tài)變量、使用new分配的變量等。C++程序設(shè)計及項目實踐48例9.19引用作為函數(shù)返回值示例程序代碼:01#include<iostream>02usingnamespacestd;0304intgi=0;05int&getRef(intx,inty)06{07gi=x+y;08returngi;09}1011int&getRef(intx)12{13staticinti=x*x;14returni;15}1617intmain(){18int&ret1=getRef(3);19int&ret2=getRef(3,4);20cout<<ret1<<'\t'<<ret2<<endl;21return0;22}C++程序設(shè)計及項目實踐499.7 const對指針及引用的寫保護(hù)指針和引用均提供了某種間接訪問內(nèi)存空間的機(jī)制,尤其在作為函數(shù)參數(shù)傳遞時,可以只傳遞實參地址,而無需拷貝完整的實參,這種參數(shù)傳遞的方式可以減少時間和空間消耗,但由于在函數(shù)內(nèi)部可以通過修改形參來改變實參,這在某些時候可能會造成意想不到的后果,因此需要對函數(shù)參數(shù)進(jìn)行保護(hù),const就提供了保護(hù)指針和引用的方法。C++程序設(shè)計及項目實踐509.7.1 保護(hù)指針及指針指向值const對指針可以保護(hù)三個方法:保護(hù)指針存儲地址、保護(hù)指針指向空間、同時保護(hù)指針存儲地址和指針指向空間。(1) const保護(hù)指針存儲地址:數(shù)據(jù)類型*constp,這種方式下,p為初始化常量,不能對p進(jìn)行修改而改變初始值。(2) const保護(hù)指針指向空間:數(shù)據(jù)類型const*p或者const數(shù)據(jù)類型*p,這種方式下*p為保護(hù)空間,不能對*p進(jìn)行修改。(3) const保護(hù)指針存儲地址和指向空間:const數(shù)據(jù)類型*constp或者數(shù)據(jù)類型const*constp,這種方式下p及*p均不能再次被修改。C++程序設(shè)計及項目實踐51例9.20const指針保護(hù)示例程序代碼:01#include<iostream>02usingnamespacestd;0304voidshowOne(constint*p)05{06//不能執(zhí)行*p=x;07cout<<"constint*p"<<endl;08cout<<*p<<endl;09}1011voidshowTwo(int*constp)12{13//不能執(zhí)行p=&x;14cout<<"int*constp"<<endl;15cout<<*p<<endl;16}1718voidshowThree(constint*constp)19{20//不能執(zhí)行p=&x或*p=x;21cout<<"constint*constp"<<endl;22cout<<*p<<endl;23}2425intmain(){26inti=3;27intj=4;28intk=5;29intconst*pi=&i;30int*constpj=&j;31intconst*constpk=&k;32pi=&j;//不能執(zhí)行*pi=j;33*pj=i;//不能執(zhí)行pj=&i;34//不能執(zhí)行pk=&i或*pk=i;35cout<<*pi<<endl;36cout<<*pj<<endl;37cout<<*pk<<endl;38showOne(&i);39showTwo(&j);40showThree(&k);41return0;42}C++程序設(shè)計及項目實踐52C++程序設(shè)計及項目實踐539.7.2 保護(hù)引用const可以對引用傳遞的函數(shù)參數(shù)進(jìn)行保護(hù),限制在函數(shù)內(nèi)部對形式參數(shù)的修改。形式為:const數(shù)據(jù)類型&引用名,這種方式下,引用會成為常量,不能對引用重新賦值。C++程序設(shè)計及項目實踐54例9.21const引用保護(hù)示例程序代碼:01#include<iostream>02usingnamespacestd;0304structStudent05{06intid;07charname[20];08};0910voidshow(constStudent&stu)11{12//不能修改stu.id或者的值13cout<<stu.id<<endl14<<<<endl;15}1617intmain(){18Studentstu{1000,"zhang"};19show(stu);20return0;21}C++程序設(shè)計及項目實踐559.8應(yīng)用C++程序設(shè)計及項目實踐56例9.22字符串截取,截取某個位置開始的若干長度的字符串。思路:設(shè)計函數(shù)boolstrmid(char*dest,char*src,intpos,intlen),其中src為需要獲取的源字符串,dest為最后獲得的目標(biāo)字符串,pos為源字符串中的截取字符的起始位置,len為獲取的字符個數(shù)。C++程序設(shè)計及項目實踐57例9.22字符串截取,截取某個位置開始的若干長度的字符串。程序代碼:01#include<iostream>02usingnamespacestd;0304boolstrmid(char*dest,char*src,intpos,intlen)05{06boolisin=false;07inti=0;08for(i=0;src[i]!='\0';i++)09{10if(i==pos)11{12isin=true;13break;14}15}16if(!isin)17{18returnfalse;19}20intn=0;21for(i=pos;src[i]!='\0'&&n<len;i++,n++)22{23dest[n]=src[i];24}25dest[n]='\0';26returntrue;27}28intmain(){29constintLEN=80;30charfirst[LEN]="IloveChineseandMathmatics";31charsecond[LEN];32if(strmid(second,first,7,30))33{34cout<<second<<endl;35}36else37{38cout<<"noresult"<<endl;39}40return0;41}C++程序設(shè)計及項目實踐58C++程序設(shè)計及項目實踐59例9.23利用函數(shù)指針實現(xiàn)通用的排序功能,支持任意基礎(chǔ)數(shù)據(jù)類型(整型、浮點(diǎn)型、字符型)數(shù)組的增序或降序排列。思路:設(shè)計一個模板函數(shù)boolselectSort(T*a,intn,bool(*pfun)(T,T)),其中第三個參數(shù)為函數(shù)指針,并另外編寫兩個模板函數(shù)booldescend(Tx,Ty),boolascend(Tx,Ty),在函數(shù)調(diào)用時,將這兩個函數(shù)名傳遞進(jìn)第一個函數(shù),從而可以控制升序或降序。C++程序設(shè)計及項目實踐60例9.23利用函數(shù)指針實現(xiàn)通用的排序功能,支持任意基礎(chǔ)數(shù)據(jù)類型(整型、浮點(diǎn)型、字符型)數(shù)組的增序或降序排列。程序代碼:01#include<iostream>02usingnamespacestd;0304template<typenameT>05booldescend(Tx,Ty)06{07returnx>y;08}0910template<typenameT>11boolascend(Tx,Ty)12{13returnx<y;14}1516template<typenameT>17boolselectSort(T*a,intn,bool(*pfun)(T,T))18{19for(inti=0;i<n-1;i++)20{21for(intj=i+1;j<n;j++)22{23if(!pfun(a[i],a[j]))24{25Tt=a[i];26a[i]=a[j];27a[j]=t;28}29}30}31returntrue;32}3334intmain(){35inta[8]={1,2,3,4,5,6,7,8};36selectSort(a,8,descend);37for(intx:a)38{39cout<<x<<'\t';40}41cout<<endl;42doubleb[7]={7.6,6.5,5.4,4.3,3.2,2.1,1.0};43selectSort(b,7,ascend);44for(doubley:b)45{46cout<<y<<'\t';47}48cout<<endl;49return0;50}C++程序設(shè)計及項目實踐61例9.24使用鏈表管理學(xué)生信息思路:管理學(xué)生信息主要包括對學(xué)生信息的增加、刪除、修改、查詢、瀏覽操作,可以利用鏈表來管理所有學(xué)生信息,并使用各個函數(shù)在鏈表上進(jìn)行操作。C++程序設(shè)計及項目實踐62例9.24使用鏈表管理學(xué)生信息程序代碼:01#include<iostream>02#include<cstring>03usingnamespacestd;04 05structStudent06{07intid;08charname[20];09Student*pNext;10};1112//增加一個節(jié)點(diǎn)13Student*addNode(Student*head)14{15Student*p=newStudent;16cout<<"id:";17cin>>p->id;18cout<<"name:";19cin>>p->name;20p->pNext=head;21returnp;22}2324//顯示鏈表25voidshowList(Student*head)26{27Student*p=head;28while(p!=NULL)29{30cout<<p->id<<'\t'<<p->name<<endl;31p=p->pNext;32}33}3435//刪除鏈表36voidclearList(Student*head)37{38Student*p=head,*pt;39while(p!=NULL)40{41pt=p;42p=p->pNext;43deletept;44}45}4647//查詢節(jié)點(diǎn)48boolfindNode(Student*head)49{50cout<<"findid:";51intn;52cin>>n;53Student*p=head;54while(p!=NULL)55{56if(p->id==n)57{58cout<<"ok:"<<p->name<<endl;59returntrue;60}61p=p->pNext;62}63cout<<"no"<<endl;64returnfalse;65}6667//修改節(jié)點(diǎn)68boolmodifyNode(Student*head)69{70cout<<"modifyid:";71intn;
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年一級注冊建筑師考試題庫300道含完整答案【各地真題】
- 健康促進(jìn)的未來發(fā)展趨勢
- 《整數(shù)除以分?jǐn)?shù)》數(shù)學(xué)課件教案
- 保護(hù)黃河的倡議書15篇
- 《基于BIM的綠色建筑施工進(jìn)度優(yōu)化與能源管理研究》教學(xué)研究課題報告
- 高中生物教師教學(xué)畫像構(gòu)建中的多源數(shù)據(jù)融合與教學(xué)效果評價教學(xué)研究課題報告
- 2025年寵物醫(yī)療美容行業(yè)品牌建設(shè)與營銷策略報告
- 2025年CFA考試Level1真題集
- 中共榮縣國有資產(chǎn)監(jiān)督管理工作委員會2025年榮縣縣屬國有企業(yè)公開招考人才儲備庫人員(60人)筆試參考題庫附帶答案詳解(3卷合一版)
- 項目經(jīng)理考試題及答案解析
- 2025陜西西安市工會系統(tǒng)開招聘工會社會工作者61人歷年題庫帶答案解析
- 外賣平臺2025年商家協(xié)議
- 2025年高職(鐵道車輛技術(shù))鐵道車輛制動試題及答案
- (新教材)2026年人教版八年級下冊數(shù)學(xué) 24.4 數(shù)據(jù)的分組 課件
- 2025陜西榆林市榆陽區(qū)部分區(qū)屬國有企業(yè)招聘20人考試筆試模擬試題及答案解析
- 老年慢性病管理及康復(fù)護(hù)理
- 2026年海南經(jīng)貿(mào)職業(yè)技術(shù)學(xué)院單招(計算機(jī))考試參考題庫及答案1套
- 代辦執(zhí)照合同范本
- 2025昆明市呈貢區(qū)城市投資集團(tuán)有限公司及下屬子公司第一批招聘(12人)(公共基礎(chǔ)知識)測試題附答案解析
- 2025年國家公務(wù)員錄用考試《行測+申論》真題卷(地市級)及答案解析
- (2025年)教育博士(EdD)教育領(lǐng)導(dǎo)與管理方向考試真題附答案
評論
0/150
提交評論