




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
上課請(qǐng)保持安靜!
請(qǐng)關(guān)閉您的手機(jī)!1C++大學(xué)基礎(chǔ)教程第6章指針和引用
北京科技大學(xué)信息基礎(chǔ)科學(xué)系2第六章指針和引用指針(Pointer)是C++和C的一種數(shù)據(jù)類型,
很多其他高級(jí)語(yǔ)言也有類似的數(shù)據(jù)類型;引用(Reference)則是C++所特有的一種數(shù)據(jù)類型本章將學(xué)習(xí):指針和引用的概念;指針和引用的使用;動(dòng)態(tài)內(nèi)存的申請(qǐng)和刪除。3第六章指針和引用6.1指針的概念
6.2指針的運(yùn)算6.3指針和函數(shù)(6.3.2和6.3.4不要求)6.4指針和字符串
6.5通過(guò)指針訪問數(shù)組(6.5.3和6.5.4不要求)6.6指針訪問動(dòng)態(tài)內(nèi)存6.7引用概念4本章教學(xué)要求:
掌握指針、指針變量、目標(biāo)變量的基本概念;掌握指針變量的聲明和初始化,指針的運(yùn)算;掌握指針作為函數(shù)的參數(shù),指針和字符串的關(guān)系,指針和數(shù)組的關(guān)系;掌握void指針的應(yīng)用,并能通過(guò)使用指針作為函數(shù)的參數(shù);使用指針訪問字符串、一維數(shù)組和二維數(shù)組;使用指針訪問動(dòng)態(tài)內(nèi)存;掌握引用的聲明和使用。5上節(jié)內(nèi)容回顧內(nèi)存空間的訪問形式通過(guò)變量名直接訪問通過(guò)地址間接訪問指針、指針變量、目標(biāo)變量指針變量的聲明和初始化6關(guān)于內(nèi)存地址內(nèi)存空間的訪問方式通過(guò)變量名直接訪問通過(guò)地址間接訪問取地址運(yùn)算符:&例:int
var;則&var
表示變量var在內(nèi)存中的起始地址7聲明例:
inti;
int*i_pointer=&i;
指向整型變量的指針指針變量的概念概念指針:變量的地址
用于間接訪問變量指針變量:
用于存放地址的變量目標(biāo)變量:指針變量
存放的地址對(duì)應(yīng)的變量20003i_pointer*i_pointeri2000變量
i_pointer內(nèi)存用戶數(shù)據(jù)區(qū)變量i變量j362000200020043010引用例1:i=3;例2:*i_pointer=3;8小結(jié)幾個(gè)概念:指針,指針變量,目標(biāo)變量符號(hào)*:在定義中表示變量為指針變量
int*i_pointer=&i;運(yùn)算符:&:取地址運(yùn)算符*:指向運(yùn)算符
*i_pointer=3;9指針變量的定義和初始化語(yǔ)法形式
數(shù)據(jù)類型*指針名=初始地址;例:
inta;int*pa=&a;注意事項(xiàng)用變量地址作為初值時(shí),該變量必須在指針初始化之前已說(shuō)明過(guò),且變量類型應(yīng)與指針類型一致??梢杂靡粋€(gè)已賦初值的指針去初始化另一個(gè)指針變量。例:charch1=’Y’,ch2=’A’;char*pch1=&ch1,*pch2=&ch2;
char*pch3=pch2;10例1指針的概念#include<iostream.h>voidmain(){inta;
int*pa=&a;a=10;
cout<<"a:"<<a<<endl;
cout<<“*pa:"<<*pa<<endl;
cout<<“&a:"<<&a<<endl;
cout<<"pa:"<<pa<<endl;
cout<<"&pa:"<<&pa<<endl;}10a0012FF7Cpa0012FF780012FF7C內(nèi)存用戶數(shù)據(jù)區(qū)11
6.2指針的運(yùn)算
126.2指針的運(yùn)算
表6.1指針的運(yùn)算136.2.1指針的賦值運(yùn)算
指針變量名=地址指針的賦值運(yùn)算一定是地址的賦值。用來(lái)對(duì)指針變量賦值的可以是:同類型變量的地址;同類型的已經(jīng)初始化的指針變量;其他同類型的指針。此外,也可以用0或者NULL對(duì)指針變量賦值。使得變量包含的是“空指針”,即不指向任何的內(nèi)存物理地址。14指針的賦值運(yùn)算“地址”中存放的數(shù)據(jù)類型與指針類型必須相符。必須注意:不同類型的指針是不可以互相賦值的。在指針賦值時(shí),不存在類型自動(dòng)轉(zhuǎn)換的機(jī)制。向指針變量賦的值必須是地址常量或變量,不能是普通整數(shù)。但可以賦值為整數(shù)0,表示空指針。15
例6.1觀察以下指針賦值運(yùn)算的結(jié)果。如果將注釋去掉,結(jié)果將如何?#include<iostream>usingnamespacestd;voidmain(){intva1=100,*pva1;floatvf1=1.0,*pvf1,*pvf2;
int*pva2=NULL;
cout<<"valueofpva2is"<<pva2<<endl;pva1=&va1;pvf1=pvf2=&vf1;
cout<<pva1<<""<<&va1<<endl;
cout<<pvf1<<""<<pvf2<<endl;
cout<<&pva1<<endl;
cout<<&pvf1<<endl;
cout<<&pvf2<<endl;
//pvf1=pva1;}pvf20012FF6Cpvf10012FF70va11000012FF7Cpva10012FF78vf11.00012FF740012FF7C內(nèi)存用戶數(shù)據(jù)區(qū)0012FF740012FF740pva20012FF6816例指針的定義、賦值與使用#include<iostream.h>voidmain(){ int*i_pointer; //聲明int型指針i_pointer
inti; //聲明int型數(shù)i i_pointer=&i; //取i的地址賦給i_pointer i=10; //int型數(shù)賦初值
cout<<"Outputinti="<<i<<endl;//輸出int型數(shù)的值
cout<<"Outputintpointeri="<<*i_pointer<<endl;//輸出int型指針?biāo)傅刂返膬?nèi)容}176.2.2間接引用運(yùn)算
間接引用運(yùn)算符“*”是一種一元運(yùn)算符,它和指針變量連用,對(duì)指針?biāo)赶虻膬?nèi)存地址單元進(jìn)行間接訪問。使用的格式是:
*指針變量如果指針變量iptr指向整型變量va,*iptr就是變量va的內(nèi)容18
例6.2對(duì)變量的直接訪問和間接訪問:寫出以下程序運(yùn)行結(jié)果。#include<iostream>usingnamespacestd;voidmain(){charch1='a',*ch;
intk1=100;
ch=&ch1; //指針ch指向變量ch1
cout<<"*ch="<<*ch<<endl; //間接訪問*ch='B';
cout<<"ch1="<<ch1<<endl; //直接訪問
ch1=k1;
cout<<"*ch="<<*ch<<endl; //間接訪問
}運(yùn)行結(jié)果:*ch=ach1=B*ch=d19
例6.3定義指向指針的指針變量。觀察對(duì)這種指針變量間接訪問的結(jié)果。#include<iostream>usingnamespacestd;voidmain(){int
va=100,*pva,**ppva;
intk1=100;
pva=&va;
cout<<"*pva="<<*pva<<endl;
ppva=&pva;
cout<<"*ppva="<<*ppva<<endl;
cout<<"pva="<<pva<<endl; }運(yùn)行結(jié)果:*pva=100*ppva=0x0012FF7C
pva=0x0012FF7C
va1000012FF7Cpva0012FF78ppva0012FF740012FF7C內(nèi)存用戶數(shù)據(jù)區(qū)k10012FF701000012FF78206.2.2間接引用運(yùn)算216.2.3指針的算術(shù)運(yùn)算
指針可以進(jìn)行的算術(shù)運(yùn)算只有加法和減法。指針可以和一個(gè)整數(shù)n做加法或者減法運(yùn)算。指針p和整數(shù)n相加(相減)的含義是指向當(dāng)前指向位置p的前方或后方第n個(gè)數(shù)據(jù)的地址。22
例6.4通過(guò)指針的間接訪問,輸出下標(biāo)為偶數(shù)的數(shù)組元素的值。#include<iostream>usingnamespacestd;voidmain(){intk1[10]={11,24,37,44,58,66,79,86,93,108},*k;k=&k1[0]; for(inti=0;i<10;i=i+2)
cout<<"k1["<<i<<"]="<<*(k+i)<<"";
cout<<endl;}
運(yùn)行結(jié)果:K1[0]=11k1[2]=37….
數(shù)組第一個(gè)元素(下標(biāo)為0)的地址賦值給指針k
每次循環(huán),指針加2236.2.3指針的算術(shù)運(yùn)算指針和指針的直接加法是沒有意義的,也是不允許的。指針和指針的減法是可以進(jìn)行的,其意義是求出兩個(gè)指針之間可以存放幾個(gè)指定類型的數(shù)據(jù)。不允許用一個(gè)整數(shù)減一個(gè)指針。246.2.4指針的關(guān)系運(yùn)算和邏輯運(yùn)算
相同類型的指針可以進(jìn)行各種關(guān)系運(yùn)算。比較兩個(gè)指針相等還是不相等。進(jìn)行指針“大于”、“小于”的比較,只是要判定指針在內(nèi)存中的相對(duì)位置。
256.2.4指針的關(guān)系運(yùn)算和邏輯運(yùn)算指向不同數(shù)據(jù)類型的指針,指針和一般的整數(shù)比較是沒有意義的,也是不允許的。惟一可以和指針比較的整數(shù)是0。通過(guò)指針和0的比較來(lái)判定指針本身是不是空指針。即指針可以和零之間進(jìn)行等于或不等于的關(guān)系運(yùn)算。例如:p==0或p!=0指針可以進(jìn)行“邏輯非”運(yùn)算266.2.5void類型指針
void類型的指針就是“無(wú)類型”指針。聲明的方式如下: void*<指針名>;void類型的指針變量中存放的也是內(nèi)存的地址,但是不指定這個(gè)地址單元內(nèi)的數(shù)據(jù)的類型。27void類型指針的使用:任何其他類型的指針都可以賦值給void指針。必須注意,這樣賦值后的void指針的類型仍然是void。void類型指針不可以直接賦值給任何其他類型的指針。無(wú)論何時(shí),void指針都不可以通過(guò)間接引用來(lái)訪問內(nèi)存中的數(shù)據(jù)。28void類型指針的使用:要通過(guò)void類型指針訪問內(nèi)存的數(shù)據(jù),必須進(jìn)行指針類型的強(qiáng)制轉(zhuǎn)換,才可以通過(guò)指針間接引用訪問內(nèi)存數(shù)據(jù)。void類型指針一般不會(huì)獨(dú)立使用,而是作為指針類型轉(zhuǎn)換的中介:某種類型的指針
void指針,進(jìn)行具體操作后強(qiáng)制轉(zhuǎn)換29memcpy函數(shù)函數(shù)原型:void*memcpy(void*dest,constvoid*src,
size_tcount);30
例6.5使用memcpy通用復(fù)制函數(shù)復(fù)制數(shù)組。
#include<iostream>usingnamespacestd;#include<string.h>voidmain(){charsrc[10]="012345678";chardest[10];char*pc=(char*)memcpy(dest,src,10);
cout<<pc<<endl;
ints1[3]={1,2,3};
intd1[3];
int*pi=(int*)memcpy(d1,s1,12);
cout<<*pi<<""<<*(pi+1)<<""<<*(pi+2)<<endl;}
運(yùn)行結(jié)果:012345678123
復(fù)制字符數(shù)據(jù),10個(gè)字節(jié)復(fù)制整型數(shù)據(jù),12個(gè)字節(jié)316.2.5void類型指針
void類型指針還有一個(gè)具體的應(yīng)用:顯示字符指針的內(nèi)容。除了字符指針外,其他指針都可以直接用cout語(yǔ)句來(lái)輸出地址值。但是,用cout輸出字符指針時(shí),則是輸出它所指向的字符串??梢詫⒆址羔槒?qiáng)制轉(zhuǎn)換為void指針,再用cout語(yǔ)句輸出,就可以看到地址值。如:char*pch="HelloC++";cout<<pch<<endl;cout<<(void*)pch<<endl;
inta[3]={1,2,3};cout<<a<<endl;cout<<*a<<endl;charc[]=“hello”;cout<<c<<endl;cout<<*c<<endl;cout<<c+1<<endl;cout<<(void*)c<<endl;326.3指針和函數(shù)
336.3指針和函數(shù)在程序設(shè)計(jì)中,指針有很多應(yīng)用。其中之一就是用指針作為函數(shù)的參數(shù),從而形成了C++函數(shù)調(diào)用中的另一種調(diào)用方式:地址調(diào)用。346.3.1指針作為函數(shù)的參數(shù)函數(shù)的形式參數(shù)是指針變量;函數(shù)的實(shí)參數(shù)是內(nèi)存的地址,具體來(lái)說(shuō)可以是數(shù)組名、變量的地址、用變量地址初始化的指針;形參指針類型和實(shí)參地址類型必須相同。用指針作為函數(shù)參數(shù),實(shí)現(xiàn)地址調(diào)用,必須滿
足以下條件:356.3.1指針作為函數(shù)的參數(shù)實(shí)參傳遞給形參的是內(nèi)存的地址,所以形參指針指向?qū)崊⒆兞?;形參指針通過(guò)間接引用,直接訪問實(shí)參變量,包括改變實(shí)參變量的值;函數(shù)調(diào)用后,可以保留對(duì)實(shí)參變量的操作結(jié)果,如果有多個(gè)實(shí)參,就可以有多個(gè)實(shí)參變量在函數(shù)調(diào)用中得到修改。滿足以上條件后,這樣的函數(shù)調(diào)用在使用上有
以下的特點(diǎn):36
例6.6編寫數(shù)據(jù)交換的函數(shù)。在main中調(diào)用這個(gè)函數(shù),交換main中定義的變量。
#include<iostream>usingnamespacestd;voidSwap(int*a,int*b);voidmain(){ intx(5),y(10);
cout<<"主函數(shù)變量的值:
x="<<x<<"y="<<y<<endl; Swap(&x,&y);
cout<<"返回后變量的值:
x="<<x<<"y="<<y<<endl;}voidSwap(int*a,int*b){ intt; t=*a; *a=*b; *b=t;
cout<<“函數(shù)中完成了交換:*a=“<<*a<<"*b="<<*b<<endl;}運(yùn)行結(jié)果:主函數(shù)變量的值:x=5y=10函數(shù)中完成了交換:*a=10*b=5返回后變量的值:
x=10y=5
變量的地址作為實(shí)參數(shù)指針變量作為形式參數(shù)376.3.1指針作為函數(shù)的參數(shù)程序中用變量x和y的地址作實(shí)參,傳遞給指針a和b,如圖6.1(a)。通過(guò)間接引用*a和*b進(jìn)行交換,實(shí)際上就是x和y進(jìn)行交換,如圖6.1(b)。
38指針變量作為實(shí)參調(diào)用函數(shù)例6.7指針變量指向一個(gè)數(shù)組。用指針變量作為實(shí)參調(diào)用一個(gè)函數(shù)。在函數(shù)中指針指向數(shù)組的第二個(gè)元素。觀察函數(shù)返回后,實(shí)參指針值有無(wú)變化。39
#include<iostream>usingnamespacestd;voidMove(int*a);voidmain(){ intx[5]={10,20,30,40,50},*px=x;
cout<<"調(diào)用前的*px="<<*px<<endl;
Move(px);
cout<<"調(diào)用后的px"; if(px==x)cout<<"沒有變化,*px還是"<<*px<<endl; elsecout<<"也向前移動(dòng),*px變?yōu)?<<*px<<endl;}voidMove(int*a){ a=a+1;
cout<<"函數(shù)中完成了指針移動(dòng):*a="<<*a<<endl;}
運(yùn)行結(jié)果:調(diào)用前的*px=10
函數(shù)中完成了指針移動(dòng):*a=20調(diào)用后的px沒有變化*px還是10
指針作為實(shí)參數(shù)指針變量作為形式參數(shù)406.3.3傳遞參數(shù)的保護(hù):指針和常量通過(guò)數(shù)組名的地址調(diào)用,可以改變實(shí)參數(shù)組的內(nèi)容。但是,并不是所有以數(shù)組名作為實(shí)參的函數(shù)調(diào)用,都需要改變數(shù)組的值。例如,在調(diào)用一個(gè)求數(shù)組最大值的函數(shù)時(shí),就不希望數(shù)組的值發(fā)生變化。希望在函數(shù)中能夠限制對(duì)數(shù)組元素的修改。使用常指針可以達(dá)到這個(gè)目的。416.3.3傳遞參數(shù)的保護(hù):指針和常量常指針是指向常量的指針(PointertoConstantdata)的習(xí)慣說(shuō)法。就是規(guī)定指針?biāo)赶虻膬?nèi)容不可以通過(guò)指針的間接引用來(lái)改變。常指針說(shuō)明的格式是:
const<類型名>*<指針名>;
例如:constint*ptint;
指針ptint的類型是(constint*),也就是指向一個(gè)恒定的整型數(shù)。42
例6.10常指針示例。觀察以下程序的運(yùn)行。
#include<iostream>usingnamespacestd;voidmain(){int
ia=10,ib=20;constint*ptint; ptint=&ia; //用ia地址初始化cout<<*ptint<<endl;ptint=&ib; //改變?yōu)閕b的地址ib=ib+100; //ib本身仍然可以改變cout<<*ptint<<endl;//*ptint=100;
//語(yǔ)句錯(cuò)誤:左值是常量}
運(yùn)行結(jié)果:10
120常指針聲明注釋去掉會(huì)出現(xiàn)編譯錯(cuò)誤436.3.3傳遞參數(shù)的保護(hù):指針和常量指針常量(Pointerconstant)。指針本身的內(nèi)容是個(gè)常量,不可以改變。指針常量聲明的格式是:
<類型名>*const<指針名>=<初值>;例如: charch,*constptch=&ch;
數(shù)組名就是數(shù)組的首地址?,F(xiàn)在可以說(shuō):數(shù)組名就是一個(gè)指針常量。
44
例6.11指針常量示例。指出以下程序的錯(cuò)誤。#include<iostream>usingnamespacestd;voidmain()
{inta=10,b=100;
int*constpa=&a; //pa是指針常量
cout<<*pa<<endl; *pa=20; //指針常量的間接引用是允許的
cout<<a<<endl; pa=&b;
constintc=50;// int*constpc=&c; }
錯(cuò)誤語(yǔ)句注釋掉后運(yùn)行結(jié)果:10
20語(yǔ)句有錯(cuò):常量不能當(dāng)左值語(yǔ)句有錯(cuò),地址類型不同//45
例6.12用常指針作形參,函數(shù)printString可以輸出數(shù)組的內(nèi)容,不可以對(duì)數(shù)組修改。
#include<iostream>usingnamespacestd;voidprintString(constchar*);voidmain(){charphrase[]="C++isamodernprogramminglanguage";
cout<<"Thestringis:\n";
printString(phrase);
cout<<endl;}voidprintString(constchar*Ptarray){while(*Ptarray) {//*Ptarray=*Ptarray+1;
cout<<*Ptarray++;} }不使用常指針也是可以完成打印。但是沒有保護(hù)了。數(shù)組名作實(shí)參數(shù)常指針作形式參數(shù)466.4指針和字符串
476.4.1字符串處理的兩種方式C++字符串常量是用雙引號(hào)括起的字符序列,并以字符‘\0’作為結(jié)束標(biāo)志。如
"Thisisastring"。字符串常量存放在內(nèi)存的某個(gè)區(qū)域,有自己固定的首地址。如果將字符串常量的首地址看成是指針,這種指針既是常指針,也是指針常量。486.4.1字符串處理的兩種方式C++處理字符串有兩種方式:數(shù)組方式和指針方式。數(shù)組方式是將字符串存入字符數(shù)組后,再進(jìn)行處理。一般可以在聲明數(shù)組的時(shí)候用字符串來(lái)初始化:charstring_array[]="aniceday!";指針方式是用字符串常量來(lái)初始化一個(gè)字符指針:char*string_pt="aniceday!";496.4.1字符串處理的兩種方式常量不能放在等式左邊運(yùn)行時(shí)會(huì)出錯(cuò)50
例6.14strcpy和strncpy的比較。#include<iostream>#include<string>usingnamespacestd;voidmain(){intn;char*array1="HappyBirthdaytoYou";chararray3[15];chararray2[25];
strcpy(array2,array1);
cout<<"Thestringinarray1is:"<<array1<<"\nThestringinarray2is:"<<array2<<'\n';/*strcpy(array3,array1);
cout<<array3<<endl;*/n=sizeof(array3);
strncpy(array3,array1,n-1);//復(fù)制array1n-1個(gè)字符到array3array3[14]='\0'; //添加'\0'到array3
cout<<"Thestringinarray3is:"<<array3<<endl;}不包括提示的運(yùn)行結(jié)果HappyBirthdaytoYouHappyBirthdaytoYouHappyBirthday
復(fù)制array1到array2,沒有問題復(fù)制array1到array3,空間不夠,有運(yùn)行錯(cuò)誤按實(shí)際數(shù)組大小,復(fù)制array1到array3,沒有問題516.5通過(guò)指針訪問數(shù)組
526.5通過(guò)指針訪問數(shù)組指針和數(shù)組有天然的聯(lián)系。因?yàn)閿?shù)組名本身就是地址,也就是某種類型的指針。將指針和數(shù)組名聯(lián)系起來(lái),訪問數(shù)組就多了一種方法。雖然一維數(shù)組名和二維數(shù)組名都是地址,都可以看作是某種指針,但是指針的類型是不同的。因此,通過(guò)指針訪問一維數(shù)組和二維數(shù)組的方法是不同的。
536.5.1通過(guò)指針訪問一維數(shù)組要通過(guò)指針訪問一維數(shù)組,必須首先聲明一個(gè)和數(shù)組類型相同的指針,并且用數(shù)組名來(lái)對(duì)指針初始化,如:
intA[10],*pa=A;然后,就可以用多種方式訪問數(shù)組元素:數(shù)組名和下標(biāo),如A[0]、A[4];指針和下標(biāo),如pa[0]、pa[4];指針加偏移量的間接引用,如*(pa+4);數(shù)組名加偏移量的間接引用,如*(A+4);指針自加后的間接引用,如*pa++。
54
例6.15求數(shù)組內(nèi)所存放的字符串的長(zhǎng)度。#include<iostream>usingnamespacestd;voidmain(){charChArray[]="Thisisastring.",*ptch;
inti,j,k,offset1,offset2;
ptch=ChArray; //指針初始化
for(i=0;ChArray[i]!='\0';i++);
cout<<"Thelengthofthestringis:"<<i<<endl;
for(j=0;ptch[j]!='\0';j++);
cout<<"Thelengthofthestringis:"<<j<<endl;
for(offset1=0;*(ChArray+offset1)!='\0';offset1++);
cout<<"Thelengthofthestringis:"<<offset1<<endl;
for(offset2=0;*(ptch+offset2)!='\0';offset2++);
cout<<"Thelengthofthestringis:"<<offset2<<endl;
for(k=0;*ptch++!='\0';k++);
cout<<"Thelengthofthestringis:"<<k<<endl;}
運(yùn)行結(jié)果都相同方式1:數(shù)組名和下標(biāo)方式2:指針和下標(biāo)方式3:數(shù)組名加偏移量的間接引用方式4:指針加偏移量的間接引用方式5:指針自加的間接引用55
例6.16求整型數(shù)組的平均值,顯示數(shù)組元素和平均值。#include<iostream>usingnamespacestd;voidmain(){int
intArray[10]={8,11,23,34,45,56,65,78,86,97},*ptint;
inti,num,sum;floataverage;
ptint=intArray;
sum=0;num=sizeof(intArray)/sizeof(*intArray);
for(i=0;i<num;i++)sum=sum+*ptint++;average=(float)sum/num;
ptint=intArray;
cout<<"數(shù)組元素是:\n";
for(i=0;i<num;i++)
cout<<*ptint++<<"";
cout<<"\n平均值是:"<<average<<endl;}
數(shù)組元素是:8112334455665788697平均值是:50.3
指針初始化求數(shù)組元素的數(shù)目求平均值指針再次初始化輸出數(shù)組元素和它們的平均值566.5.2通過(guò)指針訪問二維數(shù)組二維數(shù)組可以看成是一維數(shù)組的一維數(shù)組。二維數(shù)組名雖然也是地址(指針),但是卻和一維數(shù)組名有不同的類型。對(duì)一維數(shù)組A[5],數(shù)組名A的地址,就是數(shù)組第一個(gè)元素A[0]的地址。指針的類型是指向數(shù)組元素的指針。A+1就是元素A[1]的地址。576.5.2通過(guò)指針訪問二維數(shù)組對(duì)二維數(shù)組B[3][4],數(shù)組名B的地址,則是其中第一個(gè)一維數(shù)組B[0]的地址。指針的類型是指向一維數(shù)組的指針。B+1就是下一個(gè)一維數(shù)組B[1]的地址。如圖6.3所示。
586.5.2通過(guò)指針訪問二維數(shù)組在定義指向一維數(shù)組的指針時(shí),還必須指出一維數(shù)組的大小。聲明指向一維數(shù)組的指針的格式如下: <類型名>(*指針變量名)[一維數(shù)組大小];
例如,和圖6.3中兩個(gè)二維數(shù)組所對(duì)應(yīng)的指向一維數(shù)組的指針定義如下:char(*ptchb)[4],(*ptchc)[2];ptchb=B;ptchc=C;596.5.2通過(guò)指針訪問二維數(shù)組對(duì)于指向一維數(shù)組的指針,具有以下的特征:
二維數(shù)組名是指向一維數(shù)組的指針,而不是指向數(shù)組元素的指針。
指向一維數(shù)組指針加1的結(jié)果,是指向下一個(gè)一維數(shù)組的指針。
指向一維數(shù)組的指針的間接引用的結(jié)果仍然是地址,即*ptchb仍然是地址。只是地址的類型變了。變?yōu)橐痪S數(shù)組B[0]第一個(gè)元素B[0][0]的地址。
因?yàn)?ptchb是數(shù)組元素的地址,**ptchb就是數(shù)組元素的值。用指向一維數(shù)組指針訪問二維數(shù)組第i行第j列元素的一般公式是*(*(指針名+i)+j)。
60指向一維數(shù)組的指針ptchbptchbB[0]的地址*ptchbB[0][0]的地址**ptchbB[0][0]的值*(指針名+i)B[i][0]的地址*(*(指針名+i)+j)B[i][j]的值61
例6.17比較指向一維數(shù)組的指針和指向數(shù)組元素的指針。#include<iostream>usingnamespacestd;voidmain(){shortB[3][4],C[3][2];short(*ptshb)[4],(*ptshc)[2];
ptshb=B;ptshc=C;
cout<<"比較不同的指向一維數(shù)組指針的差別\n";
cout<<"ptshb的地址是:"<<ptshb<<"\n";
cout<<"ptchb+1的地址是:"<<ptshb+1<<"\n";
cout<<"ptchc的地址是:"<<ptshc<<"\n";
cout<<"ptchc+1的地址是:"<<ptshc+1<<"\n";
比較不同的指向一維數(shù)組指針的差別ptshb的地址是:0x0012FF68ptchb+1的地址是:0x0012FF70ptchc的地址是:0x0012FF5Cptchc+1的地址是:0x0012FF60
B的第0行地址
B的第1行地址
C的第0行地址
C的第1行地址62
例6.17比較指向一維數(shù)組的指針和指向數(shù)組元素的指針。
cout<<"不同類型的指針\n";
cout<<"ptshb的地址是:"<<ptshb<<endl;
cout<<"*ptshb的地址是:"<<*ptshb<<endl;
cout<<"*ptshb+1的地址是:"<<*ptshb+1<<endl;
cout<<"B[0][1]的地址是:"<<&B[0][1]<<endl;//cout<<"ptchb和*ptchb相等嗎?"<<(ptchb==*ptchb)<<endl; //有語(yǔ)法錯(cuò)誤
cout<<"*ptshb+1和&B[0][1]相等嗎?";
if(*ptshb+1==&B[0][1])cout<<"Yes"<<endl;}
不同類型的指針ptshb的地址是:0x0012FF68*ptshb的地址是:0x0012FF68*ptshb+1的地址是:0x0012FF6AB[0][1]的地址是:0x0012FF6A*ptshb+1和&B[0][1]相等嗎?Yes
B的第0行地址
B的第0行第0列元素的地址
B的第0行第1列元素的地址
B的第0行第1列元素的地址063
例6.18用單循環(huán)程序,求二維數(shù)組元素的平均值。#include<iostream>usingnamespacestd;voidmain(){int
dArray[3][4]={32,42,12,25,56,76,46,53,76,89,96,82},(*pt)[4];
intsum,j;floataverage;sum=0;pt=dArray;
j=sizeof(dArray)/sizeof(**dArray); for(inti=0;i<j;i++) sum=sum+*(*pt+i);average=(float)sum/j;
cout<<"數(shù)據(jù)的平均值等于:"<<average<<endl;}
運(yùn)行結(jié)果:數(shù)據(jù)的平均值等于57.0833指向一維數(shù)組指針的初始化求數(shù)組元素的數(shù)目,**dArray就是元素dArray[0][0]數(shù)組求和求平均值輸出平均值646.6指針訪問動(dòng)態(tài)內(nèi)存656.6指針訪問動(dòng)態(tài)內(nèi)存
動(dòng)態(tài)內(nèi)存是在程序執(zhí)行時(shí)才可以申請(qǐng)、使用和釋放的內(nèi)存。也就是存放動(dòng)態(tài)數(shù)據(jù)的內(nèi)存區(qū)域。存放動(dòng)態(tài)數(shù)據(jù)的區(qū)域稱為“堆”,動(dòng)態(tài)內(nèi)存也稱為堆內(nèi)存。動(dòng)態(tài)內(nèi)存不能通過(guò)變量名來(lái)使用,而只能通過(guò)指針來(lái)使用。666.6.1動(dòng)態(tài)內(nèi)存的申請(qǐng)和釋放C++中通過(guò)運(yùn)算符new申請(qǐng)動(dòng)態(tài)內(nèi)存,運(yùn)算符delete釋放動(dòng)態(tài)內(nèi)存。動(dòng)態(tài)內(nèi)存申請(qǐng)運(yùn)算符new的使用格式:
new<類型名>(初值)運(yùn)算的結(jié)果:如果申請(qǐng)成功,返回指定類型內(nèi)存的地址;如果申請(qǐng)失敗,返回NULL指針。int*pi;pi=newint(10);動(dòng)態(tài)內(nèi)存使用完畢后,要用delete運(yùn)算來(lái)釋放。delete運(yùn)算符使用格式:
delete<指針名>;
676.6.2動(dòng)態(tài)數(shù)組空間的申請(qǐng)和釋放申請(qǐng)動(dòng)態(tài)一維數(shù)組時(shí),要在new表達(dá)式中加上申請(qǐng)數(shù)組的大?。簄ew<類型名>[常量表達(dá)式];注意:在動(dòng)態(tài)申請(qǐng)數(shù)組空間時(shí),不可以對(duì)數(shù)組進(jìn)行初始化。申請(qǐng)一個(gè)動(dòng)態(tài)的整型數(shù)組:
int*piarray;
piarray=newint[10];也可以申請(qǐng)二維數(shù)組的空間:
int(*pi_marray)[4];pi_marray=newint[3][4];釋放動(dòng)態(tài)數(shù)組空間都用相同的表達(dá)式:delete[]<指針名>;
686.6.3內(nèi)存泄漏和指針懸掛
內(nèi)存泄漏是指動(dòng)態(tài)申請(qǐng)的內(nèi)存空間,沒有正常釋放,但是也不能繼續(xù)使用的情況。如:char*ch1;ch1=newchar('A');char*ch2=newchar;ch1=ch2;原來(lái)為ch1所申請(qǐng)的存放字符A的空間就不可能再使用了,產(chǎn)生了內(nèi)存泄漏。696.6.3內(nèi)存泄漏和指針懸掛讓指針指向一個(gè)已經(jīng)釋放的空間,即所謂的指針懸掛(Dangling)。如:char*ch1,*ch2;ch1=newchar;ch2=ch1;*ch2='B';deletech1;指針ch2就是指向了一個(gè)已經(jīng)釋放的地址空間,形成指針懸掛。如果還要用deletech2;語(yǔ)句來(lái)釋放ch2所指向的空間,就會(huì)出現(xiàn)運(yùn)行錯(cuò)誤。706.7引用概念716.7引用概念引用(Reference)是C++中新引入的概念,也是C語(yǔ)言中不存在的數(shù)據(jù)類型。
引用是變量或者其他編程實(shí)體(如對(duì)象)的別名。因此,引用是不可以單獨(dú)定義的。如圖6.4(a)所示,變量A在內(nèi)存中有自己的地址,而A的引用B實(shí)際上就是變量A,只是A的另外一個(gè)名字。
726.7.1引用的聲明和使用引用是通過(guò)運(yùn)算符&來(lái)定義的,定義的格式如下:
<類型名>&引用名=變量名;其中的變量名必須是已經(jīng)定義的,并且和引用的類型必須相同。例如:
int
someInt;
int&refInt=someInt;必須注意:引用必須在聲明的時(shí)候就完成初始化,不可以先聲明引用,然后再用另一個(gè)語(yǔ)句對(duì)它初始化。
736.7.1引用的聲明和使用引用有以下的特點(diǎn):引用不能獨(dú)立存在,它只是其他變量的別名;引用必須在聲明的同時(shí)就初始化;引用一旦定義,引用關(guān)系就不可以更改,即B若是A的引用,就不可能是其他變量的引用;引用的類型就是相關(guān)的變量的類型,引用的使用和變量的使用相同。74
例6.22引用的使用。觀察以下程序的結(jié)果。
#include<iostream>usingnamespacestd;voidmain(){int
intA=10;
int&refA=intA;
cout<<"引用的值和相關(guān)變量值相同:refA="<<refA<<endl;
refA=5;
cout<<"引用的變化,則相關(guān)變量也變化:intA="<<intA<<endl;
cout<<"引用的地址和相關(guān)變量地址相同:intA的地址="<<&intA<<endl;
cout<<"引用的地址和相關(guān)變量地址相同:refA的地址="<<&refA<<endl;}引用的值和相關(guān)變量值相同:refA=10引用的變化,則相關(guān)變量也變化:intA=5引用的地址和相關(guān)變量地址相同:intA的地址=0x0012FF7C引用的地址和相關(guān)變量地址相同:refA的地址=0x0012FF7C756.7.1常引用如果不希望通過(guò)引用來(lái)改變相關(guān)的變量的值,則可以定義常引用。常引用定義的格式:
const<類型名>&引用名=變量名;例如:int
someInt=10;constint&const_refA=someInt;例如:const_refA=50;
此時(shí),const_refA就是常引用。不可以通過(guò)const_refA來(lái)改變someInt變量的值。76
例6.23指針的引用。
#include<iostream>usingnamespacestd;voidmain(){int
intA=10,intB=20;
int*pti=&intA;
int*&refi=pti;
cout<<"指針的引用可以訪問指針?biāo)傅淖兞?*refi="<<*refi<<endl;
cout<<"指針變量原來(lái)的值:pti="<<pti<<endl;
refi=&intB;
cout<<"引用的變化,則相關(guān)指針也變化:pti="
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 中醫(yī)內(nèi)科病案例分析
- 甘肅稅法考試題及答案
- 文職智力測(cè)試題及答案
- 求教師面試題及答案
- 陶瓷機(jī)械試題及答案
- ICU氣管切開護(hù)理
- 細(xì)胞信號(hào)通路解析2025年創(chuàng)新藥物靶點(diǎn)發(fā)現(xiàn)與驗(yàn)證技術(shù)報(bào)告
- 腫瘤疾病病人護(hù)理指南
- 歷史文物保護(hù)修復(fù)技術(shù)理論題
- 2025年廢舊電子產(chǎn)品無(wú)害化處理與資源回收技術(shù)發(fā)展現(xiàn)狀報(bào)告
- 天然氣管道工程管道焊接施工方案
- GB/T 95-2002平墊圈C級(jí)
- GB/T 16823.3-1997螺紋緊固件擰緊試驗(yàn)方法
- 2023年鎮(zhèn)江丹陽(yáng)市民政局系統(tǒng)事業(yè)單位招聘筆試模擬試題及答案
- 幼兒園消防安全組織機(jī)構(gòu)圖
- 英語(yǔ)社團(tuán)活動(dòng)課件
- 第三方檢測(cè)市場(chǎng)部管理制度提成方案
- 學(xué)前兒童發(fā)展心理學(xué)-情感
- GB∕T 16762-2020 一般用途鋼絲繩吊索特性和技術(shù)條件
- 電網(wǎng)施工作業(yè)票模板
- 安徽省小學(xué)學(xué)生學(xué)籍表
評(píng)論
0/150
提交評(píng)論