C++程序設(shè)計(jì) 大學(xué)基礎(chǔ)教程第六章_第1頁(yè)
C++程序設(shè)計(jì) 大學(xué)基礎(chǔ)教程第六章_第2頁(yè)
C++程序設(shè)計(jì) 大學(xué)基礎(chǔ)教程第六章_第3頁(yè)
C++程序設(shè)計(jì) 大學(xué)基礎(chǔ)教程第六章_第4頁(yè)
C++程序設(shè)計(jì) 大學(xué)基礎(chǔ)教程第六章_第5頁(yè)
已閱讀5頁(yè),還剩77頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論