![C++大學(xué)基礎(chǔ)教程第六章_第1頁](http://file4.renrendoc.com/view/148897bd1b2b50e372a54e73c837f0fd/148897bd1b2b50e372a54e73c837f0fd1.gif)
![C++大學(xué)基礎(chǔ)教程第六章_第2頁](http://file4.renrendoc.com/view/148897bd1b2b50e372a54e73c837f0fd/148897bd1b2b50e372a54e73c837f0fd2.gif)
![C++大學(xué)基礎(chǔ)教程第六章_第3頁](http://file4.renrendoc.com/view/148897bd1b2b50e372a54e73c837f0fd/148897bd1b2b50e372a54e73c837f0fd3.gif)
![C++大學(xué)基礎(chǔ)教程第六章_第4頁](http://file4.renrendoc.com/view/148897bd1b2b50e372a54e73c837f0fd/148897bd1b2b50e372a54e73c837f0fd4.gif)
![C++大學(xué)基礎(chǔ)教程第六章_第5頁](http://file4.renrendoc.com/view/148897bd1b2b50e372a54e73c837f0fd/148897bd1b2b50e372a54e73c837f0fd5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
C++大學(xué)基礎(chǔ)教程第6章指針和引用
北京科技大學(xué)計算機系2022/10/181北京科技大學(xué)計算機系第六章指針和引用6.1指針的概念6.2指針的運算6.3指針和函數(shù)6.4指針和字符串6.5通過指針訪問數(shù)組6.6指針訪問動態(tài)內(nèi)存6.7引用概念2022/10/182北京科技大學(xué)計算機系關(guān)于內(nèi)存地址內(nèi)存空間的訪問方式通過變量名訪問通過地址訪問地址運算符:&例:intvar;則&var表示變量var在內(nèi)存中的起始地址2022/10/183北京科技大學(xué)計算機系聲明例:staticinti;staticint*i_pointer=&i;
指向整型變量的指針指針變量的概念概念指針:地址
用于間接訪問變量指針變量:
用于存放地址的變量目標(biāo)變量:
20003i_pointer*i_pointeri2000內(nèi)存用戶數(shù)據(jù)區(qū)變量i變量j變量
i_pointer362000200020043010引用例1:i=3;例2:*i_pointer=3;指針2022/10/184北京科技大學(xué)計算機系小結(jié)幾個概念:指針,指針變量,目標(biāo)變量符號*:在定義中表示變量為指針變量運算符:&:取地址運算符*:指向運算符2022/10/185北京科技大學(xué)計算機系指針變量的定義和初始化語法形式
[存儲類型]
數(shù)據(jù)類型*指針名=初始地址;例:inta;int*pa=&a;注意事項用變量地址作為初值時,該變量必須在指針初始化之前已說明過,且變量類型應(yīng)與指針類型一致??梢杂靡粋€已賦初值的指針去初始化另一個指針變量。charch1=’Y’,ch2=’A’;char*pch1=&ch1,*pch2=&ch2;2022/10/186北京科技大學(xué)計算機系
例1指針的概念main(){inta;int*pa=&a;a=10;cout<<"a:"<<a<<endl;cout<<"*pa"<<*pa<<endl; cout<<"&a:(Hex)"<<HEX<<&a<<endl; cout<<"pa:(HEX)"<<HEX<<pa<<endl; cout<<"&pa:(HEX)"<<HEX<<&pa<<endl;}
a:10*pa:10&a:bb4(HEX)pa:bb4(HEX)&pa:bb2(HEX)2022/10/187北京科技大學(xué)計算機系6.2指針的運算
2022/10/188北京科技大學(xué)計算機系6.2指針的運算表6.1指針的運算2022/10/189北京科技大學(xué)計算機系6.2.1指針的賦值運算
指針=地址指針的賦值運算一定是地址的賦值。用來對指針變量賦值的可以是:同類型變量的地址;同類型的已經(jīng)初始化的指針變量;其他同類型的指針?!暗刂贰敝写娣诺臄?shù)據(jù)類型與指針類型必須相符。注意:不同類型的指針是不可以互相賦值的。在指針賦值時,不存在類型自動轉(zhuǎn)換的機制。向指針變量賦的值必須是地址常量或變量,不能是普通整數(shù)。但可以賦值為整數(shù)0,表示空指針。此外,也可以用0或者NULL對指針變量賦值。使得變量包含的是“空指針”,即不指向任何的內(nèi)存物理地址。2022/10/1810北京科技大學(xué)計算機系
例6.1觀察以下指針賦值運算的結(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;
//pvf1=pva1;}valueofpva2is0x000000000x0012FF7C0x0012FF7C0x0012FF740x0012FF74注釋去掉會出現(xiàn)編譯錯誤2022/10/1811北京科技大學(xué)計算機系例指針的定義、賦值與使用#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)容}2022/10/1812北京科技大學(xué)計算機系6.2.2間接引用運算
間接引用運算符“*”是一種一元算符,它和指針變量連用,對指針?biāo)赶虻膬?nèi)存地址單元進(jìn)行間接訪問。使用的格式是:
*指針變量如果指針變量iptr指向整型變量va,*iptr就是變量va的內(nèi)容2022/10/1813北京科技大學(xué)計算機系
例6.2對變量的直接訪問和間接訪問:寫出以下程序運行結(jié)果。#include<iostream>usingnamespacestd;voidmain(){charch1='a',*ch;intk1=100;ch=&ch1; //指針ch指向變量ch1cout<<"*ch="<<*ch<<endl; //間接訪問*ch='B';cout<<"ch1="<<ch1<<endl; //直接訪問
ch1=k1;cout<<"*ch="<<*ch<<endl; //間接訪問
}運行結(jié)果:*ch=ach1=B*ch=d2022/10/1814北京科技大學(xué)計算機系
例6.3定義指向指針的指針變量。觀察對這種指針變量間接訪問的結(jié)果。#include<iostream>usingnamespacestd;voidmain(){intva=100,*pva,**ppva;//ppva是指向指針的指針
intk1=100;pva=&va;cout<<"*pva="<<*pva<<endl; //間接訪問結(jié)果是整型數(shù)
ppva=&pva;cout<<"*ppva="<<*ppva<<endl;//間接訪問結(jié)果是地址
cout<<"pva="<<pva<<endl; //就是指針pva的內(nèi)容}運行結(jié)果:*pva=100*ppva=0x0012FF7Cpva=0x0012FF7C
2022/10/1815北京科技大學(xué)計算機系6.2.2間接引用運算2022/10/1816北京科技大學(xué)計算機系6.2.3指針的算術(shù)運算
指針可以進(jìn)行的算術(shù)運算只有加法和減法。指針可以和一個整數(shù)n做加法或者減法運算。指針p和整數(shù)n相加(相減)的含義是指向當(dāng)前指向位置p的前方或后方第n個數(shù)據(jù)的地址。2022/10/1817北京科技大學(xué)計算機系
例6.4通過指針的間接訪問,輸出下標(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;}
運行結(jié)果:K1[0]=11k1[2]=37….
數(shù)組第一個元素(下標(biāo)為0)的地址賦值給指針k
每次循環(huán),指針加22022/10/1818北京科技大學(xué)計算機系6.2.3指針的算術(shù)運算指針和指針的直接加法是沒有意義的,也是不允許的。指針和指針的減法是可以進(jìn)行的,其意義是求出兩個指針之間可以存放幾個指定類型的數(shù)據(jù)。不允許用一個整數(shù)減一個指針。2022/10/1819北京科技大學(xué)計算機系6.2.4指針的關(guān)系運算和邏輯運算
相同類型的指針可以進(jìn)行各種關(guān)系運算。比較兩個指針相等還是不相等。進(jìn)行指針“大于”、“小于”的比較,只是要判定指針在內(nèi)存中的相對位置。指向不同數(shù)據(jù)類型的指針,指針和一般的整數(shù)比較是沒有意義的,也是不允許的。惟一可以和指針比較的整數(shù)是0。通過指針和0的比較來判定指針本身是不是空指針。即指針可以和零之間進(jìn)行等于或不等于的關(guān)系運算。例如:p==0或p!=02022/10/1820北京科技大學(xué)計算機系6.2.5void類型指針
void類型的指針就是“無類型”指針。聲明的方式如下: void*<指針名>;void類型的指針變量中存放的也是內(nèi)存的地址,但是不指定這個地址單元內(nèi)的數(shù)據(jù)的類型。2022/10/1821北京科技大學(xué)計算機系6.2.5void類型指針
void類型的指針的使用:任何其他類型的指針都可以賦值給void指針。必須注意,這樣賦值后的void指針的類型仍然是void。void類型指針不可以直接賦值給任何其他類型的指針。無論何時,void指針都不可以通過間接引用來訪問內(nèi)存中的數(shù)據(jù)。要通過void類型指針訪問內(nèi)存的數(shù)據(jù),必須進(jìn)行指針類型的強制轉(zhuǎn)換,才可以通過指針間接引用訪問內(nèi)存數(shù)據(jù)。2022/10/1822北京科技大學(xué)計算機系
例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;}
運行結(jié)果:012345678123
復(fù)制字符數(shù)據(jù),10個字節(jié)復(fù)制整型數(shù)據(jù),12個字節(jié)2022/10/1823北京科技大學(xué)計算機系6.2.5void類型指針
void類型指針還有一個具體的應(yīng)用:顯示字符指針的內(nèi)容。除了字符指針外,其他指針都可以直接用cout語句來輸出地址值。但是,用cout輸出字符指針時,則是輸出它所指向的字符串??梢詫⒆址羔槒娭妻D(zhuǎn)換為void指針,再用cout語句輸出,就可以看到地址值。如: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;2022/10/1824北京科技大學(xué)計算機系6.3指針和函數(shù)
2022/10/1825北京科技大學(xué)計算機系6.3指針和函數(shù)在程序設(shè)計中,指針有很多應(yīng)用。其中之一就是用指針作為函數(shù)的參數(shù),從而形成了C++函數(shù)調(diào)用中的另一種調(diào)用方式:地址調(diào)用。2022/10/1826北京科技大學(xué)計算機系6.3.1指針作為函數(shù)的參數(shù)用指針作為函數(shù)參數(shù),實現(xiàn)地址調(diào)用,必須滿足以下條件:函數(shù)的形式參數(shù)是指針變量;函數(shù)的實參數(shù)是內(nèi)存的地址,具體來說可以是數(shù)組名、變量的地址、用變量地址初始化的指針;形參指針類型和實參地址類型必須相同。2022/10/1827北京科技大學(xué)計算機系6.3.1指針作為函數(shù)的參數(shù)滿足以上條件后,這樣的函數(shù)調(diào)用在使用上有以下的特點:實參傳遞給形參的是內(nèi)存的地址,所以形參指針指向?qū)崊⒆兞?;形參指針通過間接引用,直接訪問實參變量,包括改變實參變量的值;函數(shù)調(diào)用后,可以保留對實參變量的操作結(jié)果,如果有多個實參,就可以有多個實參變量在函數(shù)調(diào)用中得到修改。2022/10/1828北京科技大學(xué)計算機系
例6.6編寫數(shù)據(jù)交換的函數(shù)。在main中調(diào)用這個函數(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;}
運行結(jié)果:主函數(shù)變量的值:x=5y=10函數(shù)中完成了交換:*a=10*b=5返回后變量的值:
x=10y=5
變量的地址作為實參數(shù)指針變量作為形式參數(shù)函數(shù)的例子里:#include<iostream.h>void
swap(int
a,int
b);void
main(){int
x(5),y(10);cout<<"x="<<x<<"y="<<y<<endl;swap(x,y);cout<<"x="<<x<<"y="<<y<<endl;}void
swap(int
a,int
b){int
t;t=a;a=b;b=t;}2022/10/1829北京科技大學(xué)計算機系6.3.1指針作為函數(shù)的參數(shù)程序中用變量x和y的地址作實參,傳遞給指針a和b,如圖6.1(a)。通過間接引用*a和*b進(jìn)行交換,實際上就是x和y進(jìn)行交換,如圖6.1(b)。
2022/10/1830北京科技大學(xué)計算機系
例6.7指針變量指向一個數(shù)組。用指針變量作為實參調(diào)用一個函數(shù)。在函數(shù)中指針指向數(shù)組的第二個元素。觀察函數(shù)返回后,實參指針值有無變化。
#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<<"也向前移動,*px變?yōu)?<<*px<<endl;}voidMove(int*a){ a=a+1;cout<<"函數(shù)中完成了指針移動:*a="<<*a<<endl;}
運行結(jié)果:調(diào)用前的*px=10
函數(shù)中完成了指針移動:*a=20調(diào)用后的px沒有變化*px還是10
指針作為實參數(shù)指針變量作為形式參數(shù)2022/10/1831北京科技大學(xué)計算機系6.3.2指針的指針作為函數(shù)的參數(shù)如果一定要改變實參指針的值,可以用指針變量的地址作實參,形式參數(shù)就應(yīng)該是指針的指針。2022/10/1832北京科技大學(xué)計算機系
例6.8修改例6.7,使得實參指針返回后,指向新的地址。#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<<"也向前移動,*px變?yōu)?<<*px<<endl;}voidMove(int**a){ *a=*a+1; cout<<"函數(shù)中完成了指針移動:**a="<<**a<<endl; }運行結(jié)果:調(diào)用前的*px=10
函數(shù)中完成了指針移動:**a=20調(diào)用后的px也向前移動,*px變?yōu)?0
指針的地址作為實參數(shù)指針的指針作為形式參數(shù)2022/10/1833北京科技大學(xué)計算機系6.3.3傳遞參數(shù)的保護:指針和常量通過數(shù)組名的地址調(diào)用,可以改變實參數(shù)組的內(nèi)容。但是,并不是所有以數(shù)組名作為實參的函數(shù)調(diào)用,都需要改變數(shù)組的值。例如,在調(diào)用一個求數(shù)組最大值的函數(shù)時,就不希望數(shù)組的值發(fā)生變化。希望在函數(shù)中能夠限制對數(shù)組元素的修改。使用常指針可以達(dá)到這個目的。2022/10/1834北京科技大學(xué)計算機系6.3.3傳遞參數(shù)的保護:指針和常量常指針是指向常量的指針(PointertoConstantdata)的習(xí)慣說法。就是規(guī)定指針?biāo)赶虻膬?nèi)容不可以通過指針的間接引用來改變。常指針說明的格式是:
const<類型名>*<指針名>;
例如:constint*ptint;指針ptint的類型是(constint*),也就是指向一個恒定的整型數(shù)。2022/10/1835北京科技大學(xué)計算機系
例6.10常指針示例。觀察以下程序的運行。
#include<iostream>usingnamespacestd;voidmain(){intia=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; //語句錯誤:左值是常量}
運行結(jié)果:10
120常指針聲明注釋去掉會出現(xiàn)編譯錯誤2022/10/1836北京科技大學(xué)計算機系6.3.3傳遞參數(shù)的保護:指針和常量指針常量(Pointerconstant)。指針本身的內(nèi)容是個常量,不可以改變。指針常量聲明的格式是:
<類型名>*const<指針名>=<初值>;例如: charch,*constptch=&ch;
數(shù)組名就是數(shù)組的首地址?,F(xiàn)在可以說:數(shù)組名就是一個指針常量。
2022/10/1837北京科技大學(xué)計算機系
例6.11指針常量示例。指出以下程序的錯誤。#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; }
錯誤語句注釋掉后運行結(jié)果:10
20語句有錯:常量不能當(dāng)左值語句有錯,地址類型不同//2022/10/1838北京科技大學(xué)計算機系
例6.12用常指針作形參,函數(shù)printString可以輸出數(shù)組的內(nèi)容,不可以對數(shù)組修改。
#include<iostream>usingnamespacestd;voidprintString(constchar*);voidmain(){charphrase[]="C++isamodernprogramminglanguage";cout<<"Thestringis:\n";printString(phrase);cout<<endl;}//main函數(shù)結(jié)束voidprintString(constchar*Ptarray){while(*Ptarray) cout<<*Ptarray++; }不使用常指針也是可以完成打印。但是沒有保護了。數(shù)組名作實參數(shù)常指針作形式參數(shù)2022/10/1839北京科技大學(xué)計算機系6.3.4指針函數(shù)如果一個函數(shù)的返回值是指針,則這樣的函數(shù)稱為指針函數(shù)。如:
int*func01(intk);
函數(shù)func01返回一個指向整型數(shù)據(jù)的指針。返回指針,實際就是返回一個內(nèi)存的地址。要注意:不能返回函數(shù)中局部變量的地址。這樣的地址處于內(nèi)存的堆棧區(qū),是所有函數(shù)公用的區(qū)域。其中的數(shù)據(jù)是不穩(wěn)定的,可能因為其他函數(shù)的執(zhí)行而發(fā)生改變。2022/10/1840北京科技大學(xué)計算機系
例6.13返回不同地址的指針函數(shù)。觀察運行的結(jié)果。#include<iostream>usingnamespacestdintva=100; //全局變量int*get_int(int*pt,intj) //指針函數(shù){intvalue=300,*pti=pt;if(j==0||j==1)returnpti;elseif(j==2)returnpti=&value;}voidmain(){int*ptint,vb=200;for(inti=0;i<3;i++) {if(i==0)ptint=get_int(&va,i); elseif(i==1)ptint=get_int(&vb,i); elseif(i==2)ptint=get_int(&va,i); cout<<"i="<<i<<"*ptint="<<*ptint<<endl; }}
運行結(jié)果i=0*ptint=100i=1*ptint=200i=2*ptint=-858993460
返回全局變量或者vb的地址返回函數(shù)局部變量的地址2022/10/1841北京科技大學(xué)計算機系6.4指針和字符串
2022/10/1842北京科技大學(xué)計算機系6.4.1字符串處理的兩種方式C++字符串常量是用雙引號括起的字符序列,并以字符‘\0’作為結(jié)束標(biāo)志。如 "Thisisastring"。字符串常量存放在內(nèi)存的某個區(qū)域,有自己固定的首地址。如果將字符串常量的首地址看成是指針,這種指針既是常指針,也是指針常量。2022/10/1843北京科技大學(xué)計算機系6.4.1字符串處理的兩種方式C++處理字符串有兩種方式:數(shù)組方式和指針方式。數(shù)組方式是將字符串存入字符數(shù)組后,再進(jìn)行處理。一般可以在聲明數(shù)組的時候用字符串來初始化:charstring_array[]="aniceday!";指針方式是用字符串常量來初始化一個字符指針:char*string_pt="aniceday!";2022/10/1844北京科技大學(xué)計算機系6.4.1字符串處理的兩種方式常量不能放在等式左邊運行時會出錯2022/10/1845北京科技大學(xué)計算機系
例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個字符到array3array3[14]='\0'; //添加'\0'到array3cout<<"Thestringinarray3is:"<<array3<<endl;}
不包括提示的運行結(jié)果HappyBirthdaytoYouHappyBirthdaytoYouHappyBirthday
復(fù)制array1到array2,沒有問題復(fù)制array1到array3,空間不夠,有運行錯誤按實際數(shù)組大小,復(fù)制array1到array3,沒有問題2022/10/1846北京科技大學(xué)計算機系6.5通過指針訪問數(shù)組
2022/10/1847北京科技大學(xué)計算機系6.5通過指針訪問數(shù)組指針和數(shù)組有天然的聯(lián)系。因為數(shù)組名本身就是地址,也就是某種類型的指針。將指針和數(shù)組名聯(lián)系起來,訪問數(shù)組就多了一種方法。雖然一維數(shù)組名和二維數(shù)組名都是地址,都可以看作是某種指針,但是指針的類型是不同的。因此,通過指針訪問一維數(shù)組和二維數(shù)組的方法是不同的。
2022/10/1848北京科技大學(xué)計算機系6.5.1通過指針訪問一維數(shù)組要通過指針訪問一維數(shù)組,必須首先聲明一個和數(shù)組類型相同的指針,并且用數(shù)組名來對指針初始化,如:
intA[10],*pa=A;然后,就可以用多種方式訪問數(shù)組元素:數(shù)組名和下標(biāo),如A[0]、A[4];指針和下標(biāo),如pa[0]、pa[4];指針加偏移量的間接引用,如*(pa+4);數(shù)組名加偏移量的間接引用,如*(A+4);指針自加后的間接引用,如*pa++。
2022/10/1849北京科技大學(xué)計算機系
例6.15求數(shù)組內(nèi)所存放的字符串的長度。#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;}
運行結(jié)果都相同方式1:數(shù)組名和下標(biāo)方式2:指針和下標(biāo)方式3:數(shù)組名加偏移量的間接引用方式4:指針加偏移量的間接引用方式5:指針自加的間接引用2022/10/1850北京科技大學(xué)計算機系
例6.16求整型數(shù)組的平均值,顯示數(shù)組元素和平均值。#include<iostream>usingnamespacestd;voidmain(){intintArray[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ù)目求平均值cout<<*ptint;指針再次初始化輸出數(shù)組元素和它們的平均值2022/10/1851北京科技大學(xué)計算機系6.5.2通過指針訪問二維數(shù)組二維數(shù)組可以看成是一維數(shù)組的一維數(shù)組。二維數(shù)組名雖然也是地址(指針),但是卻和一維數(shù)組名有不同的類型。對一維數(shù)組A[5],數(shù)組名A的地址,就是數(shù)組第一個元素A[0]的地址。指針的類型是指向數(shù)組元素的指針。A+1就是元素A[1]的地址。2022/10/1852北京科技大學(xué)計算機系6.5.2通過指針訪問二維數(shù)組對二維數(shù)組B[3][4],數(shù)組名B的地址,則是其中第一個一維數(shù)組B[0]的地址。指針的類型是指向一維數(shù)組的指針。B+1就是下一個一維數(shù)組B[1]的地址。如圖6.3所示。
2022/10/1853北京科技大學(xué)計算機系6.5.2通過指針訪問二維數(shù)組在定義指向一維數(shù)組的指針時,還必須指出一維數(shù)組的大小。聲明指向一維數(shù)組的指針的格式如下: <類型名>(*指針變量名)[一維數(shù)組大小];
例如,和圖6.3中兩個二維數(shù)組所對應(yīng)的指向一維數(shù)組的指針定義如下:char(*ptchb)[4],(*ptchc)[2];ptchb=B;ptchc=C;2022/10/1854北京科技大學(xué)計算機系6.5.2通過指針訪問二維數(shù)組對于指向一維數(shù)組的指針,具有以下的特征:
二維數(shù)組名是指向一維數(shù)組的指針,而不是指向數(shù)組元素的指針。
指向一維數(shù)組指針加1的結(jié)果,是指向下一個一維數(shù)組的指針。
指向一維數(shù)組的指針的間接引用的結(jié)果仍然是地址,即*ptchb仍然是地址。只是地址的類型變了。變?yōu)橐痪S數(shù)組B[0]第一個元素B[0][0]的地址。
因為*ptchb是數(shù)組元素的地址,**ptchb就是數(shù)組元素的值。用指向一維數(shù)組指針訪問二維數(shù)組第i行第j列元素的一般公式是*(*(指針名+i)+j)。
2022/10/1855北京科技大學(xué)計算機系
例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行地址2022/10/1856北京科技大學(xué)計算機系
例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; //有語法錯誤
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列元素的地址2022/10/1857北京科技大學(xué)計算機系
例6.18用單循環(huán)程序,求二維數(shù)組元素的平均值。#include<iostream>usingnamespacestd;voidmain(){intdArray[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;}
運行結(jié)果:數(shù)據(jù)的平均值等于57.0833指向一維數(shù)組指針的初始化求數(shù)組元素的數(shù)目,**dArray就是元素dArray[0][0]數(shù)組求和求平均值輸出平均值2022/10/1858北京科技大學(xué)計算機系6.5.3指針數(shù)組若數(shù)組元素是某種類型的指針,這樣的數(shù)組稱為指針數(shù)組。指針數(shù)組聲明的格式如下:<類型>*<數(shù)組名>[常量表達(dá)式];例如:char*member_name[10];注意和聲明指向一維數(shù)組指針的差別:char(*member_pointer)[10];
2022/10/1859北京科技大學(xué)計算機系6.5.3指針數(shù)組指向字符的指針:char*member_name[]={"Merry“,"John","Hill"};指向這樣的指針數(shù)組的指針:char**arr=member_name;或者:char**arr;arr=member_name;這樣定義后,*arr就是指向字符串的指針,以下語句 cout<<*arr<<endl;
將顯示數(shù)組中的第一個字符串"Merry"。2022/10/1860北京科技大學(xué)計算機系
例6.17比較指向一維數(shù)組的指針和指向數(shù)組元素的指針。#include<iostream>usingnamespacestd;voidmain(){shortB[3][4],C[3][2];short(*ptshb)[4],(*ptshc)[2];ptshb=B;ptshc=C;1)cout<<*(*(ptshb+i)+j)
2)short*psh[]for(i=0;i<;i++)psh[i]=B[i];*(psh[i]+j)
332022/10/1861北京科技大學(xué)計算機系
例6.19將若干字符串存入指針數(shù)組,并以NULL表示結(jié)束。將這些字符串按升序排序,輸出排序后的字符串。#include<string>#include<iostream>usingnamespacestd;voidPrint(char*[]);voidString_sort(char*[]);voidmain(){char*pn[]={"George","Bill","Wendy","Abraham","Bruce",NULL};//指針數(shù)組
String_sort(pn);Print(pn);}
函數(shù)原型函數(shù)原型指針數(shù)組求平均值輸出平均值2022/10/1862北京科技大學(xué)計算機系
voidString_sort(char*arr[]){char**p1,**p2,*p3;p1=arr;p2=arr+1; while(*(p1+1)!=NULL) {while(*p2!=NULL) {if(strcmp(*p1,*p2)>0) {p3=*p1; *p1=*p2; *p2=p3;} p2++;}
p1++;
p2=p1+1; } }voidPrint(char*arr[]){cout<<"Sortedstringsare:"<<endl; while(*arr!=NULL) {cout<<*arr<<endl;arr++;}}
Sortedstringsare:AbrahamBillBruceGeorgeWendy
逐次取出每個指針和其余的每個指針?biāo)傅淖址容^如果字符串*p1大于*p2交換地址重新設(shè)置p22022/10/1863北京科技大學(xué)計算機系6.5.4命令行參數(shù)命令行參數(shù)是main函數(shù)的參數(shù)。帶有命令行參數(shù)的main函數(shù)的原型是:<類型>main(intargc,char*argv[]);argc:整數(shù),存放命令行參數(shù)的數(shù)目。argv[]:指針數(shù)組,存放所輸入的命令行參數(shù)。其中argv[0]是所執(zhí)行的程序名,argv[argc-1]是最后一個輸入的參數(shù)字符串,argv[argc]中自動的存入NULL,表示輸入結(jié)束。2022/10/1864北京科技大學(xué)計算機系
例6.20顯示命令行參數(shù)的程序。
#include<iostream>usingnamespacestd;voidmain(intargc,char*argv[]){cout<<"Thecommandlineargumentsare:\n";for(inti=0;i<argc;++i)cout<<argv[i]<<'';}從第0個到第argc-1個參數(shù)顯示參數(shù)原工程文件名稱為:test,編譯鏈接形成可執(zhí)行文件:test.exe輸入testhelloeveryone,輸出為:Thecommandlineargumentsare:testhelloeveryone2022/10/1865北京科技大學(xué)計算機系
例6.21對命令行輸入的字符串進(jìn)行排序并輸出排序結(jié)果。
#include<string>#include<conio.h>#include<iostream>usingnamespacestd;voidPrint(char*[]);voidString_sort(char*[]);voidmain(intargc,char*argv[]){String_sort(argv+1);Print(argv+1);getche();}如在命令行輸入:E:\myfile\proj01\debug\proj01.exebcdabcaabbbd回車后運行并顯示:Sortedstringsare:aababcbbdbcd從第1個參數(shù)開始排序2022/10/1866北京科技大學(xué)計算機系6.6指針訪問動態(tài)內(nèi)存2022/10/1867北京科技大學(xué)計算機系6.6指針訪問動態(tài)內(nèi)存
動態(tài)內(nèi)存是在程序執(zhí)行時才可以申請、使用和釋放的內(nèi)存。也就是存放動態(tài)數(shù)據(jù)的內(nèi)存區(qū)域。存放動態(tài)數(shù)據(jù)的區(qū)域稱為“堆”,動態(tài)內(nèi)存也稱為堆內(nèi)存。動態(tài)內(nèi)存不能通過變量名來使用,而只能通過指針來使用。2022/10/1868北京科技大學(xué)計算機系6.6.1動態(tài)內(nèi)存的申請和釋放C++中通過運算符new申請動態(tài)內(nèi)存,運算符delete釋放動態(tài)內(nèi)存。動態(tài)內(nèi)存申請運算符new的使用格式:
new<類型名>(初值)運算的結(jié)果:如果申請成功,返回指定類型內(nèi)存的地址;如果申請失敗,返回NULL指針。動態(tài)內(nèi)存使用完畢后,要用delete運算來釋放。delete運算符使用格式:
delete<指針名>;
2022/10/1869北京科技大學(xué)計算機系6.6.2動態(tài)數(shù)組空間的申請和釋放申請動態(tài)一維數(shù)組時,要在new表達(dá)式中加上申請數(shù)組的大?。簄ew<類型名>[常量表達(dá)式];注意:在動態(tài)申請數(shù)組空間時,不可以對數(shù)組進(jìn)行初始化。也可以申請二維數(shù)組的空間:int(*pi_marray)[4];pi_marray=newint[3][4];釋放動態(tài)數(shù)組空間都用相同的表達(dá)式:delete[]<指針名>;
2022/10/1870北京科技大學(xué)計算機系6.6.3內(nèi)存泄漏和指針懸掛
內(nèi)存泄漏是指動態(tài)申請的內(nèi)存空間,沒有正常釋放,但是也不能繼續(xù)使用的情況。如:char*ch1;ch1=newchar('A');char*ch2=newchar;ch1=ch2;原來為ch1所申請的存放字符A的空間就不可能再使用了,產(chǎn)生了內(nèi)存泄漏。2022/10/1871北京科技大學(xué)計算機系6.6.3內(nèi)存泄漏和指針懸掛讓指針指向一個已經(jīng)釋放的空間,即所謂的指針懸掛(Dangling)。如:char*ch1,*ch2;ch1=newchar;ch2=ch1;*ch2='B';deletech1;指針ch2就是指向了一個已經(jīng)釋放的地址空間,形成指針懸掛。如果還要用deletech2;語句來釋放ch2所指向的空間,就會出現(xiàn)運行錯誤。2022/10/1872北京科技大學(xué)計算機系6.7引用概念2022/10/1873北京科技大學(xué)計算機系6.7引用概念引用(Reference)是C++中新引入的概念,也是C語言中不存在的數(shù)據(jù)類型。
引用是變量或者其他編程實體(如對象)的別名。因此,引用是不可以單獨定義的。如圖6.4(a)所示,變量A在內(nèi)存中有自己的地址,而A的引用B實際上就是變量A,只是A的另外一個名字。
2022/10/1874北京科技大學(xué)計算機系6.7.1引用的聲明和使用引用是通過運算符&來定義的,定義的格式如下:
<類型名>&引用名=變量名;其中的變量名必須是已經(jīng)定義的,并且和引用的類型必須相同。例如:
intsomeInt; int&refInt=someInt;必須注意:引用必須在聲明的時候就完成初始化,不可以先聲明引用,然后再用另一個語句對它初始化。
2022/10/1875北京科技大學(xué)計算機系6.7.1引用的聲明和使用引用有以下的特點:引用不能獨立存在,它只是其他變量的別名;引用必須在聲明的同時就初始化;引用一旦定義,引用關(guān)系就不可以更改,即B若是A的引用,就不可能是其他變量的引用;引用的類型就是相關(guān)的變量的類型,引用的使用和變量的使用相同。2022/10/1876北京科技大學(xué)計算機系
例6.22引用的使用。觀察以下程序的結(jié)果。
#include<iostream>usingnamespacestd;voidmain(){intintA=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的地址=0x0012FF7C2022/10/1877北京科技大學(xué)計算機系6.7.1常引用如果不希望通過引用來改變相關(guān)的變量的值,則可以定義常引用。常引用定義的格式:
const<類型名>&引用名=變量名;例如:intsomeInt=10;constint&const_refA=someIn
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 生態(tài)經(jīng)濟在農(nóng)業(yè)現(xiàn)代化的作用
- 現(xiàn)代文閱讀教學(xué)策略研究進(jìn)展匯報-探索教育新紀(jì)元
- 生產(chǎn)現(xiàn)場的人性化管理與實踐
- 現(xiàn)代辦公環(huán)境下的金融服務(wù)優(yōu)化
- 公路交通安全設(shè)施施工方案
- 2023三年級數(shù)學(xué)下冊 六 認(rèn)識分?jǐn)?shù)第4課時 分一分(二)(2)說課稿 北師大版
- 2024年九年級語文下冊 第三單元 第11課 送東陽馬生序說課稿 新人教版001
- 2023四年級數(shù)學(xué)上冊 一 認(rèn)識更大的數(shù)第4課時 國土面積說課稿 北師大版001
- Unit 2 Lesson 4 Againplease(說課稿)-2024-2025學(xué)年魯科版(五四學(xué)制)(三起)英語五年級上冊001
- 《2 叢林之美-電子相冊制作》說課稿-2023-2024學(xué)年清華版(2012)信息技術(shù)六年級上冊
- 藥膳與食療試題及答案高中
- 手術(shù)室植入物的管理
- Unit6AtthesnackbarStorytimeDiningwithdragons(課件)譯林版英語四年級上冊
- 2023年四川省公務(wù)員錄用考試《行測》真題卷及答案解析
- 機電一體化系統(tǒng)設(shè)計-第5章-特性分析
- 2025年高考物理復(fù)習(xí)壓軸題:電磁感應(yīng)綜合問題(原卷版)
- 20S515 鋼筋混凝土及磚砌排水檢查井
- 雨棚鋼結(jié)構(gòu)施工組織設(shè)計正式版
- 醫(yī)院重點監(jiān)控藥品管理制度
- 2024尼爾森IQ中國本土快消企業(yè)調(diào)研報告
- 2024年印度辣椒行業(yè)狀況及未來發(fā)展趨勢報告
評論
0/150
提交評論