c上海交大針對(duì)譚浩強(qiáng)的書_第1頁
c上海交大針對(duì)譚浩強(qiáng)的書_第2頁
c上海交大針對(duì)譚浩強(qiáng)的書_第3頁
c上海交大針對(duì)譚浩強(qiáng)的書_第4頁
c上海交大針對(duì)譚浩強(qiáng)的書_第5頁
已閱讀5頁,還剩51頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

會(huì)計(jì)學(xué)1c上海交大針對(duì)譚浩強(qiáng)的書2

主要內(nèi)容6.1指針的概念6.2變量與指針6.3數(shù)組與指針6.4字符串與指針6.5函數(shù)與指針6.6返回指針值的函數(shù)6.7指針數(shù)組和指向指針的指針6.8有關(guān)指針的數(shù)據(jù)類型和指針運(yùn)算的小結(jié)*6.9引用第1頁/共90頁36.1指針的概念張三李四101-104105-108張三、李四變量名住房號(hào)地址第2頁/共90頁4內(nèi)存用戶數(shù)據(jù)區(qū)3::6:20002004變量a變量b內(nèi)存地址為2000-2003的單元存放變量a的值為3內(nèi)存地址為2004-2007的單元存放變量b的值為6第3頁/共90頁5指針和指針變量3::6:20002004變量a變量b2000:3010point一個(gè)變量的地址稱為該變量的“指針”,地址2000是變量a的指針用來存放另一變量的地址(指針)的變量(如:point),稱為“指針變量”。指針變量的值(內(nèi)容)是指針(另一變量的地址)。第4頁/共90頁6指針的概念變量的指針變量的地址3a20002000point指針或變量的指針指針變量*Point是指針變量point指向的變量(*Point是a)若a=3即*Point=3其它變量是存放數(shù)據(jù)的,而指針變量是存放地址的.第5頁/共90頁7指針變量的定義inti,j;int*point_1,*point_2;ijpoint_1point_2Point_1=&iPoint_2=&j指針變量的值是變量i、j的地址說明格式:類型標(biāo)識(shí)符*標(biāo)識(shí)符例:int*i_pointer;float*f_pointer;&i&j第6頁/共90頁8聲明例:staticinti;staticint*i_pointer=&i;

指向整型變量的指針指針變量的概括概念指針:一個(gè)變量的地址引入指針目的:用于間接訪問變量指針變量:用于存放地址的變量,指向另一個(gè)變量20003i_pointer*i_pointeri2000引用例1:inti=3;int*i_pointer;例2:*i_pointer=3; i_pointer=&i;int*i_pointer;i_pointer=&i;第7頁/共90頁9

指針變量是一種特殊的變量,它和以前學(xué)過的其他類型的變量的不同之處是:用它來指向另一個(gè)變量。為了表示指針變量和它所指向的變量之間的聯(lián)系,在C++中用“*”符號(hào)表示指向,例如:i_pointer是一個(gè)指針變量,*i_pointer表示i_pointer所指向的變量,見圖6.3。下面兩個(gè)語句作用相同:①i=3;②*i_pointer=3;

圖6.36.2變量與指針第8頁/共90頁106.2.1定義指針變量語法形式

存儲(chǔ)類型數(shù)據(jù)類型*指針名=初始地址;例:int*pa=&a;(劃線部分都是數(shù)據(jù)類型的定義)注意事項(xiàng)用變量地址作為初值時(shí),該變量必須在指針初始化之前已說明過,且變量類型應(yīng)與指針類型一致??梢杂靡粋€(gè)已賦初值的指針去初始化另一個(gè)指針變量。不要用一個(gè)內(nèi)部auto型變量去初始化static型指針。第9頁/共90頁11指針變量指針名=地址float*pointer_3;//pointer_3是指向單精度型數(shù)據(jù)的指針變量char*pointer_4;//pointer_4是指向字符型數(shù)據(jù)的指針變量向指針變量賦的值必須是地址常量或變量,不能是普通整數(shù)。但可以賦值為整數(shù)0,表示空指針。指針的類型是它所指向變量的類型,而不是指針本身數(shù)據(jù)值的類型,任何一個(gè)指針本身的數(shù)據(jù)值都是unsignedlongint型。允許聲明指向void類型的指針。該指針可以被賦予任何類型對(duì)象的地址。例:void*general;注意:不能用一個(gè)整數(shù)給一個(gè)指針變量賦初值。inta=3;int*pointer=a;(int*pointer=&a;)?(2)

在定義變量時(shí)必須指定類型。定義void類型的變量?第10頁/共90頁12有兩個(gè)與指針變量有關(guān)的運(yùn)算符:(1)&取地址運(yùn)算符。(2)*指針運(yùn)算符(或稱間接訪問運(yùn)算符)。例如:&a為變量a的地址,*p為指針變量p所指向的存儲(chǔ)單元。6.2.2引用指針變量int*point1=&a;int*point1;point1=&a;*point1=a;*point1=3;&a3pointer*pointerainta=3;第11頁/共90頁13例6.1通過指針變量訪問整型變量。#include<iostream>usingnamespacestd;intmain(){inta,b;//定義整型變量a,bint*pointer_1,*pointer_2;//定義指針變量*pointer_1,*pointer_2a=100;b=10;//對(duì)a,b賦值pointer_1=&a;//把變量a的地址賦給pointer_1pointer_2=&b;//把變量a的地址賦給pointer_2cout<<a<<″″<<b<<endl;//輸出a和b的值cout<<*pointer_1<<″″<<*pointer_2<<endl;//輸出*pointer_1和*pointer_2的值return0;}運(yùn)行結(jié)果為:10010(a和b的值)10010(*pointer_1和*pointer_2的值)第12頁/共90頁14下面對(duì)“&”和“*”運(yùn)算符再做些說明:(1)如果“pointer_1=&a;”語句,“&”和“*”兩個(gè)運(yùn)算符的優(yōu)先級(jí)別相同,但按自右至左方向結(jié)合。*pointer_1的運(yùn)算,它就是變量a&*pointer_1與&a相同,即變量a的地址。如果有pointer_2=&*pointer_1;它的作用是將&a(a的地址)賦給pointer_2。第13頁/共90頁15#include<iostream>usingnamespacestd;voidswap(int*px,int*py){ inttemp=0; //px=&temp;//如果形參px改變指向,則*px就不能改變main函數(shù)的x的值

temp=*px;*px=*py;*py=temp;}intmain(){ intx=100,y=200; swap(&x,&y); cout<<x<<""<<y<<endl; return0; }11001101110010011100110111001001xy200100pypxMain函數(shù)swap函數(shù)傳遞y的地址傳遞x的地址第14頁/共90頁16例6.2輸入a和b兩個(gè)整數(shù),按先大后小的順序輸出a和b(用指針變量處理)。#include<iostream>usingnamespacestd;intmain(){int*p1,*p2,*p,a,b;cin>>a>>b;//輸入兩個(gè)整數(shù)p1=&a;//使p1指向ap2=&b;//使p2指向bif(a<b)//如果a<b就使p1與p2的值交換{p=p1;p1=p2;p2=p;}//將p1的指向與p2的指向交換cout<<″a=″<<a<<″b=″<<b<<endl;cout<<″max=″<<*p1<<″min=″<<*p2<<endl;return0; inttemp;}//運(yùn)行情況如下:

4578↙

if(a<b)a=45b=78{temp=*p1;*p1=*p2;*p2=temp;}

max=78min=45第15頁/共90頁17函數(shù)的參數(shù)不僅可以是整型、浮點(diǎn)型、字符型等數(shù)據(jù),還可以是指針類型。它的作用是將一個(gè)變量的地址傳送給被調(diào)用函數(shù)的形參。例6.3題目同例6.2,即對(duì)輸入的兩個(gè)整數(shù)按大小順序輸出。這里用函數(shù)處理,而且用指針類型的數(shù)據(jù)作函數(shù)參數(shù)。6.2.3指針作為函數(shù)參數(shù)第16頁/共90頁18#include<iostream>usingnamespacestd;intmain(){voidswap(int*p1,int*p2);//函數(shù)聲明int*pointer_1,*pointer_2,a,b;//定義指針變量pointer_1,pointer_2,整型變量a,bcin>>a>>b;pointer_1=&a;//使pointer_1指向apointer_2=&b;//使pointer_2指向bif(a<b)swap(pointer_1,pointer_2);//如果a<b,使*pointer_1和*pointer_2互換cout<<″max=″<<a<<″min=″<<b<<endl;//a已是大數(shù),b是小數(shù)return0;}voidswap(int*p1,int*p2)//函數(shù)的作用是將*p1的值與*p2的值交換{inttemp;temp=*p1;*p1=*p2;*p2=temp;}//運(yùn)行情況如下:

4578↙max=78min=45第17頁/共90頁19請(qǐng)注意:不要將main函數(shù)中的swap函數(shù)調(diào)用寫成if(a<b)swap(*pointer_1,*pointer_2);圖6.9第18頁/共90頁20voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}在main函數(shù)中用“swap(a,b);”調(diào)用swap函數(shù),會(huì)有什么結(jié)果呢?在函數(shù)調(diào)用時(shí),a的值傳送給x,b的值傳送給y,如圖6.10(a)所示。第19頁/共90頁21

在main函數(shù)中用“swap(a,b);”調(diào)用swap函數(shù),執(zhí)行完swap函數(shù)最后一個(gè)語句后,x和y的值是互換了,但main函數(shù)中的a和b并未互換.

由于虛實(shí)結(jié)合是采取單向的“值傳遞”方式,只能從實(shí)參向形參傳數(shù)據(jù),形參值的改變無法回傳給實(shí)參。為了使在函數(shù)中改變了的變量值能被main函數(shù)所用,而應(yīng)該用指針變量作為函數(shù)參數(shù)。在函數(shù)執(zhí)行過程中使指針變量所指向的變量值發(fā)生變化,函數(shù)調(diào)用結(jié)束后,這些變量值的變化依然保留下來,這樣就實(shí)現(xiàn)了“通過調(diào)用函數(shù)使變量的值發(fā)生變化,在主調(diào)函數(shù)中使這些值改變”的目的。voidswap(intx,inty){inttemp;temp=x;x=y;y=temp;}第20頁/共90頁22例6.4輸入a,b,c3個(gè)整數(shù),按由大到小的順序輸出。用上面介紹的方法,用3個(gè)指針變量指向3個(gè)整型變量,然后用swap函數(shù)來實(shí)現(xiàn)互換3個(gè)整型變量的值。程序如下:#include<iostream>usingnamespacestd;intmain(){voidexchange(int*,int*,int*);//對(duì)exchange函數(shù)的聲明inta,b,c,*p1,*p2,*p3;cin>>a>>b>>c;//輸入3個(gè)整數(shù)第21頁/共90頁23指向數(shù)組元素的指針的運(yùn)算比較靈活,務(wù)必小心謹(jǐn)慎。下面舉幾個(gè)例子:如果先使p指向數(shù)組a的首元素(即p=a),則:(1)p++;(或p+=1;p=p+1;)。使p指向下一元素,即a[1]。如果用*p,得到下一個(gè)元素a[1]的值。(2)*p++;由于++(后置)運(yùn)算符優(yōu)先級(jí)高于*優(yōu)先級(jí),結(jié)合方向?yàn)樽宰笾劣?,因此它等價(jià)于*(p++)。(3)*(p++)與*(++p)作用不同。前者是先取*p值,然后使p加1。后者是先使p加1,再取*p。若p的初值為a(即&a[0]),輸出*(p++)得到a[0]的值,而輸出*(++p)則得到a[1]的值。(4)(*p)++表示p所指向的元素值加1,即(a[0])++,如果a[0]=3,則(a[0])++的值為4。(5)如果p當(dāng)前指向a[i],則*(p--)先對(duì)p進(jìn)行“*”運(yùn)算,得到a[i],再使p減1,p指向a[i-1]*(--p)先使p自減1,再作*運(yùn)算,得到a[i-1]。第22頁/共90頁246.4指針和數(shù)組4.4.1指針和一維數(shù)組設(shè)有定義:

inta[6]={10,20,30,40,50,60},*p=a;

下面介紹引用數(shù)組元素的三種方式。

1.下標(biāo)方式 形式:數(shù)組名[下標(biāo)]

2.地址方式

形式:*(地址)

3.指針方式

形式:

*指針變量名假設(shè)有定義floata[10],*p=a;則如下的等價(jià)關(guān)系成立:(1)p<=>a<=>&a[0](2)p+i<=>&a[i](3)*(p+i)<=>*(a+i)<=>a[i]

指針可以作數(shù)組名用即:p[i]<=>a[i]第23頁/共90頁25設(shè)有:

p=a;for(i=0;i<10;i++) cin>>a[i];則等價(jià)于:p=a;for(i=0;i<10;i++) cin>>*p++;p=a;for(i=0;i<10;i++,p++) cin>>*p;p=a;for(i=0;i<10;i++) cin>>*(p+i);思考:第三種方法與其它二種區(qū)別何在?第24頁/共90頁26分析下列程序:#include<iostream.h>voidmain(){inta[10],i,*p;p=a;for(i=0;i<10;i++)cin>>*p++;;for(i=0;i<10;i++,p++)cout<<*p;}思考:數(shù)組元素能否正確輸出?第25頁/共90頁27注意:

p與a的區(qū)別p是地址變量,而a是地址常量。②*p++與

(*p)++區(qū)別*p++的++運(yùn)算符作用于指針變量

(*p)++的++運(yùn)算符作用于指針變量所指對(duì)象設(shè)有定義:

inta[6]={10,20,30,40,50,60},*p=a+2;p++、p--、p=p+2a++、a=a+2cout<<*p++;//輸出30cout<<*p;//輸出40cout<<(*p)++;//輸出30

cout<<*p;//輸出31第26頁/共90頁286.4.2指針和二維數(shù)組

數(shù)組名a可以解釋為指向int類型的二級(jí)指針常量;a可以看成是由兩個(gè)元素a[0]、a[1]構(gòu)成的一維數(shù)組,

a[0]可以看成是由a[0][0]、a[0][1]、a[0][2]3個(gè)整型變量組成的一維數(shù)組,可將a[0]解釋為指向int類型的一級(jí)指針常量;a[1]具有a[0]相同的性質(zhì)。設(shè)有定義:

inta[2][3];第27頁/共90頁29指針方式引用二維數(shù)組元素的兩種方式:1.指針變量引用數(shù)組元素

設(shè)有定義:

inta[2][3],*p=a[0];

通過p指針顯示二維數(shù)組的各元素:for(i=0;i<6;p++,i++){cout<<*p<<"";if(i%3==0)cout<<endl;}注意:二級(jí)指針地址不能賦值給一級(jí)指針變量:如:inta[2][3],*p=a;

第28頁/共90頁30#include<iostream>//預(yù)處理命令usingnamespacestd;intmain(){inta[2][3],*p=a[0];//int*p=a;?for(inti=0;i<2;i++) for(intj=0;j<3;j++)

cin>>a[i][j]; for(i=0;i<2;i++) for(intj=0;j<3;j++)//for(j=0;j<3;j++)j沒有定義

cout<<a[i][j]; cout<<endl; for(i=0;i<6;i++,p++) cout<<*p;

cout<<endl;return0;}第29頁/共90頁312.指針數(shù)組引用數(shù)組元素

指針數(shù)組的形式:數(shù)據(jù)類型*標(biāo)識(shí)符[整型常量表達(dá)式];即:數(shù)組中每個(gè)元素是指針。

設(shè)有定義:

inta[2][3],*p[2]={a[0],a[1]};要引用a[i][j]元素,可用指針數(shù)組表示如下:*(p[i]+j)

或*(*(p+i)+j)注意:指針數(shù)組名p與二維數(shù)組名a都是二級(jí)指針的概念,區(qū)別在于:a[i]是地址常量,p[i]是地址變量。第30頁/共90頁32例6.8輸出二維數(shù)組任一行任一列元素的值。#include<iostream>usingnamespacestd;intmain(){inta[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};int(*p)[4],i,j;cin>>i>>j;p=&a[0];cout<<*(*(p+i)+j)<<endl;return0;}運(yùn)行情況如下:

23↙23第31頁/共90頁336.4.3指針和字符串

可通過字符指針來訪問字符數(shù)組,二者的區(qū)別:字符數(shù)組字符指針定義chars[6];char*p;初始化chars[]=“china”;char*p=“china”;char*p=s;賦值s[0]=’c’;s[1]=’h’;

//逐個(gè)賦值

cin>>s;gets(s);p=“china”;

//指向字符串常量的首地址

p=newchar[6];或p=s;//應(yīng)使字符指針有確定指向后才能從鍵盤進(jìn)行輸入操作

cin>>p;或gets(s);運(yùn)算字符數(shù)組名s不能進(jìn)行自增或自減運(yùn)算

p是指針變量,可以進(jìn)行自增或自減運(yùn)算

第32頁/共90頁34【例6-(15)】輸入一串字符存儲(chǔ)在字符數(shù)組中,用指針方式逐一顯示字符,并求其長(zhǎng)度。#include"iostream.h"#include"stdio.h"voidmain(){chars[80],*p;gets(s);p=s;//p指向數(shù)組的第一個(gè)元素

cout<<"輸出每個(gè)字符:";while(*p!='\0') cout<<*p++<<"";//指針下移,直到p指向字符串結(jié)束符

cout<<"\n字符串長(zhǎng)度:"<<p-s<<endl;

}第33頁/共90頁35字符指針數(shù)組常用于處理若干字符串。設(shè)有定義:char*book[]={“Fortran”,”C/c++”,”Pascal”,”VisualBasic”};

按字符串的實(shí)際長(zhǎng)度存儲(chǔ),以’\0’表示每個(gè)字符串的結(jié)束。采用交換指針值的方法改變指針的指向。第34頁/共90頁36【例6-(16)】對(duì)4個(gè)字符串,按字典順序?qū)⑺鼈兣判蜉敵觥?include"iostream.h"#include"string.h"voidmain(){char*score[]={"Fortran","C/c++","Pascal","Basic"},*p;inti,j,k;for(i=0;i<3;i++) {k=i; for(j=i+1;j<4;j++) if(strcmp(score[k],score[j])>0)k=j; if(i!=k){p=score[i];score[i]=score[k];score[k]=p;} }for(i=0;i<4;i++) cout<<score[i]<<endl;}注意元素的比較程序:第35頁/共90頁376.5程序舉例插入數(shù)據(jù)基本思想:

1)首先要查找待插入數(shù)據(jù)在數(shù)組中的位置k;2)然后從最后一個(gè)元素開始往前直到下標(biāo)為k的元素依次往后移動(dòng)一個(gè)位置;3)第k個(gè)元素的位置空出,將欲插入的數(shù)據(jù)插入。【例4.17】在有序數(shù)組a中插入數(shù)值xfor(k=0;k<9;k++)if(x<a[k])break;//找到插入的位置下標(biāo)為kfor(i=8;i>=k;i--)a[i+1]=a[i];//從最后元素開始往后移,騰出位置

a[k]=x; 第36頁/共90頁382.刪除數(shù)據(jù)

刪除操作首先也是要找到欲刪除的元素的位置k;然后從k+1到n個(gè)位置開始向前移動(dòng);最后將數(shù)組元素減1。

【例4.18】從數(shù)組中刪除某數(shù)。for(i=0;i<10;i++)if(key==a[i])break;for(j=i;j<10;j++)a[j]=a[j+1];第37頁/共90頁393.二分法查找分析:二分法查找只適合于在已排好序的數(shù)組中進(jìn)行。設(shè)a[low]和a[high]是有序數(shù)組中最小和最大元素,待查找的數(shù)為x。算法描述如下:①開始假設(shè)待查區(qū)間的下界low為0,上界high為N-1。②求待查區(qū)間中間元素的下標(biāo)mid=(low+high)/2,x和a[mid]比較。③若x==a[mid],則查找完畢,結(jié)束程序;若x>a[mid],則繼續(xù)查找的范圍應(yīng)為a[mid]后面的元素,修改查找區(qū)間的下界low=mid+1;若x<a[mid],則繼續(xù)查找的范圍應(yīng)為a[mid]前面的元素,修改查找區(qū)間的上界high=mid-1;④重復(fù)第2、3步,直到找到x;或low>high無查找區(qū)域,找不到。第38頁/共90頁40其中,第3步可用如下程序段實(shí)現(xiàn):請(qǐng)編出完整的程序。if(x==a[mid])break;elseif(x>a[mid]) low=mid+1; else high=mid-1;第39頁/共90頁41p1=&a;p2=&b;p3=&c;//指向3個(gè)整型變量exchange(p1,p2,p3);//交換p1,p2,p3指向的3個(gè)整型變量的值cout<<a<<″″<<b<<″″<<c<<endl;//按由大到小的順序輸出3個(gè)整數(shù)}voidexchange(int*q1,int*q2,int*q3){voidswap(int*,int*);//對(duì)swap函數(shù)的聲明if(*q1<*q2)swap(q1,q2);//調(diào)用swap,將q1與q2所指向的變量的值互換if(*q1<*q3)swap(q1,q3);//調(diào)用swap,將q1與q3所指向的變量的值互換if(*q2<*q3)swap(q2,q3);//調(diào)用swap,將q2與q3所指向的變量的值互換}voidswap(int*pt1,int*pt2)//將pt1與pt2所指向的變量的值互換{inttemp;temp=*pt1;*pt1=*pt2;*pt2=temp;}運(yùn)行情況如下:

12-5687↙8712-56第40頁/共90頁42

一個(gè)變量有地址,一個(gè)數(shù)組包含若干元素,每個(gè)數(shù)組元素都在內(nèi)存中占用存儲(chǔ)單元,它們都有相應(yīng)的地址。指針變量既然可以指向變量,當(dāng)然也可以指向數(shù)組元素(把某一元素的地址放到一個(gè)指針變量中)。一般,數(shù)組的指針是指向數(shù)組的首地址的。

inta[10];//定義一個(gè)整型數(shù)組a,它有10個(gè)元素

int*p;//定義一個(gè)基類型為整型的指針變量pp=&a[0];//將元素a[0]的地址賦給指針變量p,使p指向a[0]在C++中,數(shù)組名代表數(shù)組中第一個(gè)元素(即序號(hào)為0的元素)的地址。6.3數(shù)組與指針

6.3.1指向數(shù)組元素的指針第41頁/共90頁43

下面兩個(gè)語句等價(jià):p=&a[0];p=a;

在定義指針變量時(shí)可以給它賦初值:

int*p=&a[0];//p的初值為a[0]的地址或int*p=a;//作用與前一行相同如果p的初值為&a[0],則:(1)p+i和a+i就是a[i]的地址,或者說,它們指向a數(shù)組的第i個(gè)元素。(2)*(p+i)或*(a+i)是p+i或a+i所指向的數(shù)組元素,即a[i]。

例:Inta[3];Int*p=a;//對(duì)于第i個(gè)元素:a[i]==p[i]==*(a+i)==*(p+i)(4種格式等價(jià))//第i個(gè)元素的地址:&a[i]==&p[i]==a+i==p+i(4種格式等價(jià))第42頁/共90頁44例6.5輸出數(shù)組中的全部元素。假設(shè)有一個(gè)整型數(shù)組a,有10個(gè)元素。要輸出各元素的值有3種方法:(1)下標(biāo)法#include<iostream>usingnamespacestd;intmain(){inta[10];inti;for(i=0;i<10;i++)cin>>a[i];//引用數(shù)組元素a[i]cout<<endl;for(i=0;i<10;i++)cout<<a[i]<<″″;//引用數(shù)組元素a[i]cout<<endl;return0;}第43頁/共90頁45運(yùn)行情況如下:9876543210↙(輸入10個(gè)元素的值)9876543210(輸出10個(gè)元素的值)(2)指針法將上面程序第7行和第10行的“a[i]”改為“*(a+i)”,運(yùn)行情況與(1)相同。(3)用指針變量指向數(shù)組元素#include<iostream>usingnamespacestd;intmain(){inta[10];inti,*p=a;//指針變量p指向數(shù)組a的首元素a[0]for(i=0;i<10;i++)cin>>*(p+i);//輸入a[0]~a[9]共10個(gè)元素cout<<endl;第44頁/共90頁46for(p=a;p<(a+10);p++)p<(p+10)?cout<<*p<<″″;//p先后指向a[0]~a[9]cout<<endl;return0;}運(yùn)行情況與前相同。請(qǐng)仔細(xì)分析p值的變化和*p的值。對(duì)3種方法的比較:方法(1)和(2)的執(zhí)行效率是相同的。第(3)種方法比方法(1)、(2)快。這種方法能提高執(zhí)行效率。用下標(biāo)法比較直觀,能直接知道是第幾個(gè)元素。用地址法或指針變量的方法都不太直觀,難以很快地判斷出當(dāng)前處理的是哪一個(gè)元素。第45頁/共90頁47在第5章5.4節(jié)中介紹過可以用數(shù)組名作函數(shù)的參數(shù)。前面已經(jīng)多次強(qiáng)調(diào):數(shù)組名代表數(shù)組首元素的地址。用數(shù)組名作函數(shù)的參數(shù),傳遞的是數(shù)組首元素的地址。很容易推想:用指針變量作函數(shù)形參,同樣可以接收從實(shí)參傳遞來的數(shù)組首元素的地址(此時(shí),實(shí)參是數(shù)組名)。下面用指針變量作函數(shù)形參。例6.6將10個(gè)整數(shù)按由小到大的順序排列。將形參改為指針變量。6.3.2用指針變量作函數(shù)參數(shù)接收數(shù)組地址第46頁/共90頁48#include<iostream>usingnamespacestd;intmain(){voidselect_sort(int*p,intn);//函數(shù)聲明inta[10],i;cout<<″e(cuò)ntertheoriginlarray:″<<endl;for(i=0;i<10;i++)//輸入10個(gè)數(shù)cin>>a[i];cout<<endl;select_sort(a,10);//函數(shù)調(diào)用,數(shù)組名作實(shí)參cout<<″thesortedarray:″<<endl;for(i=0;i<10;i++)//輸出10個(gè)已排好序的數(shù)cout<<a[i]<<″″;cout<<endl;return0;}voidselect_sort(int*p,intn)//用指針變量作形參{inti,j,k,t;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++)if(*(p+j)<*(p+k))k=j;//用指針法訪問數(shù)組元素

t=*(p+k);*(p+k)=*(p+i);*(p+i)=t;}}k=i;ija0a1a2a3…↑↑第47頁/共90頁49

實(shí)參與形參的結(jié)合,有以下4種形式:實(shí)參 形參數(shù)組名 數(shù)組名 數(shù)組名 指針變量指針變量 數(shù)組名指針變量 指針變量實(shí)參數(shù)組名a代表一個(gè)固定的地址,或者說是指針型常量,因此要改變a的值是不可能的。 如:a++;//語法錯(cuò)誤,a是常量,不能改變形參數(shù)組名是指針變量,并不是一個(gè)固定的地址值。它的值是可以改變的。在函數(shù)調(diào)用開始時(shí),它接收了實(shí)參數(shù)組首元素的地址,但在函數(shù)執(zhí)行期間,它可以再被賦值。第48頁/共90頁50用指針變量可以指向一維數(shù)組中的元素,也可以指向多維數(shù)組中的元素。1.多維數(shù)組元素的地址設(shè)有一個(gè)二維數(shù)組a,它有3行4列。它的定義為inta[3][4]={{1,3,5,7},{9,11,13,15},{17,18,21,23}};a是一個(gè)數(shù)組名。a數(shù)組包含3行,即3個(gè)元素:a[0],a[1],a[2]。而每一元素又是一個(gè)一維數(shù)組,它包含4個(gè)元素(即4個(gè)列元素),例如,a[0]所代表的一維數(shù)組又包含4個(gè)元素:a[0][0],a[0][1],a[0][2],a[0][3],見圖6.14??梢哉J(rèn)為二維數(shù)組是“數(shù)組的數(shù)組”,即數(shù)組a是由3個(gè)一維數(shù)組所組成的。6.3.3多維數(shù)組與指針第49頁/共90頁51圖6.14

從二維數(shù)組的角度來看,a代表二維數(shù)組首元素的地址,a[0]現(xiàn)在不是一個(gè)整型變量,而是由4個(gè)整型元素所組成的一維數(shù)組,因此a代表的是首行的起始地址(即第0行的起始地址,&a[0]),a+1代表a[1]行的首地址,即&a[1]。

a[0],a[1],a[2]既然是一維數(shù)組名,因此a[0]代表一維數(shù)組a[0]中0列元素的地址,即&a[0][0]。a[1]的值是&a[1][0],a[2]的值是&a[2][0]。第50頁/共90頁52用字符指針指向一個(gè)字符串例6.12定義一個(gè)字符指針變量并初始化,然后輸出它指向的字符串。#include<iostream>usingnamespacestd;intmain(){char*str=″IloveCHINA!″;cout<<str<<endl;return0;}對(duì)字符串中字符的存取,可以用字符數(shù)組名,也可以用指針,或字符串變量的方面存取。6.6字符串與指針第51頁/共90頁53例6.13將字符串str1復(fù)制為字符串str2//例6.13將字符串str1復(fù)制為字符串str2。#include<iostream>usingnamespacestd;intmain(){charstr1[]="IloveCHINA!",str2[20],*p1,*p2;p1=str1;p2=str2;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';p1=str1;p2=str2;cout<<"str1is:"<<p1<<endl;cout<<"str2is:"<<p2<<endl;return0;}p1=&str1;p2=&str2;?第52頁/共90頁54

在C語言中是利用庫(kù)函數(shù)malloc和free來分配和撤銷內(nèi)存空間的。C++提供了較簡(jiǎn)便而功能較強(qiáng)的運(yùn)算符new和delete來取代malloc和free函數(shù)。注意:new和delete是運(yùn)算符,不是函數(shù),因此執(zhí)行效率更高。*7.1.7動(dòng)態(tài)分配和撤銷內(nèi)存的運(yùn)算符new和delete第53頁/共90頁55運(yùn)算符new和deletenew運(yùn)算符

C++用new運(yùn)算符來動(dòng)態(tài)創(chuàng)建對(duì)象,其語法形式為:

new類型名(初值列表); 該語句的功能是在程序運(yùn)行過程中申請(qǐng)用于存放指定類型的內(nèi)存空間,并用初值列表中給出的值進(jìn)行初始化。如果創(chuàng)建的對(duì)象是數(shù)組類型,則應(yīng)按照數(shù)組的結(jié)構(gòu)來創(chuàng)建,其語法形式為:一維數(shù)組:new類型名[下標(biāo)];

當(dāng)數(shù)組為一維數(shù)組時(shí),下標(biāo)為數(shù)組元素的個(gè)數(shù),動(dòng)態(tài)分配內(nèi)存時(shí)不能指定數(shù)組元素的初值,如果內(nèi)存申請(qǐng)成功,返回一個(gè)指向新分配內(nèi)存的首地址的指定類型的指針,如果失敗,返回0。多維數(shù)組:new類型名[下標(biāo)1][下標(biāo)2];

當(dāng)數(shù)組為多維數(shù)組時(shí),返回一個(gè)指向新分配內(nèi)存的首地址的指針,但該指針的類型為指定數(shù)組的類型。delete運(yùn)算符 運(yùn)算符delete的功能是刪除由new運(yùn)算符創(chuàng)建的對(duì)象,釋放指針指向的內(nèi)存空間,其語法形式為:delete指針名;如果new運(yùn)算符創(chuàng)建的對(duì)象是數(shù)組,則刪除對(duì)象時(shí)應(yīng)使用的語法形式為:

delete[]指針名;第54頁/共90頁56例子:

newint;//開辟一個(gè)存放整數(shù)的存儲(chǔ)空間,返回一個(gè)指向該存儲(chǔ)空間的地址(即指針)newint(100);//開辟一個(gè)存放整數(shù)的空間,并指定該整數(shù)的初值為100,返回一個(gè)指向該存儲(chǔ)空間的地址

newchar[10];//開辟一個(gè)存放字符數(shù)組(包括10個(gè)元素)的空間,返回首元素的地址

newint[5][4];//開辟一個(gè)存放二維整型數(shù)組(大小為5*4)的空間,返回首元素的地址

float*p=newfloat(3.14159);//開辟一個(gè)存放單精度數(shù)的空間,并指定該實(shí)數(shù)的初值為3.14159,將返回的該空間的地址賦給指針變量pdeletep;//要撤銷上面用new開辟的存放單精度數(shù)的空間

char*pt=newchar[10];delete[]pt;//在指針變量前面加一對(duì)方括號(hào),表示是對(duì)數(shù)組空間的撤銷操作第55頁/共90頁57

指針變量也可以指向一個(gè)函數(shù)。一個(gè)函數(shù)在編譯時(shí)被分配給一個(gè)入口地址。這個(gè)函數(shù)入口地址就稱為函數(shù)的指針??梢杂靡粋€(gè)指針變量指向函數(shù),然后通過該指針變量調(diào)用此函數(shù)。例6.14求a和b中的大者。6.7函數(shù)與指針

6.7.1用函數(shù)指針變量調(diào)用函數(shù)第56頁/共90頁58#include<iostream>usingnamespacestd;intmain(){intmax(intx,inty);//函數(shù)聲明inta,b,m;cin>>a>>b;m=max(a,b);//調(diào)用函數(shù)max,求出最大值,賦給mcout<<″max=″<<m<<endl;return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}第57頁/共90頁59intmax(intx,inty);可以用一個(gè)指針變量指向max函數(shù),然后通過該指針變量調(diào)用此函數(shù)。定義指向max函數(shù)的指針變量的方法是:int(*p)(int,int);

p所指向的函數(shù)的形參類型

p是指向函數(shù)的指針變量指針變量p指向的函數(shù)的類型請(qǐng)將它和函數(shù)max的原型作比較intmax(int,int);//max函數(shù)原型可以看出:只是用(*p)取代了max,其他都一樣。程序如下:第58頁/共90頁60#include<iostream>usingnamespacestd;intmain(){intmax(intx,inty);//函數(shù)聲明int(*p)(int,int);//定義指向函數(shù)的指針變量pinta,b,m;p=max;//使p指向函數(shù)maxcin>>a>>b;m=p(a,b);cout<<″max=″<<m<<endl;return0;}

請(qǐng)注意第7行的賦值語句“p=max;”。此語句千萬不要漏寫,它的作用是將函數(shù)max的入口地址賦給指針變量p。這時(shí),p才指向函數(shù)max。指向函數(shù)的指針變量的一般定義形式為:函數(shù)類型(*指針變量名)(函數(shù)形參表)第59頁/共90頁61一個(gè)函數(shù)可以帶回一個(gè)整型值、字符值、實(shí)型值等,也可以帶回指針型的數(shù)據(jù),即地址。其概念與以前類似,只是帶回的值的類型是指針類型而已。返回指針值的函數(shù)簡(jiǎn)稱為指針函數(shù)。定義指針函數(shù)的一般形式為類型名*函數(shù)名(參數(shù)表列);例如int*a(intx,inty);6.8返回指針值的函數(shù)第60頁/共90頁62如果一個(gè)數(shù)組,其元素均為指針類型數(shù)據(jù),該數(shù)組稱為指針數(shù)組,也就是說,指針數(shù)組中的每一個(gè)元素相當(dāng)于一個(gè)指針變量,它的值都是地址。一維指針數(shù)組的定義形式為類型名*數(shù)組名[數(shù)組長(zhǎng)度];例如int*p[4];可以用指針數(shù)組中各個(gè)元素分別指向若干個(gè)字符串,使字符串處理更加方便靈活。6.7指針數(shù)組和指向指針的指針

6.7.1指針數(shù)組的概念第61頁/共90頁63例6.15若干字符串按字母順序(由小到大)輸出。#include<iostream>usingnamespacestd;intmain(){voidsort(char*name[],intn);//聲明函數(shù)voidprint(char*name[],intn);//聲明函數(shù)char*name[]={″BASIC″,″FORTRAN″,″C++″,″Pascal″,″COBOL″};//定義指針數(shù)組intn=5;sort(name,n);print(name,n);return0;}voidsort(char*name[],intn){char*temp;inti,j,k;for(i=0;i<n-1;i++){k=i;第62頁/共90頁64for(j=i+1;j<n;j++)if(strcmp(name[k],name[j])>0)k=j;if(k!=i){temp=name[i];name[i]=name[k];name[k]=temp;}}}voidprint(char*name[],intn){inti;for(i=0;i<n;i++)cout<<name[i]<<endl;}運(yùn)行結(jié)果為BASICCOBOLC++FORTRANPascal第63頁/共90頁65圖6.21圖6.22第64頁/共90頁66

下面介紹指向指針的指針。怎樣定義一個(gè)指向指針數(shù)據(jù)的指針變量呢?如下:char*(*p);從附錄B可以知道,*運(yùn)算符的結(jié)合性是從右到左,因此“char*(*p);”可寫成:char**p;6.7.2指向指針的指針第65頁/共90頁67例6.16指向字符型數(shù)據(jù)的指針變量。#include<iostream>usingnamespacestd;intmain(){char**p;//定義指向字符指針數(shù)據(jù)的指針變量pchar*name[]={″BASIC″,″FORTRAN″,″C++″,″Pascal″,″COBOL″};p=name+2;//見圖6.23中p的指向cout<<*p<<endl;//輸出name[2]指向的字符串cout<<**p<<endl;//輸出name[2]指向的字符串中的第一個(gè)字符}運(yùn)行結(jié)果為C++C指針數(shù)組的元素也可以不指向字符串,而指向整型數(shù)據(jù)或單精度型數(shù)據(jù)等。第66頁/共90頁686.9有關(guān)指針的數(shù)據(jù)類型和指針運(yùn)算的小結(jié)

6.9.1有關(guān)指針的數(shù)據(jù)類型的小結(jié)定義含義inti;定義整型變量int*p;p為指向整型數(shù)據(jù)的指針變量inta[n];定義整型數(shù)組a,它有n個(gè)元素int*p[n];定義指針數(shù)組p,它由n個(gè)指向整型數(shù)據(jù)的指針元素組成int(*p)[n];p為指向含n個(gè)元素的一維數(shù)組的指針變量intf();f為帶回整型函數(shù)值的函數(shù)int*p();p為帶回一個(gè)指針的函數(shù),該指針指向整型數(shù)據(jù)int(*p)();p為指向函數(shù)的指針,該函數(shù)返回一個(gè)整型值int**p;p是一個(gè)指向指針的指針變量,它指向一個(gè)指向整型數(shù)據(jù)的指針變量第67頁/共90頁69前面已用過一些指針運(yùn)算(如p++,p+i等),現(xiàn)在把全部的指針運(yùn)算列出如下。(1)指針變量加/減一個(gè)整數(shù)例如:p++,p--,p+i,p-i,p+-i,p-=i等。C++規(guī)定,一個(gè)指針變量加/減一個(gè)整數(shù)是將該指針變量的原值(是一個(gè)地址)和它指向的變量所占用的內(nèi)存單元字節(jié)數(shù)相加或相減。如p+i代表這樣的地址計(jì)算:p+i*d,d為p所指向的變量單元所占用的字節(jié)數(shù)。這樣才能保證p+i指向p下面的第i個(gè)元素。(2)指針變量賦值將一個(gè)變量地址賦給一個(gè)指針變量。如6.8.2指針運(yùn)算小結(jié)第68頁/共90頁70p=&a;//將變量a的地址賦給pp=array;//將數(shù)組array首元素的地址賦給pp=&array[i];//將數(shù)組array第i個(gè)元素的地址賦給pp=max;//max為已定義的函數(shù),將max的入口地址賦給pp1=p2;//p1和p2都是同類型的指針變量,將p2的值賦給p1(3)指針變量可以有空值,即該指針變量不指向任何變量,可以這樣表示:p=NULL;實(shí)際上NULL代表整數(shù)0,也就是使p指向地址為0的單元。這樣可以使指針不指向任何有效的單元。實(shí)際上系統(tǒng)已先定義了NULL:#defineNULL0在iostream頭文件中就包括了以上的NULL定義,NULL是一個(gè)符號(hào)常量。應(yīng)注意,p的值等于NULL和p未被賦值是兩個(gè)不同的概念。第69頁/共90頁71任何指針變量或地址都可以與NULL作相等或不相等的比較,如if(p==NULL)p=p1;(4)兩個(gè)指針變量可以相減如果兩個(gè)指針變量指向同一個(gè)數(shù)組的元素,則兩個(gè)指針變量值之差是兩個(gè)指針之間的元素個(gè)數(shù),見圖6.25。假如p1指向a[1],p2指向a[4],則p2-p1=(a+4)-(a+1)=4-1=3。但p1+p2并無實(shí)際意義。第70頁/共90頁72(5)兩個(gè)指針變量比較若兩個(gè)指針指向同一個(gè)數(shù)組的元素,則可以進(jìn)行比較。指向前面的元素的指針變量小于指向后面元素的指針變量。如圖6.25中,p1<p2,或者說,表達(dá)式“p1<p2”的值為真,而“p2<p1”的值為假。注意,如果p1和p2不指向同一數(shù)組則比較無意義。圖6.25第71頁/共90頁73(6)對(duì)指針變量的賦值應(yīng)注意類型問題。在本章前幾節(jié)中介紹了指針的基本概念和初步應(yīng)用。應(yīng)該說明,指針是C和C++中重要的概念,是C和C++的一個(gè)特色。使用指針的優(yōu)點(diǎn)是:①提高程序效率;②在調(diào)用函數(shù)時(shí),如果改變被調(diào)用函數(shù)中某些變量的值,這些值能為主調(diào)函數(shù)使用,即可以通過函數(shù)的調(diào)用,得到多個(gè)可改變的值;③可以實(shí)現(xiàn)動(dòng)態(tài)存儲(chǔ)分配。但是同時(shí)應(yīng)該看到,指針使用實(shí)在太靈活,對(duì)熟練的程序人員來說,可以利用它編寫出頗有特色的、質(zhì)量?jī)?yōu)良的程序,實(shí)現(xiàn)許多用其他高級(jí)語言難以實(shí)現(xiàn)的功能,但也十分容易出錯(cuò),而且這種錯(cuò)誤往往難以發(fā)現(xiàn)。第72頁/共90頁74

對(duì)一個(gè)數(shù)據(jù)可以使用“引用”(reference),這是C++對(duì)C的一個(gè)重要擴(kuò)充,引用是一種新的變量類型,它的作用是為一個(gè)變量起一個(gè)別名。假如有一個(gè)變量a,想給它起一個(gè)別名b,可以這樣寫:inta;//定義a是整型變量int&b=a;//聲明b是a的引用以上語句聲明了b是a的引用,即b是a的別名。經(jīng)過這樣的聲明后,a或b的作用相同,都代表同一變量。*6.10引用

6.10.1什么是變量的引用第73頁/共90頁75注意:在上述聲明中,&是引用聲明符,并不代表地址。不要理解為“把a(bǔ)的值賦給b的地址”。聲明變量b為引用類型,并不需要另外開辟內(nèi)存單元來存放b的值。b和a占內(nèi)存中的同一個(gè)存儲(chǔ)單元,它們具有同一地址。聲明b是a的引用,可以理解為:使變量b具有變量a的地址。見圖6.26,如果a的值是20,則b的值也是20。在聲明一個(gè)引用類型變量時(shí),必須同時(shí)使之初始化,即聲明它代表哪一個(gè)變量。圖6.26第74頁/共90頁76例6.17引用和變量的關(guān)系。#include<iostream>#include<iomanip>usingnamespacestd;intmain(){inta=10;int&b=a;//聲明b是a的引用a=a*a;//a的值變化了,b的值也應(yīng)一起變化cout<<a<<setw(6)<<b<<endl;b=b/5;//b的值變化了,a的值也應(yīng)一起變化cout<<b<<setw(6)<<a<<endl;return0;}運(yùn)行記錄如下:

100 100(a和b的值都是100)20 20(a和b的值都是20)6.10.2引用的簡(jiǎn)單使用第75頁/共90頁77有了變量名,為什么還需要一個(gè)別名呢?C++之所以增加引用類型,主要是把它作為函數(shù)參數(shù),以擴(kuò)充函數(shù)傳遞數(shù)據(jù)的功能。到目前為止,介紹過函數(shù)參數(shù)傳遞的兩種情況。(1)將變量名作為實(shí)參和形參。這時(shí)傳給形參的是變量的值,傳遞是單向的。如果在執(zhí)行函數(shù)期間形參的值發(fā)生變化,并不傳回給實(shí)參。因?yàn)樵谡{(diào)用函數(shù)時(shí),形參和實(shí)參不是同一個(gè)存儲(chǔ)單元。(2)傳遞變量的指針。形參是指針變量,實(shí)參是一個(gè)變量的地址,調(diào)用函數(shù)時(shí),形參(指針變量)指向?qū)崊⒆兞繂卧?.10.3引用作為函數(shù)參數(shù)第76頁/共90頁78引用作為函數(shù)參數(shù)C++提供了向函數(shù)傳遞數(shù)據(jù)的第(3)種方法,即傳送變量的別名。例6.20利用“引用形參”實(shí)現(xiàn)兩個(gè)變量的值互換。#include<iostream.h>voidSwap(int&a,int&b);intmain(){ inti(3),j(5); cout<<“i="<<i<<"j="<<j<<endl; Swap(i,j); cout<<“i="<<i<<"j="<<j<endl; return0;}第77頁/共90頁79voidSwap(int&a,int&b){ intt; t=a; a=b; b=t;}輸出結(jié)果為i=5j=3①使用引用類型就不必在swap函數(shù)中聲明形參是指針變量。指針變量要另外開辟內(nèi)存單元,其內(nèi)容是地址。而引用變量不是一個(gè)獨(dú)立的變量,不單獨(dú)占內(nèi)存單元②在main函數(shù)中調(diào)用swap函數(shù)時(shí),實(shí)參不必用變量的地址(在變量名的前面加&),而直接用變量名。系統(tǒng)向形參傳送的是實(shí)參的地址而不是實(shí)參的值。顯然,這種用法比使用指針變量簡(jiǎn)單、直觀、方便。使用變量的引用,可以部分代替指針的操作。第78頁/共90頁80例6.21對(duì)3個(gè)變量按由小到大的順序排序。#include<iostream>usingnamespacestd;intmain(){voidsort(int&,int&,int&);//函數(shù)聲明,形參是引用類型inta,b,c;//a,b,c是需排序的變量inta1,b1,c1;//a1,b1,c1最終的值是已排好序的數(shù)列cout<<″Pleaseenter3integers:″;cin>>a>>b>>c;//輸入a,b,ca1=a;b1=b;c1=c;sort(a1,b1,c1);//調(diào)用sort函數(shù),以a1,b1,c1為實(shí)參cout<<″sortedorderis″<<a1<<″″<<b1<<″″<<c1<<endl;//此時(shí)a1,b1,c1已排好序return0;}voidsort(int&i,int&j,int&k)//對(duì)i,j,k3個(gè)數(shù)排序{voidchange(int&,int&);//函數(shù)聲明,形參是引用類型if(i>j)change(i,j);//使i<=j第79頁/共90頁

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(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)論