版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
2023/10/61C++大學(xué)基礎(chǔ)教程第6章指針和引用
2023/10/61C++大學(xué)基礎(chǔ)教程第6章指針和引用2023/10/62指針(Pointer)是C++和C的一種數(shù)據(jù)類型。很多其他高級語言也有類似的數(shù)據(jù)類型。引用(Reference)則是C++所特有的一種數(shù)據(jù)類型。2023/10/62指針(Pointer)是C++和C的一種2023/10/63第六章指針和引用6.1指針的概念6.2指針的運(yùn)算6.3指針和函數(shù)6.4指針和字符串6.5通過指針訪問數(shù)組6.6指針訪問動態(tài)內(nèi)存6.7引用概念
2023/10/63第六章指針和引用6.1指針的概念2023/10/646.1指針的概念
2023/10/646.1指針的概念2023/10/656.1.1
指針和指針變量指針是變量的地址 例如,定義整型變量a,a的地址就是一個指針。 直接指定內(nèi)存某個地址開始(如0x00430100)存放指針的變量就是指針變量。2023/10/656.1.1指針和指針變量指針是變量的地2023/10/666.1.1
指針和指針變量當(dāng)聲明了一個指針變量后,確定了三件事:1.變量本身在內(nèi)存中所分配的地址和字節(jié)數(shù)(4個)2.系統(tǒng)允許的地址范圍,及地址單元內(nèi)可以存放的內(nèi)容3.指針變量可以進(jìn)行的運(yùn)算訪問指針變量時,只能看到地址通過這個地址訪問地址單元中的內(nèi)容,這樣的訪問稱為對于內(nèi)存單元的間接訪問。2023/10/666.1.1指針和指針變量當(dāng)聲明了一個指2023/10/676.1.2指針變量的聲明和初始化指針變量聲明的格式是:
類型名*變量名1,*變量名2;例如:
int*va1,*va2; char*ch1,*ch2;指針變量在聲明后,變量的值(地址)是隨機(jī)的。這樣的指針變量是不能安全的使用的2023/10/676.1.2指針變量的聲明和初始化指針2023/10/686.1.2指針變量的聲明和初始化在聲明指針變量時的“*”,有兩個含義:聲明變量va1、ch1、ch2都是指針變量;說明變量va1的類型是(int*)型,即指向整型變量的指針。ch1和ch2的類型是(char*)型指針變量都是有類型的---所指定的地址單元中存放的數(shù)據(jù)的類型
2023/10/686.1.2指針變量的聲明和初始化在聲2023/10/696.1.2指針變量的聲明和初始化指針變量必須初始化后才能安全使用聲明指針變量時進(jìn)行初始化的格式:
類型名*指針變量名=&變量名;
charch1=’Y’,ch2=’A’; char*pch1=&ch1,*pch2=&ch2;2023/10/696.1.2指針變量的聲明和初始化指針2023/10/6106.1.2指針變量的聲明和初始化賦值方式進(jìn)行初始化:
inti1=’Y’,i2=’A’; int*pi1,*pi2; pi1=&i1; pi2=&i2;沒有初始化的指針變量不可以使用
(編譯系統(tǒng)會給出警告,而運(yùn)行時會出現(xiàn)錯誤)
2023/10/6106.1.2指針變量的聲明和初始化賦2023/10/6116.2指針的運(yùn)算
2023/10/6116.2指針的運(yùn)算2023/10/6126.2指針的運(yùn)算表6.1指針的運(yùn)算2023/10/6126.2指針的運(yùn)算2023/10/6136.2.1指針的賦值運(yùn)算指針的賦值:地址的賦值同類型變量的地址同類型的已經(jīng)初始化的指針變量;其他同類型的指針用0或者NULL賦值
“空指針”,即不指向任何的內(nèi)存物理地址不同類型的指針不可以互相賦值
在指針賦值時,不存在類型自動轉(zhuǎn)換的機(jī)制2023/10/6136.2.1指針的賦值運(yùn)算指針的賦值2023/10/614
例6.1觀察以下指針賦值運(yùn)算的結(jié)果。如果將注釋去掉,結(jié)果將如何?#include<iostream>usingnamespacestd;voidmain(){intva1=100,*pva1;int*pva2=NULL;floatvf1='A',*pvf1,*pvf2;cout<<"valueofpva2is"<<pva2<<endl;pva1=&va1;pvf1=pvf2=&vf1;cout<<pva1<<""<<&va1<<endl;cout<<pvf1<<""<<pvf2<<endl;//pvf1=pva1;}valueofpva2is0x000000000x0012FF7C0x0012FF7C0x0012FF740x0012FF74注釋去掉會出現(xiàn)編譯錯誤2023/10/614例6.1觀察以下指針賦值運(yùn)算的結(jié)果2023/10/6156.2.2間接引用運(yùn)算
間接引用運(yùn)算符“*”
:一元運(yùn)算符
和指針變量連用,對指針?biāo)赶虻膬?nèi)存地址單元進(jìn)行間接訪問使用的格式:
*指針變量如果指針變量iptr指向整型變量va *iptr就是變量va的內(nèi)容
2023/10/6156.2.2間接引用運(yùn)算間接引用運(yùn)算2023/10/616
例6.2對變量的直接訪問和間接訪問#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;//間接訪問
}運(yùn)行結(jié)果:*ch=ach1=B*ch=d2023/10/616例6.2對變量的直接訪問和間接訪問2023/10/617
例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)容}運(yùn)行結(jié)果:*pva=100*ppva=0x0012FF7Cpva=0x0012FF7C
2023/10/617例6.3觀察對這種指針變2023/10/6186.2.2間接引用運(yùn)算2023/10/6186.2.2間接引用運(yùn)算2023/10/6196.2.3指針的算術(shù)運(yùn)算
可以進(jìn)行的只有加法和減法--和整數(shù)n做加法或者減法指針p和整數(shù)n相加(相減)的含義是指向當(dāng)前指向位置p的前方或后方第n個數(shù)據(jù)的地址。2023/10/6196.2.3指針的算術(shù)運(yùn)算可以進(jìn)行的2023/10/620
例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;}運(yùn)行結(jié)果:K1[0]=11k1[2]=37….
數(shù)組第一個元素(下標(biāo)為0)的地址賦值給指針k
每次循環(huán),指針加22023/10/620例6.4通過指針的間接訪問,輸出下2023/10/6216.2.3指針的算術(shù)運(yùn)算指針和指針的直接加法沒有意義指針和指針的減法可以進(jìn)行----求出兩個指針之間可以存放幾個指定類型的數(shù)據(jù)不允許用一個整數(shù)減一個指針2023/10/6216.2.3指針的算術(shù)運(yùn)算指針和指針的2023/10/6226.2.4指針的關(guān)系運(yùn)算和邏輯運(yùn)算
同類型的指針可以進(jìn)行關(guān)系運(yùn)算進(jìn)行指針“大于”、“小于”的比較,是判定指針在內(nèi)存中的相對位置指針和一般的整數(shù)比較沒有意義,也不允許
惟一可以和指針比較的整數(shù)是0。判定指針是不是空指針
2023/10/6226.2.4指針的關(guān)系運(yùn)算和邏輯運(yùn)算2023/10/6236.2.5void類型指針
void類型的指針就是“無類型”指針:
void*指針名;存放的也是內(nèi)存的地址,但不指定這個地址單元內(nèi)的數(shù)據(jù)的類型2023/10/6236.2.5void類型指針void2023/10/6246.2.5void類型指針使用要點(diǎn)
--任何指針都可以賦值給void指針
賦值后的void指針的類型仍然是void
--void指針不可以賦值給其他任何類型的指針
--void指針不可通過間接引用訪問內(nèi)存中數(shù)據(jù)
--必須進(jìn)行指針類型的強(qiáng)制轉(zhuǎn)換,才可以使用指針間接引用訪問內(nèi)存數(shù)據(jù)2023/10/6246.2.5void類型指針使用要點(diǎn)2023/10/625
例6.5使用memcpy通用復(fù)制函數(shù)復(fù)制數(shù)組 原型void*memcpy(void*dest,constvoid*,size)
#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個字節(jié)復(fù)制整型數(shù)據(jù),12個字節(jié)2023/10/625例6.5使用memcpy通用復(fù)制函2023/10/6266.2.5void類型指針
void類型指針應(yīng)用:顯示字符指針的內(nèi)容其他指針直接用cout語句輸出地址值而字符指針輸出的是字符串將字符指針強(qiáng)制轉(zhuǎn)換為void指針cout語句輸出便是地址值例:char*pch="HelloC++";cout<<pch<<endl;cout<<(void*)pch<<endl;
2023/10/6266.2.5void類型指針void2023/10/627指針是地址int*p;p=&a;*p=100;b=*p+2;2023/10/627指針是地址int*p;*p=100;2023/10/6286.3指針和函數(shù)
2023/10/6286.3指針和函數(shù) 2023/10/6296.3指針和函數(shù)在程序設(shè)計中,指針有很多應(yīng)用其中之一就是作為函數(shù)的參數(shù),形成了C++函數(shù)調(diào)用中的另一種調(diào)用方式:地址調(diào)用
2023/10/6296.3指針和函數(shù)在程序設(shè)計中,指針有2023/10/6306.3.1指針作為函數(shù)的參數(shù)實現(xiàn)地址調(diào)用,必須滿足以下條件:函數(shù)的形式參數(shù)是指針變量;函數(shù)的實參數(shù)是內(nèi)存的地址 (可以是數(shù)組名、變量的地址、用變量地址初始化的指針)形參指針類型和實參地址類型必須相同
2023/10/6306.3.1指針作為函數(shù)的參數(shù)實現(xiàn)地址2023/10/6316.3.1指針作為函數(shù)的參數(shù)實參傳遞給形參的是內(nèi)存的地址,所以形參指針指向?qū)崊⒆兞啃螀⒅羔樛ㄟ^間接引用,直接訪問實參變量(包括改變實參變量的值)函數(shù)調(diào)用后,改變了實參,如果有多個實參,就可以有多個實參變量在函數(shù)調(diào)用中被修改2023/10/6316.3.1指針作為函數(shù)的參數(shù)2023/10/632
例6.6編寫數(shù)據(jù)交換的函數(shù)。#include<iostream>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ù)2023/10/632例6.6編寫數(shù)據(jù)交換的函數(shù)。運(yùn)行結(jié)2023/10/6336.3.1指針作為函數(shù)的參數(shù)變量x和y的地址作實參傳遞給指針a和b,如圖(a)通過間接引用*a和*b進(jìn)行交換,實際上就是x和y進(jìn)行交換,如圖(b)2023/10/6336.3.1指針作為函數(shù)的參數(shù)變量x和2023/10/634
例6.7指針變量指向一個數(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;*a=100;cout<<“函數(shù)中完成了指針移動:*a="<<*a<<endl;}
運(yùn)行結(jié)果:調(diào)用前的*px=10
函數(shù)中完成了指針移動:*a=20調(diào)用后的px沒有變化*px還是10
指針作為實參數(shù)指針變量作為形式參數(shù)2023/10/634例6.7指針變量指向一個數(shù)組運(yùn)行結(jié)2023/10/6356.3.3傳遞參數(shù)的保護(hù):指針和常量通過數(shù)組名地址調(diào)用,可以改變實參數(shù)組內(nèi)容但有時并不需要改變數(shù)組的值例如,在調(diào)用一個求數(shù)組最大值的函數(shù)時,就不希望數(shù)組的值發(fā)生變化希望在函數(shù)中能夠限制對數(shù)組元素的修改使用常指針可以達(dá)到這個目的2023/10/6356.3.3傳遞參數(shù)的保護(hù):指針和常量2023/10/6366.3.3傳遞參數(shù)的保護(hù):指針和常量常指針是指向常量的指針(PointertoConstantdata)規(guī)定指針?biāo)赶虻膬?nèi)容不可以通過指針的間接引用來改變。常指針說明的格式是:
const類型名*指針名;
例如:constint*ptint;指針ptint的類型是(constint*),即指向一個恒定的整型數(shù)2023/10/6366.3.3傳遞參數(shù)的保護(hù):指針和常量2023/10/637
例6.10常指針示例。觀察以下程序的運(yùn)行。
#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; //語句錯誤:左值是常量}運(yùn)行結(jié)果:10
120常指針聲明注釋去掉會出現(xiàn)編譯錯誤2023/10/637例6.10常指針示例。觀察以下程序2023/10/6386.3.3傳遞參數(shù)的保護(hù):指針和常量指針常量(Pointerconstant)指針本身是常量(地址是常量),不可以改變指針常量聲明的格式:
類型名*const指針名=初值; charch,*constptch=&ch;數(shù)組名是數(shù)組的首地址--數(shù)組名是指針常量
2023/10/6386.3.3傳遞參數(shù)的保護(hù):指針和常量2023/10/639
例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; }
錯誤語句注釋掉后運(yùn)行結(jié)果:10
20語句有錯:常量不能當(dāng)左值語句有錯,地址類型不同不能用常量地址初始化指針常量2023/10/639例6.11指針常量示例。指出以下程2023/10/640
例6.12用常指針作形參,函數(shù)printString可以輸出數(shù)組的內(nèi)容,不可以對數(shù)組修改。
#include<iostream>usingnamespacestd;voidprintString(constchar*);voidmain(){charphrase[]="C++isaprogramminglanguage";cout<<"Thestringis:\n";printString(phrase);cout<<endl;}//main函數(shù)結(jié)束voidprintString(constchar*Ptarray){while(*Ptarray) cout<<*Ptarray++; }
不使用常指針也是可以完成打印。但是沒有保護(hù)了。數(shù)組名作實參數(shù)常指針作形式參數(shù)2023/10/640例6.12用常指針作形參,函數(shù)pr2023/10/6416.4指針和字符串
2023/10/6416.4指針和字符串 2023/10/6426.4.1字符串處理的兩種方式字符串常量:雙引號括起,‘\0’結(jié)束如: "Thisisastring"。字符串常量有自己固定的首地址如果將字符串常量的首地址看成是指針,這種指針既是常指針,也是指針常量。2023/10/6426.4.1字符串處理的兩種方式字符串2023/10/6436.4.1字符串處理的兩種方式處理字符串兩種方式:數(shù)組方式和指針方式
數(shù)組方式是將字符串存入字符數(shù)組:charstring_array[]="What’saniceday!";指針方式是用字符串常量來初始化一個字符指針:char*string_pt="What’saniceday!";2023/10/6436.4.1字符串處理的兩種方式處理字2023/10/6446.4.1字符串處理的兩種方式指針常量不能放在等式左邊運(yùn)行時會出錯2023/10/6446.4.1字符串處理的兩種方式指針常2023/10/6456.4.2字符串操作函數(shù)
實參數(shù):字符數(shù)組名、已經(jīng)初始化的字符指針,字符串常量目的串必須是可寫的。2023/10/6456.4.2字符串操作函數(shù)實參數(shù):2023/10/646
例6.14strcpy和strncpy的比較。#include<string>
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ù)制array1的n-1個字符
array3[14]='\0';//添加'\0'到array3cout<<"Thestringinarray3is:"<<array3<<endl;}
不包括提示的運(yùn)行結(jié)果HappyBirthdaytoYouHappyBirthdaytoYouHappyBirthday
復(fù)制array1到array2,沒有問題復(fù)制array1到array3,空間不夠,有運(yùn)行錯誤按實際數(shù)組大小,復(fù)制array1到array3,沒有問題2023/10/646例6.14strcpy和strnc2023/10/6476.5通過指針訪問數(shù)組
2023/10/6476.5通過指針訪問數(shù)組 2023/10/6486.5通過指針訪問數(shù)組指針和數(shù)組有天然的聯(lián)系數(shù)組名就是地址,也就是某種類型的指針雖然一維數(shù)組名和二維數(shù)組名都是地址,都可以看作是某種指針,但是指針的類型是不同的通過指針訪問一維數(shù)組和二維數(shù)組的方法是不同的2023/10/6486.5通過指針訪問數(shù)組指針和數(shù)組有天2023/10/6496.5.1通過指針訪問一維數(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++
2023/10/6496.5.1通過指針訪問一維數(shù)組必須聲2023/10/650
例6.15求數(shù)組內(nèi)所存放的字符串的長度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:指針自加的間接引用2023/10/650例6.15求數(shù)組內(nèi)所存放的字符串的2023/10/651
例6.16求整型數(shù)組的平均值,顯示數(shù)組元素和平均值。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;}
運(yùn)行結(jié)果:數(shù)組元素是:8112334455665788697平均值是:50.3
指針初始化求數(shù)組元素的數(shù)目求平均值指針再次初始化輸出數(shù)組元素和它們的平均值2023/10/651例6.16求整型數(shù)組的平均值,顯示數(shù)2023/10/6526.5.2通過指針訪問二維數(shù)組二維數(shù)組可以看成是一維數(shù)組的一維數(shù)組二維數(shù)組名也是地址(指針),但和一維數(shù)組名有不同的類型對一維數(shù)組A[5]數(shù)組名A的地址,是第一個元素A[0]的地址指針的類型是指向數(shù)組元素的指針A+1A[1]的地址2023/10/6526.5.2通過指針訪問二維數(shù)組二維數(shù)2023/10/6536.5.2通過指針訪問二維數(shù)組對二維數(shù)組B[3][4]數(shù)組名B的地址,一維數(shù)組B[0]的地址指針的類型是指向一維數(shù)組的指針B+1一維數(shù)組B[1]的地址
2023/10/6536.5.2通過指針訪問二維數(shù)組對二維2023/10/6546.5.2通過指針訪問二維數(shù)組定義指向一維數(shù)組的指針時,必須指出一維數(shù)組的大小聲明格式如下:
類型名(*指針變量名)[一維數(shù)組大小];
例如:char(*ptchb)[4],(*ptchc)[2];ptchb=B;ptchc=C;2023/10/6546.5.2通過指針訪問二維數(shù)組定義指2023/10/6556.5.2通過指針訪問二維數(shù)組指向一維數(shù)組的指針具有的特征:
二維數(shù)組名是指向一維數(shù)組的指針,不指向數(shù)組元素
指針加1是指向下一個一維數(shù)組的指針
指向一維數(shù)組的指針的間接引用的結(jié)果仍然是地址,即*ptchb仍然是地址,為一維數(shù)組B[0]第一個元素B[0][0]的地址
*ptchb是數(shù)組元素的地址,**ptchb就是數(shù)組元素的值 訪問二維數(shù)組第i行第j列元素:*(*(指針名+i)+j)2023/10/6556.5.2通過指針訪問二維數(shù)組指向一2023/10/656
例6.17比較指向一維數(shù)組的指針和指向數(shù)組元素的指針voidmain(){shortB[3][4],C[3][2];short(*ptshb)[4],(*ptshc)[2];ptshb=B;ptchc=C;cout<<"比較不同的指向一維數(shù)組指針的差別\n";cout<<"ptshb的地址是:"<<ptshb<<"\n";cout<<"ptshb+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行地址2023/10/656例6.17比較指向一維數(shù)組的指針和指2023/10/657
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列元素的地址2023/10/657cout<<"不同類型的指針\2023/10/658
例6.18用單循環(huán)程序,求二維數(shù)組元素的平均值。voidmain(){
intArray[3][4]={32,42,12,25,56,76,46,53,76,89,96,82},
(*pt)[4];intsum,j;floataverage;sum=0;pt=Array;
j=sizeof(Array)/sizeof(**Array); 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ù)目,**Array就是元素Array[0][0]數(shù)組求和求平均值輸出平均值2023/10/658例6.18用單循環(huán)程序,求二維數(shù)組2023/10/659一維數(shù)組:intintArray[2]={8,11},*ptint;sum=sum+*ptint++;二維數(shù)組:intA[2][3]={32,42,12,25,56,76},(*pt)[3];sum=sum+*(*(pt+i)+j);2023/10/659一維數(shù)組:2023/10/6606.6指針訪問動態(tài)內(nèi)存2023/10/6606.6指針訪問動態(tài)內(nèi)存2023/10/6616.6指針訪問動態(tài)內(nèi)存
動態(tài)內(nèi)存:在程序執(zhí)行時才可以申請、使用和釋放的內(nèi)存存放動態(tài)數(shù)據(jù)的區(qū)域稱為“堆”,動態(tài)內(nèi)存也稱為堆內(nèi)存
動態(tài)內(nèi)存不能通過變量名來使用,只能通過指針來使用2023/10/6616.6指針訪問動態(tài)內(nèi)存動態(tài)內(nèi)存:2023/10/6626.6.1動態(tài)內(nèi)存的申請和釋放C++中通過運(yùn)算符new申請動態(tài)內(nèi)存,運(yùn)算符delete釋放動態(tài)內(nèi)存new的使用格式:
new類型名(初值)
int*p;p=newint(3);申請成功:返回指定類型內(nèi)存的地址申請失敗:返回NULL指針2023/10/6626.6.1動態(tài)內(nèi)存的申請和釋放C++2023/10/6636.6.1動態(tài)內(nèi)存的申請和釋放運(yùn)算符delete釋放動態(tài)內(nèi)存delete運(yùn)算符使用格式:
delete指針名;
deletep;
new與delete應(yīng)該成對出現(xiàn)2023/10/6636.6.1動態(tài)內(nèi)存的申請和釋放運(yùn)算符2023/10/6646.6.2動態(tài)數(shù)組空間的申請和釋放申請動態(tài)數(shù)組要加上數(shù)組的大?。阂痪S:
new類型名[常量表達(dá)式];注意:動態(tài)申請數(shù)組空間時,不可以對數(shù)組進(jìn)行初始化二維:int(*pi_marray)[4];pi_marray=newint[3][4];釋放動態(tài)數(shù)組空間都用相同的表達(dá)式:delete[]<指針名>;
2023/10/6646.6.2動態(tài)數(shù)組空間的申請和釋放申2023/10/6656.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)存泄漏2023/10/6656.6.3內(nèi)存泄漏和指針懸掛內(nèi)存泄2023/10/6666.6.3內(nèi)存泄漏和指針懸掛指針指向一個已經(jīng)釋放的空間,即指針懸掛char*ch1,*ch2;ch1=newchar;ch2=ch1;*ch2='B';deletech1;指針ch2指向了一個已經(jīng)釋放的地址空間---指針懸掛用deletech2;語句來釋放ch2所指向的空間,會出現(xiàn)運(yùn)行錯誤2023/10/6666.6.3內(nèi)存泄漏和指針懸掛指針指向2023/10/6676.7引用概念2023/10/6676.7引用概念2023/10/6686.7引用概念引用(Reference)是C++中新引入的概念,是C語言中不存在的數(shù)據(jù)類型
引用是變量或者其他編程實體(如對象)的別名因此引用不可以單獨(dú)定義如圖6.4(a):變量A在內(nèi)存中有自己的地址,而A的引用B實際上就是變量A,只是A的另外一個名字
2023/10/6686.7引用概念引用(Referenc2023/10/6696.7.1引用的聲明和使用引用通過運(yùn)算符&來定義:
類型名&引用名=變量名;變量名必須已經(jīng)定義和引用的類型必須相同
intsomeInt; int&refInt=someInt;必須注意:引用必須在聲明的時候就完成初始化,不可以先聲明引用,然后再用另一個語句對它初始化。
2023/10/6696.7.1引用的聲明和使用引用通過運(yùn)2023/10/670改進(jìn)C中函數(shù)的形參定義為指針型參數(shù)時所帶來的不安全性intadd(int*x,int*y){*x=*x+*y;return*x;}intadd(int&x,int&y){x=x+y;returnx;}改為2023/10/670改進(jìn)C中函數(shù)的形參定義為指針型參數(shù)時所2023/10/6716.7.1引用的聲明和使用引用的特點(diǎn):
引用不能獨(dú)立存在,它只是其他變量的別名引用必須在聲明的同時初始化引用一旦定義,引用關(guān)系就不可以更改B是A的引用,就不可能是其他變量的引用引用的類型就是相關(guān)的變量的類型,引用的使用和變量的使用相同2023/10/6716.7.1引用的聲明和使用引用的特點(diǎn)2023/10/672
例6.22引用的使用。觀察以下程序的結(jié)果。
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的地址=0x0012FF7C2023/10/672例6.22引用的使用。觀察以下程序2023/10/673
例6.23指針的引用。voidmain(){ intintA=10,intB=20; int*pti=&intA; int*&refi=pti; cout<<“指針的引用可以訪問指針?biāo)傅淖? 量:*refi="<<*refi<<endl;cout<<"指針變量原來的值:pti="<<pti<<endl; refi=&intB;cout<<“引用的變化,則相關(guān)指針也變化:pti="<<pti<<endl; cout<<"指針?biāo)傅淖兞恐狄舶l(fā)生變化:*pti="<<*pti<<endl;}
指針的引用可以訪問指針?biāo)傅淖兞?*refi=10指針變量原來的值:pti=0x0012FF7C引用的變化,則相關(guān)指針也變化:pti=0x0012FF78指針?biāo)傅淖兞恐狄舶l(fā)生變化:*pti=202023/10/673例6.23指針的引用。指針的引用2023/10/6746.7.1引用的聲明和使用如果不希望通過引用來改變相關(guān)的變量的值,可以定義常引用:
const類型名&引用名=變量名;例如:intsomeInt=10;constint&const_refA=someInt;const_refA就是常引用。不可以通過const_refA來改變someInt變量的值2023/10/6746.7.1引用的聲明和使用如果不希望2023/10/6756.7.2通過引用傳遞函數(shù)參數(shù)引用使用最多的場合是作為函數(shù)的形式參數(shù)
引用作為函數(shù)的形參有以下特點(diǎn):形參,實參是相同類型的變量
引用作為形參,參數(shù)傳遞屬于地址傳遞
引用作為形參,在函數(shù)中并不產(chǎn)生實參副本是同一個實體
函數(shù)對
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 治療肚臍病的故事
- 廢棄資源綜合利用的水環(huán)境與水資源保護(hù)考核試卷
- 天然氣開采的社會責(zé)任與公眾參與考核試卷
- 體育用品廣告宣傳與體育保險考核試卷
- 木材的變形與干縮原因考核試卷
- 創(chuàng)業(yè)空間的投資與風(fēng)險管理考核試卷
- 智能醫(yī)療設(shè)備研發(fā)合作協(xié)議
- 軌道交通項目異議處理程序時效
- 邯鄲市健身器材市場租賃合同
- 水利信息化管理操作指南
- 機(jī)械加工工時定額標(biāo)準(zhǔn)計算手冊
- 商務(wù)禮儀說課
- 混凝土售后服務(wù)
- 盾構(gòu)始發(fā)條件驗收
- GB/T 6726-2008汽車用冷彎型鋼尺寸、外形、重量及允許偏差
- GB/T 4372.1-2014直接法氧化鋅化學(xué)分析方法第1部分:氧化鋅量的測定Na2EDTA滴定法
- GB/T 30680-2014氟橡膠板通用技術(shù)條件
- GB/T 16830-2008商品條碼儲運(yùn)包裝商品編碼與條碼表示
- GB 5226.1-2008機(jī)械電氣安全機(jī)械電氣設(shè)備第1部分:通用技術(shù)條件
- GA/T 850-2021城市道路路內(nèi)停車位設(shè)置規(guī)范
- 雙代號網(wǎng)絡(luò)計劃圖習(xí)題
評論
0/150
提交評論