第-章━━指針與函數(shù)指針與堆內(nèi)存優(yōu)秀文檔_第1頁
第-章━━指針與函數(shù)指針與堆內(nèi)存優(yōu)秀文檔_第2頁
第-章━━指針與函數(shù)指針與堆內(nèi)存優(yōu)秀文檔_第3頁
第-章━━指針與函數(shù)指針與堆內(nèi)存優(yōu)秀文檔_第4頁
第-章━━指針與函數(shù)指針與堆內(nèi)存優(yōu)秀文檔_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

C++程序設計第4章(3)

━━指針與函數(shù)、指針與堆內(nèi)存1主要內(nèi)容指針作為函數(shù)參數(shù)指針作為函數(shù)返回值指向函數(shù)的指針C++的四個內(nèi)存區(qū)域動態(tài)存儲分配堆內(nèi)存new與delete運算符動態(tài)存儲分配的幾點說明使用new和delete的幾點說明常指針指向常量的指針類型標識符的定義2指針作為函數(shù)參數(shù)作用:指針作為函數(shù)參數(shù),可以使主調(diào)函數(shù)與被調(diào)函數(shù)之間共享變量或?qū)ο?,以實現(xiàn)函數(shù)之間數(shù)據(jù)的雙向傳遞。地址傳遞:①若某函數(shù)的一個形參定義為指針類型,則調(diào)用該函數(shù)時其對應的實參可以是:

◆相同類型的變量(或?qū)ο螅┑牡刂?/p>

◆相同類型的指針變量

◆相同類型的數(shù)組名②由于實參是一個地址,將該地址傳遞給了對應的形參指針變量,此時形參指針變量與實參指針指向的是同一個內(nèi)存區(qū)域的變量(或?qū)ο螅虼巳粼诒徽{(diào)函數(shù)中修改了形參指針變量所指向的數(shù)據(jù),也就修改了主調(diào)函數(shù)中實參指針所指向的數(shù)據(jù)。3【例】(值傳遞、引用傳遞、地址傳遞━━函數(shù)的參數(shù)三種傳遞方式的比較)#include<iostream.h>voidswap1(

intp1

,

intp2

){

inttemp=p1;p1=p2;p2=temp;}voidswap2(

int&p1

,

int&p2

){

inttemp=p1;p1=p2;p2=temp;}voidswap3(

int*p1

,

int*p2

){

inttemp=*p1;*p1=*p2;

*p2=temp;}voidswap4(

int*p1,

int*p2

){

int*temp=p1;p1=p2;

p2=temp;}voidmain(){inta=3,b=6;cout<<“a=”<<a<<“\tb=”<<b<<endl;

swap1(

a,b

)

;cout<<“a=”<<a<<“\tb=”<<b<<endl;a=3;b=6;cout<<“a=”<<a<<“\tb=”<<b<<endl;

swap2(

a,b)

;cout<<“a=”<<a<<“\tb=”<<b<<endl;a=3;b=6;cout<<“a=”<<a<<“\tb=”<<b<<endl;

swap3(

&a,&b

);cout<<“a=”<<a<<“\tb=”<<b<<endl;a=3;b=6;cout<<“a=”<<a<<“\tb=”<<b<<endl;

swap4(

&a,&b

)

;cout<<“a=”<<a<<“\tb=”<<b<<endl;}運行:a=3b=6a=3b=

6a=3b=6a=

6

b=

3a=3b=6a=

6

b=

3a=3b=6a=

3

b=

64【例】(形參為指針類型,實參可以是相同類型的數(shù)組名)#include<iostream.h>voidsort1(

int*p,intn

)//對p指針所指向的n個元素的數(shù)組按升序排序{

inti,j,t;for(i=0;i<n-1;i++)//選擇排序法for(j=i+1;j<n;j++)if(*(p+i)>*(p+j)){t=*(p+i);*(p+i)=*(p+j);*(p+j)=t;}}voidsort2(

int*p,intn

)//對p指針所指向的n個元素的數(shù)組按升序排序{

inti,j,t;for(i=0;i<n-1;i++)//選擇排序法for(j=i+1;j<n;j++)if(p[i]>p[j]){t=p[i];p[i]=p[j];p[j]=t;}}voidsort3(

intp[],intn

)//對n個元素的p數(shù)組按升序排序{

inti,j,t;for(i=0;i<n-1;i++)//選擇排序法for(j=i+1;j<n;j++)if(p[i]>p[j]){t=p[i];p[i]=p[j];p[j]=t;}}5voidmain(){inta[6]={43,81,32,11,63,10};intb[6]={43,81,32,11,63,10};intc[6]={43,81,32,11,63,10};intd[6]={43,81,32,11,63,10};inti;

sort1(a,6)

;

for(i=0;i<6;i++)cout<<a[i]<<“\t”;cout<<endl;

sort2(b,6)

;

for(i=0;i<6;i++)cout<<b[i]<<“\t”;cout<<endl;

sort3(c,6)

;

for(i=0;i<6;i++)cout<<c[i]<<“\t”;cout<<endl;

int*point=d;

sort2(point,6)

;

for(i=0;i<6;i++)cout<<d[i]<<“\t”;cout<<endl;}運行:11324363811011324363811011324363811011324363816【例】(設計通用的兩矩陣相乘的函數(shù))

分析:a為m×n矩陣,b為n×p矩陣,a乘以b得到c矩陣,則c為m×p的矩陣。k=n-1矩陣相乘公式:cij=

∑aik×bkj

k=0#include<iostream.h>voidmatrixmul(

float*pa,float*pb,float*pc,intm,intn,intp){

inti,j,k;floatt;for(i=0;i<m;i++)for(j=0;j<p;j++){t=0;for(k=0;k<n;k++)t+=

(*(pa+i*n+k))

*

(*(pb+k*p+j));

(*(pc+i*p+j))=t;}

}voidmain(){floata[2][3]={{1,2,3},{4,5,6}};floatb[3][5]={{1,2,3,4,5},{6,7,8,9,6},{5,4,3,2,1}};floatc[2][5];

matrixmul(*a,*b,*c,2,3,5)

;inti,j;

for(i=0;i<2;i++){for(j=0;j<5;j++)cout<<c[i][j]<<“\t”;cout<<endl;}}運行:282828282064677073567【例】(求二維數(shù)組的平均值)#include<iostream.h>floataverage1(float*p,intn)//形參p為元素指針{

floatsum=0;inti;for(i=0;i<n;i++)sum+=*p++;returnsum/n;}floataverage2(floatp[][5],intn)//形參p為二維數(shù)組{

floatsum=0;inti,j;for(i=0;i<n;i++)for(j=0;j<5;j++)sum+=p[i][j];returnsum/(n*5);}floataverage3(float(*p)[5],intn)//形參p為行指針{

floatsum=0;inti,j;for(i=0;i<n;i++){for(j=0;j<5;j++)sum+=(*p)[j];p++;}returnsum/(n*5);}voidmain(){floata[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};

cout<<“平均值=”<<average1(*a,15)<<endl;cout<<“平均值=”<<average2(a,3)<<endl;cout<<“平均值=”<<average3(a,3)<<endl;}運行:平均值=8平均值=8平均值=88k=n-1563#include<iostream.voidmain()cout<<s1<<endl;//輸出:XYZ若要賦給元素指針變量,必須進行類型強制轉(zhuǎn)換。if(p==0)exit(0);或if(p==NULL)exit(0);ints3(inta,intb,floatc);491floatf3(floatx)cout<<p(a,b)<<endl;//也可寫成:(*p)(a,b)i=1{t=0;指針作為函數(shù)返回值作用:任一函數(shù),利用return語句可以返回一個值,當函數(shù)的返回值為指針時,返回的必須是一個指向已定義數(shù)據(jù)的指針,且只能返回全局變量或靜態(tài)變量的指針,不能返回局部變量的指針。返回值為指針的函數(shù)的定義:

類型*函數(shù)名(形參列表){函數(shù)體}【例】(實現(xiàn)字符串逆序的函數(shù))#include<iostream.h>char*

flip(char*p){

char*p1,*p2,temp;

p1=p2=p;while(*p2++);p2-=2;while(p1<p2){temp=*p2;*p2--=*p1;*p1++=temp;}returnp;}voidmain(){chars[100];cout<<“請輸入一行字符:”;cin.getline(s,100);cout<<“逆序后:”<<flip(s)<<endl;cout<<“逆序后:”<<

s

<<endl;}sp…\0p1p2p2p2初始狀態(tài)運行:請輸入一行字符:123456ABCDEFGH↙逆序后:HGFEDCBA654321逆序后:HGFEDCBA6543219【例】(用遞歸函數(shù)實現(xiàn)字符串的逆序)#include<iostream.h>//用遞歸函數(shù)實現(xiàn)字符串的逆序char*

flip1(char*p,intn)//對從p所指的字符開始的后面n個字符實現(xiàn)逆序{

chart;

if(n>1){t=p[0];p[0]=p[n-1];p[n-1]=t;flip1(p+1,n-2)

;}returnp;}//用遞歸函數(shù)實現(xiàn)字符串的逆序輸出void

flip2(char*p,inti)//對p所指的字符串從第i個字符開始的字符串逆序輸出{

if(p[i]!=‘\0’)flip2(p,i+1)

;cout<<p[i];}voidmain(){chars[100],*p=s;intn=0;cout<<“請輸入一行字符:”;cin.getline(s,100);while(*p++)n++;

flip1(s,n)

;cout<<“逆序后s=”<<

s

<<endl;cout<<“還原后s=”<<flip1(s,n)

<<endl;cout<<“逆序輸出:”;flip2(s,0)

;cout<<endl;}運行:請輸入一行字符:123456ABCDEFGH↙逆序后s=HGFEDCBA654321還原后s=

123456ABCDEFGH逆序輸出:HGFEDCBA65432110【例】(實現(xiàn)字符串拷貝的函數(shù))#include<iostream.h>char*

copy(char*to,char*from){

char*p=to

;while(*to++=*from++);returnp;}voidmain(){chars1[20],s2[20];cout<<“請輸入一行字符:”;cin.getline(s1,20);cout<<“拷貝前s2=”<<s2<<endl;

copy(s2,s1);cout<<“第1次拷貝后:”<<s2<<endl;

copy(s2,“ABCDEFG”);cout<<“第2次拷貝后:”<<s2<<endl;}運行:請輸入一行字符:123456↙拷貝前s2=燙燙燙燙燙燙燙燙燙燙123456第1次拷貝后:123456第2次拷貝后:ABCDEFGtop…\0from…\0…11【例】(實現(xiàn)字符串拼接的函數(shù))#include<iostream.h>char*

stringcat(char*to,char*from){

char*p=to

;while(*to++

);to--;while(*to++=*from++);returnp;}voidmain(){chars1[20],s2[20];cout<<“請輸入第一個字符串:”;cin.getline(s1,20);cout<<“請輸入第二個字符串:”;cin.getline(s2,20);cout<<“拼接前:s1=”<<s1<<“\ts2=”<<s2<<endl;

stringcat(s1,s2);cout<<“拼接后:s1=”<<s1<<“\ts2=”<<s2<<endl;}運行:請輸入第一個字符串:123456↙請輸入第二個字符串:ABCDEFG↙拼接前:s1=123456s2=ABCDEFG拼接后:s1=123456ABCDEFGs2=ABCDEFGtop…\0tofrom…\0…12指向函數(shù)的指針函數(shù)的指針:函數(shù)的代碼存儲在內(nèi)存中,其起始地址稱為函數(shù)的入口地址,其函數(shù)名代表該函數(shù)的入口地址,可以定義一個指向函數(shù)的指針變量來指向它,即將函數(shù)名賦給該指針變量,這樣就可以通過該指針變量來調(diào)用該函數(shù)。指向函數(shù)的指針變量的定義:返回值類型(

*指針變量名

)(形參列表表);對指向函數(shù)的指針變量的賦值:

指針變量=函數(shù)名

注意:指向函數(shù)的指針變量只能指向與其具有相同返回值類型且相同參數(shù)(參數(shù)類型、個數(shù)、順序均一致)的這一類函數(shù)。通過指向函數(shù)的指針變量來調(diào)用函數(shù):

格式1:

(*指針變量)

(實參列表)格式2:

指針變量

(實參列表)13指向函數(shù)的指針【例】floats1(intx,inty);floats2(inta,intb);ints3(inta,intb,floatc);

float

(*f1)

(int,int);

int

(*f2)

(int,int,float);f1=s1;√這樣f1(3,5);就等價于s1(3,5);f1=s2;√這樣f1(3,5);就等價于s2(3,5);f1=s3;×f2=s3;√這樣f2(3,5,7);就等價于s3(3,5,7);指向函數(shù)的指針常用來作為函數(shù)的參數(shù):那么在調(diào)用該函數(shù)時,其對應的實參只要是與該形參指針變量同類型的函數(shù)名即可,這樣在多次調(diào)用該函數(shù)的過程中,可實現(xiàn)再調(diào)用不同功能的函數(shù)(由對應的實參確定),從而大大增加程序的靈活性。14【例】(分別實現(xiàn)兩個操作數(shù)的加、減、乘、除運算的函數(shù))#include<iostream.h>float

add(floatx,floaty){

cout<<x<<“+”<<y<<“=”;returnx+y;}float

sub(floatx,floaty){

cout<<x<<“-”<<y<<“=”;returnx-y;}float

mul(floatx,floaty){

cout<<x<<“×”<<y<<“=”;returnx*y;}float

div(floatx,floaty){

cout<<x<<“÷”<<y<<“=”;returnx/y;}voidmain(){floata,b;charc;

float

(*p)(float,float);cout<<“請輸入運算式(數(shù)據(jù)運算符數(shù)據(jù)):\n”;cin>>a>>c>>b;

switch(c){case‘+’:p=add;break;case‘-’:p=sub;break;case‘*’:p=mul;break;case‘/’:p=div;break;default:cout<<“運算式輸入錯誤!\n”;return;}cout<<p(a,b)<<endl;//也可寫成:(*p)(a,b)

}第1次運行:請輸入運算式(數(shù)據(jù)運算符數(shù)據(jù)):5*6↙5×6=30第2次運行:請輸入運算式(數(shù)據(jù)運算符數(shù)據(jù)):18/5↙18÷5=3.615【例】(分別實現(xiàn)求一維數(shù)組的各元素和、最大元素、各元素平均值的函數(shù))#include<iostream.h>float

sum(float*p,intn){

floats=0;for(inti=0;i<n;i++)s+=*p++;returns;}float

max(float*p,intn){

floatm=*p++;for(inti=1;i<n;i++){if(*p>m)m=*p;p++;}returnm;}float

ave(float*p,intn){

returnsum(p,n)/n;}void

process(float*p,intn,float(*fp)(float*,int)){

cout<<fp(p,n)<<endl;}voidmain(){floatx[8]={2,8,5,7,6,3,9,4};cout<<“元素和=”;process(

x,8,sum

);cout<<“最大值=”;process(

x,8,max

);cout<<“平均值=”;process(

x,8,ave

);}運行:元素和=44最大值=916【例】(用梯形法求下列三個定積分的近似值)

area1=∫42

(1+x2)

dxarea2=∫1

x/(1+x2)

dx

area3=∫31

(x+x2)/(1+sinx+x2)

dx分析:用梯形法求定積分area=∫ba

f(x)

dx的近似值的通用公式為:

i=n-1area=[

(f(a)+f(b))/2

+

∑f(a+i*h)

h

i=1

其中:a和b分別為積分的下限和上限;n為積分區(qū)間的分隔數(shù);h=(b-a)/n,h為積分步長;f(x)為被積函數(shù)。#include<iostream.h>#include<math.h>float

f1(floatx){

return(1+x*x);}float

f2(floatx){

returnx/(1+x*x);}float

f3(floatx){

return(x+x*x)/(1+sin(x)+x*x);}17常指針變量的聲明:類型*const指針變量名=地址;voidmain()area3=∫31(x+x2)/(1+sinx+x2)dxcout<<p(a,b)<<endl;//也可寫成:(*p)(a,b)請輸入六個整數(shù):563491↙a=3;b=6;cout<<“a=”<<a<<“\tb=”<<b<<endl;#include<iostream.【例】(用梯形法求下列三個定積分的近似值)typedefchar*string;{char*p=to;cout<<“逆序后s=”<<s<<endl;通過指向函數(shù)的指針變量來調(diào)用函數(shù):cout<<“請輸入一行字符:”;cin.若創(chuàng)建成功(堆空間申請成功),new運算返回新分配二維數(shù)組空間的首地址;cout<<endl;…\0{chars[100],*p=s;intn=0;float

jifen(float(*f)(float),floata,floatb,intn){

floaty,h;y=(f(a)+f(b))/2;h=(b-a)/n;for(inti=1;i<n;i++)y+=f(a+i*h);return(y*h);}voidmain(){cout<<“第一個積分值=”;cout<<jifen(f1,2,4,1000)<<endl;cout<<“第二個積分值=”;cout<<jifen(f2,1,2.5,1000)<<endl;cout<<“第三個積分值=”;cout<<jifen(f3,1,3,1000)<<endl;}運行:指向被積函數(shù)的指針變量積分的下限積分的下限積分區(qū)間的分隔數(shù)18C++的四個內(nèi)存區(qū)域C++的四個內(nèi)存區(qū)域:

①代碼區(qū)━━存放程序代碼。

②靜態(tài)數(shù)據(jù)區(qū)━━存放全局變量或?qū)ο?、存放static局部變量或?qū)ο?。全局變量或?qū)ο笤诔绦蜷_始運行時在該區(qū)分配;static局部變量或?qū)ο笤诔绦蜻\行過程中第一次進入其作用域時在該區(qū)分配。該區(qū)的變量或?qū)ο笾钡匠绦蜻\行結束才被釋放。

③局部數(shù)據(jù)區(qū)(棧區(qū))

━━存放auto局部變量或?qū)ο?。auto局部變量或?qū)ο笤诔绦蜻\行到其作用域時在棧區(qū)分配,但怎樣分配在編譯時就已經(jīng)確定。auto局部變量或?qū)ο笤陔x開其作用域時即被釋放。

④動態(tài)存儲區(qū)(自由存儲區(qū)、堆區(qū))

━━存放程序運行過程中由new運算符動態(tài)創(chuàng)建的變量或?qū)ο蟆討B(tài)創(chuàng)建的變量或?qū)ο笤诰幾g時無法為其預定存儲空間,系統(tǒng)根據(jù)運行時的具體要求在該區(qū)分配。該區(qū)的變量或?qū)ο笮枰褂胐elete運算符才能將其釋放。19動態(tài)存儲分配靜態(tài)存儲分配:通常程序中定義的變量或?qū)ο?,編譯器在編譯時就可根據(jù)該變量或?qū)ο蟮念愋椭榔渌鑳?nèi)存空間的大小,即怎樣分配在編譯時就已經(jīng)能夠確定,從而在適當?shù)臅r候為它們分配確定的內(nèi)存空間,這種內(nèi)存分配稱為靜態(tài)存儲分配。動態(tài)存儲分配:有些變量或?qū)ο笾挥性诔绦蜻\行過程中才能確定其大小,這樣編譯器在編譯時就無法為它們預定內(nèi)存空間,只能在程序運行過程中,系統(tǒng)根據(jù)運行時的具體要求進行內(nèi)存分配,稱為動態(tài)存儲分配。動態(tài)存儲分配是在自由存儲區(qū)(堆區(qū))中進行。20堆內(nèi)存關于堆內(nèi)存:堆區(qū)是由操作系統(tǒng)直接管理的內(nèi)存區(qū)域,它是“公共的區(qū)域”,而且“面積”比較大,它的“生命周期”也不是由編譯系統(tǒng)控制的,而是由編程的人來控制的。在許多的應用中,堆內(nèi)存的使用都是必不可少的。必須通過指針,才可以使用堆內(nèi)存。堆內(nèi)存的分配與釋放:在程序運行過程中,遇到一個需要動態(tài)分配的變量或?qū)ο髸r,必須向系統(tǒng)申請取得堆內(nèi)存中的一塊所需大小的內(nèi)存空間,用于存放該變量或?qū)ο?。當不再使用該變量或?qū)ο髸r,必須結束它的生命期,需要顯式釋放其所占用的內(nèi)存空間。C++中,取得和釋放堆內(nèi)存中的空間,分別通過new和delete運算符來完成。new用來動態(tài)分配內(nèi)存空間,delete用來將動態(tài)分配得到的內(nèi)存空間歸還給系統(tǒng)(釋放)。21new與delete運算符new運算符━━動態(tài)申請堆空間

格式1:

指針變量=new類型名;

格式2:

指針變量=new類型名(初始值)

功能:動態(tài)創(chuàng)建一個指定類型的變量或?qū)ο?。若?chuàng)建成功(堆空間申請成功),new運算返回新分配堆空間的首地址;若創(chuàng)建失?。ǘ芽臻g申請失?。?,new運算返回0或NULL(空指針)。delete運算符━━動態(tài)釋放堆空間

格式:

delete指針;

功能:釋放由new運算動態(tài)創(chuàng)建的變量或?qū)ο?。指針的值必須是new運算所分配堆空間的首地址,即new運算的返回值。22new與delete運算符new運算符━━動態(tài)創(chuàng)建一維數(shù)組

格式:

指針變量=new類型名[下標表達式];

功能:動態(tài)創(chuàng)建一個指定類型的一維數(shù)組,數(shù)組元素的個數(shù)為下標表達式的值。若創(chuàng)建成功(堆空間申請成功),new運算返回新分配一維數(shù)組空間的首地址;若創(chuàng)建失?。ǘ芽臻g申請失?。?,new運算返回0或NULL(空指針)。

注意:動態(tài)為數(shù)組分配堆空間時,不能同時進行初始化。

delete運算符━━動態(tài)釋放一維數(shù)組

格式:

delete[]指針;

功能:釋放由new運算動態(tài)創(chuàng)建的一維數(shù)組。指針的值必須是new運算所分配一維數(shù)組空間的首地址,且前面必須加上一對方括號“[]”。

注意:若delete中的方括號“[]”不寫,只是釋放一維數(shù)組中一個元素的空間。23【例】(動態(tài)創(chuàng)建變量)#include<iostream.h>voidmain(){int*p=newint(100);cout<<*p<<endl;*p=200;cout<<*p<<endl;

deletep;

}【例】(動態(tài)創(chuàng)建一維數(shù)組)#include<iostream.h>voidmain(){int*p=newint[6];cout<<“請輸入六個整數(shù):\n”;for(inti=0;i<6;i++)cin>>p[i];for(i=0;i<6;i++)cout<<*(p+i)<<‘\t’;cout<<endl;

delete[]p;

}運行:請輸入六個整數(shù):563491↙563491pp[0]p[1]p[2]p[3]p[4]p[5]100p運行:10020024new與delete運算符new運算符━━動態(tài)創(chuàng)建二維數(shù)組

格式:

指針變量=new類型名[下標表達式1][下標表達式2];

功能:動態(tài)創(chuàng)建一個指定類型的二維數(shù)組,數(shù)組元素的個數(shù)為各維下標表達式值的乘積。若創(chuàng)建成功(堆空間申請成功),new運算返回新分配二維數(shù)組空間的首地址;若創(chuàng)建失?。ǘ芽臻g申請失?。?,new運算返回0或NULL(空指針)。注意:new運算創(chuàng)建二維數(shù)組時,必須將返回的地址賦給行指針變量;若要賦給元素指針變量,必須進行類型強制轉(zhuǎn)換。delete運算符━━動態(tài)釋放二維數(shù)組

格式:

delete[]指針;

功能:釋放由new運算動態(tài)創(chuàng)建的二維數(shù)組。指針的值必須是new運算所分配二維數(shù)組空間的首地址,且前面必須加上一對方括號“[]”。

注意:若delete中的方括號“[]”不寫,只是釋放二維數(shù)組中的一行元素的空間。25returnsum/(n*5);}if(p==0)exit(0);或if(p==NULL)exit(0);{float(*p1)[3]=newfloat[2][3];int(*f2)(int,int,float);{floaty,h;#include<iostream.{inta[6]={43,81,32,11,63,10};cout<<“請輸入六個整數(shù):”;*s1=‘1’;//正確{inti,j,t;注意:new運算創(chuàng)建二維數(shù)組時,必須將返回的地址賦給行指針變量;voidflip2(char*p,inti)//對p所指的字符串從第i個字符開始的字符串逆序輸出floataverage1(float*p,intn)//形參p為元素指針作用:指針作為函數(shù)參數(shù),可以使主調(diào)函數(shù)與被調(diào)函數(shù)之間共享變量或?qū)ο?,以實現(xiàn)函數(shù)之間數(shù)據(jù)的雙向傳遞。函數(shù)的指針:函數(shù)的代碼存儲在內(nèi)存中,其起始地址稱為函數(shù)的入口地址,其函數(shù)名代表該函數(shù)的入口地址,可以定義一個指向函數(shù)的指針變量來指向它,即將函數(shù)名賦給該指針變量,這樣就可以通過該指針變量來調(diào)用該函數(shù)。intb[6]={43,81,32,11,63,10};【例】(動態(tài)創(chuàng)建二維數(shù)組)#include<iostream.h>voidmain(){float(*p1)[3]=newfloat[2][3];inti,j;cout<<“請輸入六個整數(shù):”;for(i=0;i<2;i++)for(j=0;j<3;j++)cin>>p1[i][j];for(i=0;i<2;i++){for(j=0;j<3;j++)cout<<*(*(p1+i)+j)<<‘\t’;cout<<endl;}float*p2=

(float*)newfloat[2][3];

cout<<“請輸入六個整數(shù):”;for(i=0;i<6;i++)cin>>p2[i];for(i=0;i<6;i++){cout<<*(p2+i)<<‘\t’;if((i+1)%3==0)cout<<endl;}

delete[]p1;

delete[]p2;}運行:請輸入六個整數(shù):563491↙563491請輸入六個整數(shù):563491↙563491p1p1[0][0]p1[0][1]p1[0][2]p1[1][0]p1[1][1]p1[1][2]p1+1p2p2[0]p2[1]p2[2]p2[3]p2[4]p2[5]p2+126動態(tài)存儲分配的幾點說明動態(tài)分配失?。?/p>

動態(tài)分配是在堆內(nèi)存中進行,但堆區(qū)資源有限,動態(tài)分配可能失敗,這時new運算返回一個空指針(0或NULL),表示發(fā)生異常,堆區(qū)資源不足,分配失敗。指針刪除與堆空間釋放:

delete指針p;其實際含義是刪除指針p所指向的變量或?qū)ο?,即釋放p所指向的堆空間,而不是刪除指針p本身,釋放該堆空間后,指針p就成了空懸指針(即指針p未指向一個有效的地址,而空懸指針是程序錯誤的一個根源),此時最好將指針p置空(0或NULL)。動態(tài)數(shù)組的撤消:delete[]指針p;━━注意“[]”不可缺少,否則回收不徹底!

①若釋放由new創(chuàng)建的一維數(shù)組,而delete中又少了“[]”,由于指針p指向的是一維數(shù)組的首元素,是元素地址,此時只回收了首元素所占的堆空間。

②若釋放由new創(chuàng)建的二維數(shù)組,而delete中又少了“[]”,由于指針p指向的是二維數(shù)組的首行,是行地址,此時只回收了首行元素所占的堆空間。27動態(tài)存儲分配的幾點說明內(nèi)存泄漏與重復釋放:

①new和delete是配對使用的,若new返回的指針值丟失,其所分配的堆空間將無法回收,稱為內(nèi)存泄漏。程序執(zhí)行結束后,這部分空間將從系統(tǒng)中丟失,必須重新啟動計算機才能找回。

②對同一個堆空間重復釋放也是危險的,因為可能在第一次釋放后,該空間已經(jīng)分配給其它變量或?qū)ο螅俅吾尫艜剐碌淖兞炕驅(qū)ο髞G失。動態(tài)分配的變量或?qū)ο蟮纳嫫冢?/p>

①非動態(tài)分配的變量或?qū)ο?,在定義時都要用標識符命名,稱命名變量或?qū)ο?。auto局部的命名變量或?qū)ο笃渖嫫谠谧饔糜騼?nèi);全局和static局部的命名變量或?qū)ο笤诔绦蜻\行結束才被自動釋放。

②動態(tài)分配的變量或?qū)ο鬀]有名字,對其訪問只能通過指針來間接進行,稱無名變量或?qū)ο?。其生存期不依賴于建立它的作用域,例如在被調(diào)函數(shù)中動態(tài)分配的變量或?qū)ο?,只要不被delete釋放,在返回主調(diào)函數(shù)后仍可使用,但前提是其起始地址必須從被調(diào)函數(shù)中帶出,否則將無法訪問。28使用new和delete的幾點說明使用new動態(tài)分配的存儲空間,若不賦初值,其初值不確定。若new動態(tài)分配的空間較大,通常需要判斷其返回的指針值是否為0或NULL,若為0或NULL,表示動態(tài)分配失敗,此時應終止程序執(zhí)行或進行出錯處理。

【例】

int(*p)[200]=newint[100][200];

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論