




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第八章指針和基于指針的字符串指針引用調(diào)用數(shù)組與指針函數(shù)指針基于指針的字符串總結(jié)指針的概念指針就是把地址作為數(shù)據(jù),把地址存儲(chǔ)在內(nèi)存中指針變量:存儲(chǔ)地址的變量變量的指針:當(dāng)一個(gè)變量存儲(chǔ)另一個(gè)變量的地址時(shí),那我們說它就是那個(gè)變量的指針100021000如在某一程序中定義了intx;X=2;如系統(tǒng)給x分配的空間是1000號單元,則指向x的指針是另一個(gè)變量,該變量中存放的數(shù)據(jù)為1000指針變量的定義如何定義一個(gè)變量為指針變量?類型標(biāo)識符*指針變量;如:int*a;double*b; char*c;指針運(yùn)算符指針運(yùn)算符包括兩個(gè)一元運(yùn)算符:&,*
形式:&變量名如:&y返回變量y在內(nèi)存中的地址&運(yùn)算符的意義:
變量所占據(jù)的內(nèi)存地址由系統(tǒng)分配,因?yàn)槲覀儾恢老到y(tǒng)分配給變量的真正地址是什么。如何獲得該地址,并將它入一個(gè)指針變量中?用地址運(yùn)算符“&”
解決。如:a=&x;&運(yùn)算符后面不能跟常量或表達(dá)式。如&2
是沒有意義的,&(m*n+p)。也是沒有意義的指針運(yùn)算符指針運(yùn)算符包括兩個(gè)一元運(yùn)算符:&,*
形式:*指針變量名如:*a
返回指針變量intPtr中存儲(chǔ)的地址所指向空間中的值*運(yùn)算符的意義:
如何用指針變量處理和改變它所指向的單元的值?用引用運(yùn)算符“*”解決。如*a
表示的是a
指向的這個(gè)單元的內(nèi)容。因此*也稱為間接引用或間接運(yùn)算符在對a
使用引用運(yùn)算之前,必須先對a
賦值指針的定義及使用指針變量可以指向不同的變量。如上例中intp指向x,我們可以通過對intp的重新賦值改變指針的指向。如果想讓intp指向y,只要執(zhí)行intp=&y就可以了。這時(shí),intp與x無任何關(guān)系。同類的指針變量之間可相互賦值,表示二個(gè)指針指向同一內(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;//指針本身的地址}運(yùn)行結(jié)果:580x0067fe000x0067fe00580x0067fe00指針的初始化指針在使用前必須初始化。僅和別的變量一樣定義指針,不初始化是一個(gè)比較普通的錯(cuò)誤。沒有初始化的指針可能指向任意地址,對這些指針作操作可能會(huì)導(dǎo)致程序錯(cuò)誤。NULL是一個(gè)特殊指針值,稱為空指針。它的值為0。它可被用來初始化一個(gè)指針,表示不指向任何地址。8.2指針的運(yùn)算數(shù)組名本身實(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++){//計(jì)算數(shù)組元素之和sum+=*iPtr;iPtr++;}cout<<"sumis"<<sum<<endl;}
運(yùn)行結(jié)果為sumis90指針的運(yùn)算都是以數(shù)據(jù)類型為單位展開的,且只有加減法使用于指針運(yùn)算。對int指針加6,實(shí)際上加了12;對char指針加6,實(shí)際上加了6;對float指針加6,實(shí)際上加了24;.............8.3數(shù)組與指針在C++中,數(shù)組與指針是密切相關(guān)的,兩者幾乎可以交換使用.數(shù)組名代表數(shù)組的起始地址,因此一個(gè)數(shù)組名就是一個(gè)常量指針.數(shù)組與指針不同之處
1、系統(tǒng)內(nèi)存空間分配不同
2、數(shù)組名是常量指針,不能修改它的值。數(shù)組與指針——相同之處#defineN5;inta[N],*p;假設(shè)300是a的基地址如下操作是允許的:p=a;等價(jià)于p=&a[0]此時(shí)p=300;p=a+1;等價(jià)于p=&a[1]此時(shí)p=304;數(shù)組與指針——不同之處#defineN5;inta[N],*p;假設(shè)300是a的基地址以下操作是不允許的:
a=p;a++;a+=3;a是常量指針,不能修改它的值。運(yùn)行并分析Fig.8.20,Fig.8.21指針的運(yùn)算#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);//元素個(gè)數(shù)for(n=0;n<size;n++)//方法1sum1+=iArray[n];iPtr=iArray;for(n=0;n<size;n++)//方法2sum2+=*iPtr++;iPtr=iArray;//此句不能省略,因?yàn)榉椒?修改了iPtrfor(n=0;n<size;n++)//方法3sum3+=*(iPtr+n);iPtr=iArray;//此句可以省略,因?yàn)榉椒?沒有修改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;}運(yùn)行結(jié)果:1741741741741748.4堆內(nèi)存分配堆是內(nèi)存空間。堆允許程序在運(yùn)行時(shí),申請某個(gè)大小的內(nèi)存空間。指針數(shù)組數(shù)組是同種數(shù)據(jù)類型數(shù)據(jù)的集合,該類型當(dāng)然也可以是指針.指針數(shù)組:數(shù)組的每個(gè)元素都是指針如:char*a[4];charch1,ch2,ch3,ch4
a[0]=&ch1;a[1]=&ch2;a[2]=&che3;a[3]=&ch4;指針數(shù)組
實(shí)際應(yīng)用中,常見的做法是字符串?dāng)?shù)組:constchar*suit[4]={“Hearts”,“Diamonds”,“Clubs”,“Spades”}
字符串?dāng)?shù)組中的每一項(xiàng)都是一個(gè)字符串,實(shí)際指向相應(yīng)字符串的第一個(gè)字符的指針(地址)
動(dòng)態(tài)內(nèi)存分配#include<alloc.h>void*malloc(size_t,size_t);當(dāng)系統(tǒng)無法分配所申請的空間時(shí),返回值為NULLmalloc()分配的存儲(chǔ)空間沒有被初始化,開始值無用動(dòng)態(tài)分配空間分配n個(gè)int需要的空間int*p;p=(int*)malloc(n*sizeof(int));強(qiáng)制類型轉(zhuǎn)換釋放空間voidfree(void*ptr);函數(shù)用途:釋放malloc函數(shù)申請的空間強(qiáng)烈建議:由malloc申請的內(nèi)存空間在程序運(yùn)行過程中不會(huì)自動(dòng)釋放,當(dāng)申請的空間不再需要使用的話,程序員必須free函數(shù)釋放相應(yīng)的空間。new與deletenew與delete是c++專有的操作符,不用頭文件聲明new類似于函數(shù)malloc()分配堆內(nèi)存,可以帶初始化值表或單元個(gè)數(shù),new的返回值是具有操作數(shù)之?dāng)?shù)據(jù)類型的指針返回delete類似于函數(shù)free(),釋放堆內(nèi)存,delete的操作數(shù)是new返回的指針,當(dāng)返回的是new分配的數(shù)組時(shí),應(yīng)帶[]//*********************//**ch8_9.cpp**//*********************#include<iostream.h>//#include<alloc.h>//無須頭文件voidmain(){intarraysize;//元素個(gè)數(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ù)的機(jī)會(huì).如何通過指針只能做讀取,而不能寫入?用const修飾加const的時(shí)機(jī):遵循最小特權(quán)原則,對于函數(shù)的參數(shù),在能滿足函數(shù)處理數(shù)據(jù)的要求的前提下,給予它最小的權(quán)限const修飾參數(shù)的四種方式指向非常量的非常量指針調(diào)用:intx;f(&x);voidf(int*ptr){
可以通過引用改變x的值;//*ptr=3;
可以改變ptr本身的值;//ptr++;};
此時(shí),x是變量,ptr也是變量const修飾參數(shù)的四種方式指向常量數(shù)據(jù)的非常量指針調(diào)用:intx;f(&x)voidf(constint*ptr){
不可以通過引用改變x的值;//*ptr=3;
可以改變ptr本身的值;//ptr++;};
此時(shí),x是變量,ptr也是變量,但不可以通過對ptr的引用運(yùn)算而修改x的值const修飾參數(shù)的四種方式指向非常量的常量指針調(diào)用:intx;f(&x)voidf(int*constptr){
可以通過引用改變x的值;//*ptr=3;
不可以改變ptr本身的值;//ptr++;};
此時(shí),ptr是常量,x可以通過ptr的引用方式來改動(dòng)const修飾參數(shù)的四種方式指向常量的常量指針調(diào)用:intx;f(&x)voidf(constint*constptr){
不可以通過引用改變x的值;//*ptr=3;
不可以改變ptr本身的值;//ptr++;};
此時(shí),ptr是變量,ptr所指的空間中的值也不能通過它來改變sizeof函數(shù)sizeof(類型名)返回該數(shù)據(jù)類型單個(gè)元素所占的字節(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,即一個(gè)指針變量占據(jù)的空間,
而非數(shù)組array占據(jù)的空間8.6指針與函數(shù)1.使用指針修改函數(shù)參數(shù)但在某些應(yīng)用中確實(shí)需要改變實(shí)際參數(shù)的值。例如,我們經(jīng)常需要修改兩個(gè)變量的值,希望有個(gè)函數(shù)可以實(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;}運(yùn)行結(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ù)稱為指針函數(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)作一個(gè)單元來處理的一系列字符從存儲(chǔ)方式上看:第一種解釋:特殊的一維字符數(shù)組
charstr[size];
第二種解釋:指向字符的指針char*cptr;
即:通過指向字符串第一個(gè)字符的指針來訪問該字符串.一個(gè)字符串的值就是它的第一個(gè)字符的地址串的結(jié)束符‘\0’
inta[3]={1,2,3}chars[3]={‘a(chǎn)’,’b’,’\0’}s的實(shí)際長度為2,但必須分配2+1個(gè)空間,多余一個(gè)空間用來存放’\0’
串是以’\0’為結(jié)束符的一維字符數(shù)組空字符串沒有任何字符,只有’\0’‘a(chǎn)’與”a”‘a(chǎn)’字符常量,只需要1個(gè)字節(jié)存放“a”串常量,需要2個(gè)字節(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要點(diǎn)輸出字符指針就是輸出字符串。輸出字符指針的間接引用,就是輸出單個(gè)字符。兩個(gè)字符串的比較是地址的比較,同理,兩個(gè)數(shù)組名、函數(shù)指針的比較也是地址的比較。常見錯(cuò)誤忘記給串尾加上\0;程序員有責(zé)任確保為串分配足夠空間;
chars[3];strcpy(s,”abc“);‘a(chǎn)’與”a”用錯(cuò)位置charw[100];scanf(“%s”,&w)8.8指針函數(shù)一個(gè)數(shù)組中若每個(gè)元素都是一個(gè)指針如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;//輸出字符串}運(yùn)行結(jié)果:4202628fred4202633baraney4202640wilma4202646bettyarr是指向字符指針的指針,所以*(arr+i)就是arr[i];arr是指針而不是數(shù)組;輸出字符指針就是輸出字符串8.10函數(shù)指針指向函數(shù)的指針:
指針指向內(nèi)存中函數(shù)代碼存放的起始地址函數(shù)指針和其它指針一樣也可以傳遞給函數(shù)、從函數(shù)中返回、賦給其他的函數(shù)指針、存儲(chǔ)在數(shù)組中。函數(shù)指針的聲明:
如int(*func)(int,int)
類型名(*指針變量名)(形式參數(shù)列表)函數(shù)指針通過函數(shù)指針調(diào)用函數(shù):
如(*compare)(3+5,x)其中x是int類型
(*指針變量名)(實(shí)際參數(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)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025專賣店、超市、商場員工聘用合同范本
- 庫房出租合同模板二零二五年
- 土地流轉(zhuǎn)居間合同書二零二五年
- 買房蓋房租房合同樣本
- 二零二五勞動(dòng)合同勞動(dòng)合同簽訂原則
- 系統(tǒng)培訓(xùn)方案模板
- 買期房抵押合同樣本
- 居間廠房轉(zhuǎn)讓合同二零二五年
- 二零二五代簽合同授權(quán)的委托書
- 投資收益分配股權(quán)轉(zhuǎn)讓定金協(xié)議二零二五年
- 湖南省張家界市慈利縣2023-2024學(xué)年八年級下學(xué)期期中考試物理試題
- 金屬非金屬地下礦山監(jiān)測監(jiān)控系統(tǒng)建設(shè)規(guī)范
- 2024年蘇州市軌道交通集團(tuán)有限公司招聘筆試參考題庫附帶答案詳解
- 新概念英語第2冊課文(完整版)
- 水培吊蘭的養(yǎng)殖方法要領(lǐng)
- 動(dòng)物的遷徙行為與地球生態(tài)系統(tǒng)
- 【小學(xué)心理健康教育分析國內(nèi)外文獻(xiàn)綜述4100字】
- 校園金話筒大賽(臨沂賽區(qū))策劃書
- 正確使用文丘里面罩
- 破碎錘施工方案
- 2023年10月自考00161財(cái)務(wù)報(bào)表分析(一)試題及答案含評分標(biāo)準(zhǔn)
評論
0/150
提交評論