2014c課件6指針與引用_第1頁
2014c課件6指針與引用_第2頁
2014c課件6指針與引用_第3頁
2014c課件6指針與引用_第4頁
2014c課件6指針與引用_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

C++程序設(shè)計計算機專業(yè)核心基礎(chǔ)課程淮陰工學(xué)院計算機工程學(xué)院回顧前面我們學(xué)習(xí)了:指針與數(shù)組、字符串(數(shù)組)的關(guān)系;指針與函數(shù)的關(guān)系。下面請同學(xué)們練習(xí):

P196:第4題。P197:第11題。練習(xí)3 P196:第10題。constintN=5;voidinput(char*p[],intn){ chars[50]; inti; for(i=0;i<n;i++) { cin>>s; p[i]=newchar[strlen(s)+1]; strcpy(p[i],s); }}voidsort(char*p[],intn){ inti,j,k; char*pt; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(strcmp(p[k],p[j])>0) k=j; if(i!=k) { pt=p[k]; p[k]=p[i]; p[i]=pt; } }}練習(xí)4 設(shè)計返回指針值的函數(shù),將輸入的一個字符串按逆向輸出。char*fun(char*p1){

while(*p1++);

指針p1移到s1的串尾

p1--; returnp1;

返回指向目標(biāo)串尾地址的指針p1}6.4 引用(一)什么是引用引用是個別名,用另一個變量或?qū)ο?目標(biāo))的名字初始化它。引用作為目標(biāo)的別名而使用,對引用的改動實際就是對目標(biāo)的改動。引用能使用任何合法變量名。為建立引用,先寫上目標(biāo)的類型,后跟引用運算符“&”,然后是引用的名字。 例如,引用一個整型變量:

intsomeInt;

int&rInt=someInt; 聲明rInt是對整數(shù)的引用,初始化為引用someInt。在這里,要求someInt已經(jīng)有聲明或定義,而引用僅僅是它的別名。一、基本概念

引用不是值,不占存儲空間。 聲明引用時,目標(biāo)的存儲狀態(tài)不會改變。引用只有聲明,沒有定義。 引用在聲明時必須被初始化,否則會產(chǎn)生編譯錯誤。 下面的語句包含一個引用的聲明和一個變量的定義:

inty_1=10;

int&rInt=y_1,sa;

6.4 引用不要以為聲明了兩個引用。建議:

為了提高可讀性,不應(yīng)在同一行上同時聲明引用、指針和變量。voidmaximun(int*p,intn,int&max){//求p數(shù)組中n個元素的最大值maxmax=p[0];//初始第1個元素作為最大值

inti;for(i=1;i<n;i++)//掃描后面元素if(p[i]>max)

max=p[i];//對*pmax進行更新}正確方式:指針作為形參,返回目標(biāo)信息//功能:求n個整數(shù)的最大值//程序:ch7_ex9_4.cppconstintL=100;voidmaximun(int*p,intn,int&max);voidmain(){

inta[L],mmax;

input(a,L);

maximun(a,L,mmax);

print(a,L);

cout<<″最大值=″<<mmax<<endl;}6.4 引用(二)引用操作1. 引用地址:引用的地址就是所引用目標(biāo)的地址。2. 引用賦值:即對引用目標(biāo)的賦值。例如:

intintOne;

int&rInt=intOne;

intOne=5;

intintTwo=8;

rInt=intTwo;6.4 引用(三)引用對象與限制條件1. 可以引用常量例如:

double&rr=1;實際過程是:

doubletemp;

temp=double(1);

double&rr=temp; 上面的語句中將臨時變量顯式地表示出來,事實上,臨時變量并不在存放局部變量的棧區(qū)。6.4 引用2. 可以引用指針

int*a;

int*&p=a;

intb=8;

p=&b;如下圖:6.4 引用3.

不可以引用void

如:void&a=3;

是錯誤的因為:

void僅在語法上相當(dāng)于一個類型,而本質(zhì)上不是類型,沒有任何一個變量或?qū)ο蟮念愋蜑関oid。4.不可以引用數(shù)組

如:

inta[10];

int&ra[10]=a;是錯誤的因為:數(shù)組是元素的集合,數(shù)組名表示集合空間的起始地址,不是名副其實的數(shù)據(jù)類型。6.4 引用5. 沒有引用的引用,也沒有引用的指針例如:

inta;

int&ra=a;

int&*p=&ra;

//是錯誤的6. 引用不能用類型來初始化例如:

int&ra=int;

//是錯誤的 因為引用是變量或?qū)ο蟮囊茫皇穷愋偷囊谩?. 有空指針,無空引用例如:

int&ri=NULL;//是錯誤的6.4 引用1.引用傳遞參數(shù) 引用作參數(shù)傳遞的是原來的變量。

voidswap(int&rx,int&ry)

{

inttemp=rx;rx=ry;ry=temp;

}

voidmain()

{

intx=5,y=6;

cout<<"調(diào)用前,x:"<<x<<",y:"<<y<<endl;

swap(x,y);

cout<<"調(diào)用后,x:"<<x<<",y:"<<y<<endl;

}二、引用作函數(shù)參數(shù)6.4 引用傳遞引用的內(nèi)存布局

swap函數(shù)main函數(shù)6.4 引用2. 存在的問題 引用在有些情況下能隱藏錯誤。例如:

inta=10;

intb=20;

swap(a,b);

在沒有看到函數(shù)原型之前,可能會認(rèn)為實參a和b是通過值來傳遞的,從而不能通過函數(shù)調(diào)用來修改它,而事實上卻能夠修改。

引用隱藏了函數(shù)所使用的參數(shù)傳遞的類型,無法從所看到的函數(shù)調(diào)用判斷其是值傳遞還是引用傳遞。

6.4 引用

正因為此,下面的代碼中兩個重載函數(shù)將引起編譯報錯:

voidfn(ints) { //... } voidfn(int&t) { //... } voidmain() { inta=5;

fn(a);

}匹配哪一個函數(shù)?6.4 引用

函數(shù)只能返回一個值,如果需要返回兩個以上值,可用引用傳遞多個參數(shù),讓函數(shù)返回多個信息。這一策略繞過了函數(shù)的返回值,把返回值留給函數(shù)。例如: 下面的程序返回了三個值,兩個是引用,另一個是函數(shù)返回值:

intFactor(intn,int&rSquared,int&rCubed) {

if(n>20||n<0)

returntrue;

rSquared=n*n;

rCubed=n*n*n;

returnfalse; }三、返回多個值6.4 引用

函數(shù)返回值時,要生成一個值的副本。而用引用返回值時,不生成副本。例如:

floattemp; floatfn1(floatr) {

temp=r*r*3.14;

returntemp; } float&fn2(floatr) {

temp=r*r*3.14;

returntemp; }四、用引用返回值6.4 引用 voidmain() {

floata=fn1(5.0)

float&b=fn1(5.0);

floatc=fn2(5.0);

float&d=fn2(5.0);

cout<<a<<endl;

cout<<b<<endl;

cout<<c<<endl;

cout<<d<<endl;

}運行結(jié)果:

78.5

78.5

78.5

78.5第一種方式第二種方式第三種方式第四種方式6.4 引用第一種情況:

這是一般的函數(shù)返回值方式。返回全局變量temp值時,C++創(chuàng)建臨時變量并將temp的值78.5復(fù)制給該臨時變量。返回到主函數(shù)后,賦值語句a=fnl(5.0)把臨時變量的值78.5復(fù)制給a。6.4 引用第二種情況:函數(shù)以值方式返回時,復(fù)制temp的值給臨時變量。返回后,引用b以該臨時變量來初始化,成為臨時變量的別名。由于臨時變量的作用域短暫,所以b面臨無效的危險。在“float&b=fnl(5.0);”之后,臨時變量不再存在。所以引用b以后的值無法確定。6.4 引用第三種情況:函數(shù)返回值不產(chǎn)生副本,直接將變量temp返回給主函數(shù)。主函數(shù)的賦值語句中的左值直接從變量temp中得到復(fù)制,避免了臨時變量的產(chǎn)生。6.4 引用第四種情況:函數(shù)返回一個引用,不產(chǎn)生任何返回值的副本。在主函數(shù)中,一個引用聲明d用該返回值來初始化,使得d成為temp的別名。由于temp是全局變量,所以在d的有效期內(nèi)temp始終保持有效。這樣做法是安全的。6.4 引用

對引用的初始化,可以是變量,可以是常量,也可以是一定類型的堆空間變量。 但是,由于引用不是指針,下面的代碼直接從堆中獲得的變量空間來初始化引用是錯的:

int&

a=new

int[2];a不是指針注意:如果new不能在堆空間成功地獲得內(nèi)存分配,它返回NULL。因為引用不能是NULL,因此,在確認(rèn)它不是NULL之前,程序不能用這一內(nèi)存初始化引用。五、返回堆中變量的引用6.4 引用例如:

voidfn() { int*pInt=newint;

if(pInt==NULL) {

cout<<"errormemoryallocation!";

return;

}

int&

rInt=*pInt;

…… delete&rInt;

}6.4 引用說明:必要時用值傳遞參數(shù)必要時返回值不要返回有可能退出作用域的引用不要引用空目標(biāo)函數(shù)返回信息的4種方式1.函數(shù)名返回方式

intmax(inta,intb){return(a>b)?a:b;}2.指針作為形參方式

voidmaximun(inta,intb,int*PMax){*PMax=(a>b)?a:b;}3.以引用作為形參方式

voidmaximun(inta,intb,int&max)//引用作為函數(shù)參數(shù)具有返回信息作用

{max=(a>b)?a:b;}調(diào)用時:

intmax;

maximun(23,85,max);函數(shù)返回信息的4種方式4.全局變量方式

intmax;

voidmaximun(inta,intb){max=(a>b)?a:b;}調(diào)用時:

maximun(23,85);intmax;inta=23;intb=85;

voidmaximun(){max=(a>b)?a:b;}調(diào)用時:

maximun(23,85);6.4 引用引用和指針使函數(shù)的“黑盒”性被打破。函數(shù)可以訪問不屬于自己??臻g的內(nèi)存。這對把握不住C++的人來說是危險的,而對熟練的程序員來說,正是引用和指針才使函數(shù)只能返回單一值的狀態(tài)被打破,使得函數(shù)功能更趨強大。函數(shù)的副作用是良性還是惡性,各人自有評說,對于函數(shù)潛在的破壞性,是放任自流,還是要適當(dāng)?shù)匾种疲瑢<覀儎颖M了腦筋,直到C++類機制的實現(xiàn),才使函數(shù)的惡性作用得以控制。練習(xí)一

編程實現(xiàn)兩個字符串變量的交換。 例如:

char*ap="hello";

char*bp="howareyou"; 交換的結(jié)果使得ap和bp指向的內(nèi)容分別為:

ap:"howareyou?“ bp:"hello“練習(xí)一 voidSwap(char*&str1,char*&str2) { char*temp=str1; str1=str2; str2=temp; } voidmain() { char*ap="hello"; char*bp="howareyou?"; cout<<ap<<endl<<bp<<endl; Swap(ap,bp); cout<<"交換以后:\n"; cout<<ap<<endl<<bp<<endl; }6.5綜合實例1.字符串處理實例 從鍵盤上輸入兩個字符串:對兩個字符串分別由小到大排序。將它們合并,合并后的字符串按由小到大排序,并刪去相同的字符。顯示排序和合并后的字符串。

程序舉例分析: 對字符串的處理分為三步:從鍵盤上輸入兩個字符串將兩個字符串分別排序?qū)⒆址喜@示處理結(jié)果

字符串排序是指將一個字符串中各個字符按照ASCII值的大小排序。 排序算法很多,如快速排序、冒泡排序等。

程序舉例

合并字符串的步驟:從前往后取A中的字符,并按從前往后的順序與B中的字符比較,若A中的字符較小,則將該字符存入C。取A的下一個字符,繼續(xù)與B中的字符比較。若A中的字符較大,則將B中的字符存入C。取B的下一個字符,繼續(xù)與A中的字符比較。若A與B中的字符相等,則將A或B中的字符存入C。同時取A、B的下一個字符。若A或B字符串到達末尾,則將B或A的剩余部分加到字符串C中。注意:

A、B、C三個字符串如果用字符數(shù)組來表示,C數(shù)組的長度不能小于A、B兩數(shù)組的長度之和。

程序舉例2. 快速排序 編制程序,使用標(biāo)準(zhǔn)庫函數(shù)qsort(),對各類數(shù)組進行排序。(1) 對整數(shù)數(shù)組進行從小到大排序。以一個整數(shù)的各位數(shù)字之和的大小為依據(jù)。 數(shù)組中元素值為:

12,32,42,51,8,16,51,21,19,9(2) 對浮點數(shù)組進行從小到大排序。 數(shù)組中元素為:

32.1,456.87,332.67,442.0,98.12,

451.79,340.12,54.55,99.87,72.5(3) 對字符串?dāng)?shù)組進行從小到大排序。以各字符串的長度為依據(jù),如果長度相等,再比較字符串的值。 數(shù)組中的元素為:

enter,number,size,begin,of,cat,case,

program,certain,a

程序舉例 #include<iostream.h> #include<stdlib.h> intCompIntBitSum(constvoid*a,constvoid*b); intCompFloat(constvoid*a,constvoid*b); intCompStrLen(constvoid*a,constvoid*b);

程序舉例 voidmain() { inta[]={12,32,42,51,8,16,21,19,9}; intanum=sizeof(a)/sizeof(*a); cout<<"\n排序前:\n"; for(inti=0;i<anum;i++) cout<<a[i]<<""; cout<<endl;

qsort(a,anum,sizeof(*a),CompIntBitSum); cout<<"排序后:\n"; for(inti=0;i<anum;i++) cout<<a[i]<<""; cout<<endl;

程序舉例 floatf[]={32.1,456.87,332.67,442.0,98.12, 451.79,340.12,54.55,99.87,72.5}; intfnum=sizeof(f)/sizeof(*f); cout<<"\n排序前:\n"; for(inti=0;i<fnum;i++) cout<<f[i]<<""; cout<<endl; qsort(f,fnum,sizeof(*f),CompFloat); cout<<"排序后:\n"; for(inti=0;i<fnum;i++) cout<<f[i]<<""; cout<<endl;

程序舉例

char*str[]={"enter","number","siz

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論