C++第8章指針課件_第1頁
C++第8章指針課件_第2頁
C++第8章指針課件_第3頁
C++第8章指針課件_第4頁
C++第8章指針課件_第5頁
已閱讀5頁,還剩55頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第八章指針和基于指針的字符串指針引用調(diào)用數(shù)組與指針函數(shù)指針基于指針的字符串總結(jié)指針的概念指針就是把地址作為數(shù)據(jù),把地址存儲在內(nèi)存中指針變量:存儲地址的變量變量的指針:當(dāng)一個變量存儲另一個變量的地址時,那我們說它就是那個變量的指針100021000如在某一程序中定義了intx;X=2;如系統(tǒng)給x分配的空間是1000號單元,則指向x的指針是另一個變量,該變量中存放的數(shù)據(jù)為1000指針變量的定義如何定義一個變量為指針變量?類型標(biāo)識符*指針變量;如:int*a;double*b; char*c;指針運算符指針運算符包括兩個一元運算符:&,*

形式:&變量名如:&y返回變量y在內(nèi)存中的地址&運算符的意義:

變量所占據(jù)的內(nèi)存地址由系統(tǒng)分配,因為我們不知道系統(tǒng)分配給變量的真正地址是什么。如何獲得該地址,并將它入一個指針變量中?用地址運算符“&”

解決。如:a=&x;&運算符后面不能跟常量或表達(dá)式。如&2

是沒有意義的,&(m*n+p)。也是沒有意義的指針運算符指針運算符包括兩個一元運算符:&,*

形式:*指針變量名如:*a

返回指針變量intPtr中存儲的地址所指向空間中的值*運算符的意義:

如何用指針變量處理和改變它所指向的單元的值?用引用運算符“*”解決。如*a

表示的是a

指向的這個單元的內(nèi)容。因此*也稱為間接引用或間接運算符在對a

使用引用運算之前,必須先對a

賦值指針的定義及使用指針變量可以指向不同的變量。如上例中intp指向x,我們可以通過對intp的重新賦值改變指針的指向。如果想讓intp指向y,只要執(zhí)行intp=&y就可以了。這時,intp與x無任何關(guān)系。同類的指針變量之間可相互賦值,表示二個指針指向同一內(nèi)存空間??罩羔樦羔槢]有指向任何空間空指針用常量NULL表示,NULL的值一般賦為0不能引用空指針指向的值指針變量的地址指針也是變量,是變量就具有內(nèi)存地址。所以指針也具有地址。例如#include<iostream.h>voidmain(){intiCount=18;int*iPtr=&iCount;*iPtr=58;

cout<<iCount<<endl;cout<<iPtr<<endl;cout<<&iCount<<endl;//與iPtr值相同cout<<*iPtr<<endl;//與iCount值相同cout<<&iPtr<<endl;//指針本身的地址}運行結(jié)果:580x0067fe000x0067fe00580x0067fe00指針的初始化指針在使用前必須初始化。僅和別的變量一樣定義指針,不初始化是一個比較普通的錯誤。沒有初始化的指針可能指向任意地址,對這些指針作操作可能會導(dǎo)致程序錯誤。NULL是一個特殊指針值,稱為空指針。它的值為0。它可被用來初始化一個指針,表示不指向任何地址。8.2指針的運算數(shù)組名本身實際上就是地址,表示數(shù)組的起始地址例如#include<iostream.h>voidmain(){intiArray[10];intsum=0;int*iPtr=iArray;//用數(shù)組名iArray給指針初始化for(inti=0;i<10;i++)//給數(shù)組賦值iArray[i]=i*2;

也可以寫成int*iPtr;iPtr=iArray;for(intindex=0;index<10;index++){//計算數(shù)組元素之和sum+=*iPtr;iPtr++;}cout<<"sumis"<<sum<<endl;}

運行結(jié)果為sumis90指針的運算都是以數(shù)據(jù)類型為單位展開的,且只有加減法使用于指針運算。對int指針加6,實際上加了12;對char指針加6,實際上加了6;對float指針加6,實際上加了24;.............8.3數(shù)組與指針在C++中,數(shù)組與指針是密切相關(guān)的,兩者幾乎可以交換使用.數(shù)組名代表數(shù)組的起始地址,因此一個數(shù)組名就是一個常量指針.數(shù)組與指針不同之處

1、系統(tǒng)內(nèi)存空間分配不同

2、數(shù)組名是常量指針,不能修改它的值。數(shù)組與指針——相同之處#defineN5;inta[N],*p;假設(shè)300是a的基地址如下操作是允許的:p=a;等價于p=&a[0]此時p=300;p=a+1;等價于p=&a[1]此時p=304;數(shù)組與指針——不同之處#defineN5;inta[N],*p;假設(shè)300是a的基地址以下操作是不允許的:

a=p;a++;a+=3;a是常量指針,不能修改它的值。運行并分析Fig.8.20,Fig.8.21指針的運算#include<iostream.h>intsum1,sum2,sum3,sum4,sum5;//存放每種方法的結(jié)果intiArray[]={1,4,2,7,13,32,21,48,16,30};//全局?jǐn)?shù)組int*iPtr;voidmain(){intsize,n;size=sizeof(iArray)/sizeof(*iArray);//元素個數(shù)for(n=0;n<size;n++)//方法1sum1+=iArray[n];iPtr=iArray;for(n=0;n<size;n++)//方法2sum2+=*iPtr++;iPtr=iArray;//此句不能省略,因為方法2修改了iPtrfor(n=0;n<size;n++)//方法3sum3+=*(iPtr+n);iPtr=iArray;//此句可以省略,因為方法3沒有修改iPtrfor(n=0;n<size;n++)//方法4sum4+=iPtr[n];for(n=0;n<size;n++)//方法5sum5+=*(iArray+n);cout<<sum1<<endl<<sum2<<endl<<sum3<<endl<<sum4<<endl<<sum5<<endl;}運行結(jié)果:1741741741741748.4堆內(nèi)存分配堆是內(nèi)存空間。堆允許程序在運行時,申請某個大小的內(nèi)存空間。指針數(shù)組數(shù)組是同種數(shù)據(jù)類型數(shù)據(jù)的集合,該類型當(dāng)然也可以是指針.指針數(shù)組:數(shù)組的每個元素都是指針如:char*a[4];charch1,ch2,ch3,ch4

a[0]=&ch1;a[1]=&ch2;a[2]=&che3;a[3]=&ch4;指針數(shù)組

實際應(yīng)用中,常見的做法是字符串?dāng)?shù)組:constchar*suit[4]={“Hearts”,“Diamonds”,“Clubs”,“Spades”}

字符串?dāng)?shù)組中的每一項都是一個字符串,實際指向相應(yīng)字符串的第一個字符的指針(地址)

動態(tài)內(nèi)存分配#include<alloc.h>void*malloc(size_t,size_t);當(dāng)系統(tǒng)無法分配所申請的空間時,返回值為NULLmalloc()分配的存儲空間沒有被初始化,開始值無用動態(tài)分配空間分配n個int需要的空間int*p;p=(int*)malloc(n*sizeof(int));強制類型轉(zhuǎn)換釋放空間voidfree(void*ptr);函數(shù)用途:釋放malloc函數(shù)申請的空間強烈建議:由malloc申請的內(nèi)存空間在程序運行過程中不會自動釋放,當(dāng)申請的空間不再需要使用的話,程序員必須free函數(shù)釋放相應(yīng)的空間。new與deletenew與delete是c++專有的操作符,不用頭文件聲明new類似于函數(shù)malloc()分配堆內(nèi)存,可以帶初始化值表或單元個數(shù),new的返回值是具有操作數(shù)之?dāng)?shù)據(jù)類型的指針返回delete類似于函數(shù)free(),釋放堆內(nèi)存,delete的操作數(shù)是new返回的指針,當(dāng)返回的是new分配的數(shù)組時,應(yīng)帶[]//*********************//**ch8_9.cpp**//*********************#include<iostream.h>//#include<alloc.h>//無須頭文件voidmain(){intarraysize;//元素個數(shù)int*array;cout<<"pleaseinputanumberofarray:\n";cin>>arraysize;

if((array=newint[arraysize])==NULL){//分配堆內(nèi)存cout<<"can'tallocatemorememory,terminating.\n";return;}for(intcount=0;count<arraysize;count++)array[count]=count*2;for(intcount=0;count<arraysize;count++)cout<<array[count]<<"";cout<<endl;delete[]array;//釋放堆內(nèi)存}8.5const修飾指針指針是如此的奇妙,通過傳遞指針值,函數(shù)獲得了對外界變量空間的訪問權(quán)限,尤其為其創(chuàng)造了修改空間中數(shù)據(jù)的機會.如何通過指針只能做讀取,而不能寫入?用const修飾加const的時機:遵循最小特權(quán)原則,對于函數(shù)的參數(shù),在能滿足函數(shù)處理數(shù)據(jù)的要求的前提下,給予它最小的權(quán)限const修飾參數(shù)的四種方式指向非常量的非常量指針調(diào)用:intx;f(&x);voidf(int*ptr){

可以通過引用改變x的值;//*ptr=3;

可以改變ptr本身的值;//ptr++;};

此時,x是變量,ptr也是變量const修飾參數(shù)的四種方式指向常量數(shù)據(jù)的非常量指針調(diào)用:intx;f(&x)voidf(constint*ptr){

不可以通過引用改變x的值;//*ptr=3;

可以改變ptr本身的值;//ptr++;};

此時,x是變量,ptr也是變量,但不可以通過對ptr的引用運算而修改x的值const修飾參數(shù)的四種方式指向非常量的常量指針調(diào)用:intx;f(&x)voidf(int*constptr){

可以通過引用改變x的值;//*ptr=3;

不可以改變ptr本身的值;//ptr++;};

此時,ptr是常量,x可以通過ptr的引用方式來改動const修飾參數(shù)的四種方式指向常量的常量指針調(diào)用:intx;f(&x)voidf(constint*constptr){

不可以通過引用改變x的值;//*ptr=3;

不可以改變ptr本身的值;//ptr++;};

此時,ptr是變量,ptr所指的空間中的值也不能通過它來改變sizeof函數(shù)sizeof(類型名)返回該數(shù)據(jù)類型單個元素所占的字節(jié)數(shù)sizeof數(shù)組名返回該數(shù)組所占的字節(jié)數(shù)注意:intarray[10];cout<<sizeofarray<<endl;//返回10*4即40但voidf(int*p,intlen){cout<<sizeofp<<endl;}

調(diào)用f(array,10);//輸出4,即一個指針變量占據(jù)的空間,

而非數(shù)組array占據(jù)的空間8.6指針與函數(shù)1.使用指針修改函數(shù)參數(shù)但在某些應(yīng)用中確實需要改變實際參數(shù)的值。例如,我們經(jīng)常需要修改兩個變量的值,希望有個函數(shù)可以實現(xiàn)此功能。要解決此問題可以采用指針作為參數(shù)。指針作為函數(shù)參數(shù)例子#include<iostream.h>voidswap(int*,int*);voidmain(){inta=3,b=8;cout<<"a="<<a<<",b="<<b<<endl;swap(&a,&b);cout<<"afterswapping...\n";cout<<"a="<<a<<",b="<<b<<endl;}voidswap(int*x,int*y){inttemp=*x;*x=*y;*y=temp;}運行結(jié)果:a=3,b=8afterswapping...a=8,b=3棧30067:f0900067:f092返回地址38swaptempyx0067:F090b0067:F092amain指針傳遞步驟把函數(shù)參數(shù)聲明為指針在函數(shù)體內(nèi)使用間接訪問指針當(dāng)調(diào)用函數(shù)時,把地址作為參數(shù)傳遞指針函數(shù)返回指針的函數(shù)稱為指針函數(shù)//**********************//**ch8_14.cpp**//**********************#include<iostream.h>int*getInt(char*str)//指針函數(shù){intvalue=20;cout<<str<<endl;return&value;//warning:將局部變量的地址返回是不妥的}voidsomefn(char*str){inta=40;cout<<str<<endl;}voidmain(){int*pr=getInt("inputavalue:");//賦值取自返回的指針值cout<<*pr<<endl;//第一次輸出*prsomefn("Itisuncertain.");cout<<*pr<<endl;//第二次輸出*pr}8.7字符數(shù)組字符串:

是可以被當(dāng)作一個單元來處理的一系列字符從存儲方式上看:第一種解釋:特殊的一維字符數(shù)組

charstr[size];

第二種解釋:指向字符的指針char*cptr;

即:通過指向字符串第一個字符的指針來訪問該字符串.一個字符串的值就是它的第一個字符的地址串的結(jié)束符‘\0’

inta[3]={1,2,3}chars[3]={‘a(chǎn)’,’b’,’\0’}s的實際長度為2,但必須分配2+1個空間,多余一個空間用來存放’\0’

串是以’\0’為結(jié)束符的一維字符數(shù)組空字符串沒有任何字符,只有’\0’‘a(chǎn)’與”a”‘a(chǎn)’字符常量,只需要1個字節(jié)存放“a”串常量,需要2個字節(jié)存放

aa\0串的初始化方法一:chars[4]={‘a(chǎn)’,’b’,’c’,’\0’};方法二:chars[]={‘a(chǎn)’,’b’,’c’,’\0’};串的初始化(續(xù))為常量字符串初始化串方式三:chars[]=“abc”;方式四:constchar*p=“abc”;方式四首先在內(nèi)存中為“abc”分配空間并將值寫入,最后將該空間的起始地址賦給指針變量P要點輸出字符指針就是輸出字符串。輸出字符指針的間接引用,就是輸出單個字符。兩個字符串的比較是地址的比較,同理,兩個數(shù)組名、函數(shù)指針的比較也是地址的比較。常見錯誤忘記給串尾加上\0;程序員有責(zé)任確保為串分配足夠空間;

chars[3];strcpy(s,”abc“);‘a(chǎn)’與”a”用錯位置charw[100];scanf(“%s”,&w)8.8指針函數(shù)一個數(shù)組中若每個元素都是一個指針如char*proname[]={"fortran","C","C++"}f

or...........C'\0'C++'\0'0088:22510088:22590088:225Bproname'\0'字符數(shù)組的內(nèi)存表示指向指針的指針指針數(shù)組名是指向指針的指針(即二級指針)例如char*pc[]={"a","b","c"};char**ppc;ppc=pc;//ok//**********************//**ch8_20.cpp**//**********************#include<iostream.h>voidPrint(char*[],int);voidmain(){char*pn[]={"Fred","Barney","Wilma","Betty"};intnum=sizeof(pn)/sizeof(char*);Print(pn,num);}voidPrint(char*arr[],intlen){for(inti=0;i<len;i++)//輸出各字符串cout<<(int)arr[i]<<""http://輸出字符串地址<<arr[i]<<endl;//輸出字符串}Print(pn,num);}voidPrint(char*arr[],intlen){for(inti=0;i<len;i++)//輸出各字符串cout<<(int)arr[i]<<""http://輸出字符串地址<<arr[i]<<endl;//輸出字符串}運行結(jié)果:4202628fred4202633baraney4202640wilma4202646bettyarr是指向字符指針的指針,所以*(arr+i)就是arr[i];arr是指針而不是數(shù)組;輸出字符指針就是輸出字符串8.10函數(shù)指針指向函數(shù)的指針:

指針指向內(nèi)存中函數(shù)代碼存放的起始地址函數(shù)指針和其它指針一樣也可以傳遞給函數(shù)、從函數(shù)中返回、賦給其他的函數(shù)指針、存儲在數(shù)組中。函數(shù)指針的聲明:

如int(*func)(int,int)

類型名(*指針變量名)(形式參數(shù)列表)函數(shù)指針通過函數(shù)指針調(diào)用函數(shù):

如(*compare)(3+5,x)其中x是int類型

(*指針變量名)(實際參數(shù)列表)函數(shù)指針的內(nèi)在區(qū)別

不作函數(shù)調(diào)用的數(shù)組名是地址,同樣,不作函數(shù)調(diào)用的函數(shù)名也是地址,所以可賦值給函數(shù)指針。不同的參數(shù),不同的返回類型,構(gòu)成不同的函數(shù)。intfn1(charx,chary);int*fn2(charx,chary);intfn3(inta);int(*fp1)(chara,charb);int(*fp2)(ints);fp1=fn1;//OK,fn1函數(shù)與指針fp1指向的函數(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論