




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、本章主要內(nèi)容:指針的定義及初始化指針的指針指針的運(yùn)算指針與數(shù)組指針數(shù)組和數(shù)組指針指針與字符串指針與函數(shù)1.1 指針的概述指針是語言中廣泛使用的一種數(shù)據(jù)類型。運(yùn)用指針編程是C語言最主要的風(fēng)格之一。利用指針變量可以表示多種數(shù)據(jù)結(jié)構(gòu),能方便地使用數(shù)組和字符串,并能像匯編一樣處理內(nèi)存地址。正因?yàn)樗撵`活多變,初學(xué)者往往會感到很困惑。通過本章的學(xué)習(xí),我們要玩轉(zhuǎn)指針。利用指針編寫程序,跟數(shù)組結(jié)合使用等等。1.2 地址與指針在計(jì)算機(jī)中,所有的數(shù)據(jù)都是存放在存儲器中的,一般把存儲器的一個(gè)字節(jié)稱為一個(gè)內(nèi)存單元。不同的數(shù)據(jù)類型占用的內(nèi)存單元是不同的。為了快速、準(zhǔn)確的訪問這些內(nèi)存單元,計(jì)算機(jī)為每一個(gè)內(nèi)存單元進(jìn)行編號
2、,內(nèi)存單元的編號也就是內(nèi)存單元的地址。C語言中,把這個(gè)地址叫做指針。1.3 指針的定義指針是一種數(shù)據(jù)類型,基于該類型聲明的變量稱為指針變量,該變量存放的是內(nèi)存中的某個(gè)地址,和普通的變量一樣,在使用指針變量之前應(yīng)先對指針變量進(jìn)行聲明:類型 * 指針變量名;/如 int* pNum;“*”表示語句聲明的是一個(gè)指針變量,類型指定了指針?biāo)傅膬?nèi)存單元的數(shù)據(jù)類型??梢詫nt*理解成一種復(fù)合類型,是指向int型數(shù)據(jù)的指針。應(yīng)當(dāng)注意,下面的語句:int * pNum1,pNum2;聲明了一個(gè)指針(pNum1)和一個(gè)int型變量(pNum2),在一次性聲明多個(gè)指針時(shí),每個(gè)指針變量名前都要加*,int *pN
3、um1,*pNum2;便一次性聲明了兩個(gè)指針變量。通過sizeof可以計(jì)算出指針變量所占用的內(nèi)存單元始終是4個(gè)字節(jié)。也就是說任何類型的指針變量都只占用4個(gè)字節(jié)的內(nèi)存空間。如:int *pi;char *pch; double *pf; 則:sizeof(pi)=sizeof(pch)=sizeof(pf)=4(參見代碼Example1)另外,修改指針變量的值并不會影響到指針?biāo)赶虻淖兞康闹?。如:int i = 8; int j = 9; int *pi = &i; pi = &j; i的值始終是8沒有改變。1.4 初始化指針聲明指針變量時(shí),C并不會自動(dòng)對其進(jìn)行初始化,這時(shí),指針變量的值是隨機(jī)的
4、,在內(nèi)存中亂指一氣,此時(shí),通過指針間接訪問所指的內(nèi)存區(qū)域是十分危險(xiǎn)的,因?yàn)槟阃耆恢雷约涸谧鲂┦裁?。通過取地址符(&)給指針變量賦值是個(gè)有效的手段,實(shí)際上,可以在聲明一個(gè)指針變量的同時(shí)完成其初始化。int num=1; int *pN=#上述語句聲明了一個(gè)指向int型變量的指針pN,并用num在內(nèi)存中的地址對其賦值。在使用指針前,一般要對其進(jìn)行初始化(在聲明的同時(shí)初始化或賦值),使其有一個(gè)確定合適的值,對于無處可指的指針變量,也要將其初始化為NULL(即0,空指針)。如:int *pa = NULL;1.5 指針的指針指針變量也是變量,占據(jù)一定的內(nèi)存空間,有地址,因此可以用一個(gè)指針指
5、向它,這稱為指向指針的指針,或二級指針。可已通過“*”聲明一個(gè)二級指針,如double num; double* pN=# double* ppN=&pN;上面的指針可以看成指向double*變量類型的指針,若有需要,還可以定義三級、甚至更高級的指針。1.6 指針之間相互賦值C允許同類型的指針間的賦值,如圖4.2所示,pN1和pN2是兩個(gè)相同類型的指針,執(zhí)行“pN2=pN1;”這樣一個(gè)賦值操作后,pN1和pN2指向同樣的地址,也就是說,兩個(gè)指針指向同一個(gè)內(nèi)存單元,對*pN2的任何改動(dòng)都會影響*pN1的值,反之亦然(參見代碼Example2)1.7 指針的運(yùn)算C語言中指針?biāo)苓M(jìn)行的運(yùn)算是
6、十分有限的,通常有以下幾種:指針與整數(shù)的加減(包括指針的自增和自減)、同類型指針間的比較、同類型的指針相減。指針與整數(shù)的加減:指針與整數(shù)的加減表示指針在內(nèi)存中向下或向上移動(dòng)整數(shù)個(gè)單位。該單位是多少個(gè)內(nèi)存字節(jié)取決于指針?biāo)缸兞康念愋?。如:short類型的每次移動(dòng)2個(gè)字節(jié),double類型的每次移動(dòng)8個(gè)字節(jié)。將指針變量+1,其地址增加的值等于所指向的類型占用的內(nèi)存字節(jié)數(shù)。公式:指針變量新值=指針變量當(dāng)前值+N*指針?biāo)割愋驼加玫膬?nèi)存字節(jié)數(shù)。(參見代碼Example3)同類型指針的比較:兩個(gè)指針的比較是兩個(gè)指針保存的地址數(shù)值大小的比較,如:p1的值為0x12345678,p2的值為0x1234567
7、9,則p1p2。同類型的指針相減:兩個(gè)相同類型指針相減,返回值是個(gè)整數(shù),其值為:(指針1的值-指針2的值)/ 指針?biāo)赶蜃兞康念愋退純?nèi)存字節(jié)數(shù)。(參見代碼Example4)1.8 指針與數(shù)組指針與一維數(shù)組:在C語言中,指針和數(shù)組的關(guān)系非常密切,其原因在于凡是能用數(shù)組下標(biāo)完成的操作都可以用指針來實(shí)現(xiàn)??梢酝ㄟ^數(shù)組的下標(biāo)唯一確定數(shù)組中的某個(gè)元素,這種訪問方式稱為下標(biāo)法。由于數(shù)組的每個(gè)元素都相當(dāng)于一個(gè)相應(yīng)類型的變量,指針變量可以指向一般的變量,當(dāng)然也可以指向數(shù)組中的元素。而且數(shù)組中的各個(gè)元素是按順序連續(xù)的存放在內(nèi)存中,因此,我們只要知道一個(gè)數(shù)組的首地址(即第一個(gè)元素的地址),然后依次往下移動(dòng),就能
8、找到該數(shù)組的所有元素。(參見代碼Example5)C語言中,獲取數(shù)組首地址的方法有兩種:第一個(gè)元素的地址:p = &a0;數(shù)組名,數(shù)組名也代表數(shù)組的首地址:p = a;P指向數(shù)組的首地址之后,p+1表示數(shù)組元素a1的地址,p+i表示數(shù)組元素ai的地址,因此我們可以通過*(p+i)來訪問數(shù)組元素ai;這種訪問方法叫指針法。假設(shè):int a10 = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10; int *p = a;那么獲得數(shù)組下標(biāo)為i的元素的地址:a+i p+i &ai訪問數(shù)組下標(biāo)為i的元素:ai *(a+i) pi *(p+i)注意點(diǎn):數(shù)組名和指針變量本身并不完全等同,數(shù)組名代
9、表的是一個(gè)地址常量,是數(shù)組的首地址,是不能改變的,而指針變量的值是可以改變的,它可以指向數(shù)組的任意一個(gè)元素的地址。因此語句p+; +p; p+=5;等等都是合法的,而a+; +a; a+=5;等都是非法的。(參見代碼Example6)指針與二維數(shù)組:在C語言中,二維數(shù)組是按照行優(yōu)先的規(guī)律轉(zhuǎn)換成一維數(shù)組存放在內(nèi)存中。例如:int a43; int *p = &a00;或int *p = a0 則二維數(shù)組在內(nèi)存中的存儲順序及地址關(guān)系如圖:a表示二維數(shù)組的首地址,a0表示第0行元素的首地址,a1表示第1行元素的首地址,a2表示第二行元素的首地址,a3表示第3行元素的首地址。由此歸納:a+i:二維數(shù)組
10、第i行的首地址。 ai*(a+i):二維數(shù)組第i行第0列的地址。&ai0 或 ai*(a+i)+j:二維數(shù)組第i行第j列的地址 &aij 或 ai + j*(*(a+i):二維數(shù)組第i行第0列的值。ai0 或 *ai*(*(a+i) + j):二維數(shù)組第i行第j列的值。aij或 *(ai + j)由ai*(a+i)可以將二維數(shù)組進(jìn)行轉(zhuǎn)換,將數(shù)組的一個(gè)拆開就是aij (*(a+i)j*(*(a+i) +j)如果一個(gè)指針*p = a0.則可以通過*(p + (i*每行列數(shù)+j)獲得第i行、第j列的值(即aij),這可以根據(jù)上面的對照存儲表得出。(參見代碼Example7)1.9 數(shù)組指針與指針數(shù)組
11、數(shù)組指針:指向由n個(gè)元素組成的一維數(shù)組的指針。(趨向于指針)定義格式:數(shù)據(jù)類型 (*指針變量)n; ()不能缺少。n必須與二維數(shù)組aij的j相同。賦值方式:int a34; int (*p)4; p = a; 或 int (*p)4 = a;定義的時(shí)候初始化。數(shù)組指針通常和二維數(shù)組名等價(jià)。訪問方式:pij 或 *(p+i)j 或 *(*(p+i) + j)指針數(shù)組:數(shù)組的每一個(gè)元素都是一個(gè)指針變量。(趨向于數(shù)組)定義格式:數(shù)據(jù)類型 *數(shù)組名n; 所有元素都必須是同種存儲類型和指向相同數(shù)據(jù)類型。賦值方式:int a34; int *pb3 = a0, a1, a2; 指針數(shù)組通常和指針的指針等價(jià)
12、。訪問方式:pij 或 *(p+i)j 或 *(*(p+i) + j)指針數(shù)組主要用于處理若干個(gè)字符串。如:char * name = “Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”;這樣name0就指向”Sunday” (參見代碼Example8)1.10 指針與字符串C語言存儲訪問一個(gè)字符串有兩種方式:字符數(shù)組、字符指針。char str = “how are you?”; char *pStr = “how are you?”;其中后者為文字常量區(qū),內(nèi)容不能被修改。1.11 指針與函
13、數(shù)前面我們講過C語言中函數(shù)傳遞有2中方式:值傳遞和地址傳遞。其中地址傳遞就是指針。此時(shí)形參的改變會影響是實(shí)參的變化。數(shù)組名作為函數(shù)的參數(shù),它可以作為函數(shù)的形參和實(shí)參,本質(zhì)上還是地址傳遞。以下四種情況都會引起形參和實(shí)參一起變化形參和實(shí)參都是數(shù)組名形參是數(shù)組名,實(shí)參是指針變量形參是指針變量,實(shí)參是數(shù)組名形參和實(shí)參都是指針變量(參見代碼Example9)1.12 動(dòng)態(tài)內(nèi)存分配C語言中動(dòng)態(tài)分配和釋放內(nèi)存是利用函數(shù)malloc()和free()來實(shí)現(xiàn)的.在#include 頭文件中函數(shù)原型:void* malloc(int size); /表示動(dòng)態(tài)分配size個(gè)字節(jié)的內(nèi)存空間eg: char *pStr
14、 = (char*)malloc(20*sizeof(char);分配20個(gè)char類型內(nèi)存空間,總共20個(gè)字節(jié)eg: int *pNum = (char*)malloc(5 * sizeof(int); 分配5個(gè)int類型的內(nèi)存空間,總共20個(gè)字節(jié)void free(void*); /釋放內(nèi)存空間eg: free(pStr); free(pNum);因?yàn)閙alloc的返回值類型是void*,所以通常要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。注意:只有動(dòng)態(tài)分配內(nèi)存之后才能用free釋放,對于下面這種情況:int x = 5;int *px = &x;free(px);在這里,px不是動(dòng)態(tài)分配內(nèi)存,而是直接用一個(gè)已有
15、的地址賦給px,但是又用free進(jìn)行了釋放,所以會出現(xiàn)問題,不需要free(px);來釋放。C+中是利用運(yùn)算符new和delete來實(shí)現(xiàn)的。new是一個(gè)單目運(yùn)算符,操作數(shù)為一個(gè)類型名,返回值為指向操作數(shù)類型的指針。為一個(gè)變量分配動(dòng)態(tài)的內(nèi)存的基本格式為:類型類型* 指針變量名 = new 類型名;其中的“new 類型名”通知編譯器:需要開辟的內(nèi)存是用來存儲的值是什么類型,new操作符能根據(jù)這個(gè)類型名自動(dòng)計(jì)算要分配的存儲空間的大小。int* pNum = new int;舉例來說,上述代碼會在運(yùn)行時(shí)為一個(gè)int型數(shù)值分配內(nèi)存,聲明了指向int型的指針pNum,pNum初始為可以用動(dòng)態(tài)申請內(nèi)存的首地
16、址,因此,用指針pNum可訪問這塊內(nèi)存區(qū)域。 申請內(nèi)存的同時(shí)可對該區(qū)域進(jìn)行初始化,對基本的變量類型,下列語句是合法的:int* pNum = new int(8);另外還可以用new分配數(shù)組:數(shù)據(jù)類型 * 指針變量名 = new 類型名n; 通知編譯器動(dòng)態(tài)開辟足以存儲n個(gè)類型為“類型名”的元素的連續(xù)內(nèi)存空間(數(shù)組),并聲明“指針變量名”,指向數(shù)組的第一個(gè)元素。使用new分配內(nèi)存的幾種形式舉例如下:int *p1 = new int;int *p2 = new int(7); /這種是分配一個(gè)int空間,初始化為7int *p3 = new int7; /這種是分配7個(gè)int空間,沒有初始化用n
17、ew動(dòng)態(tài)分配內(nèi)存之后,要用delete來釋放。使用delete釋放內(nèi)存的幾種形式舉例如下:delete p1;delete p3; /釋放數(shù)組的時(shí)候,要加上。注意:不要使用或釋放已經(jīng)釋放的內(nèi)存塊。例如下面的這個(gè)例子:int* pN1 = new int(8);/申請一個(gè)int型大小的動(dòng)態(tài)內(nèi)存,初始化為8int* pN2 = pN1;/指針間的賦值printf(%dn, *pN1);delete pN2;/釋放掉pN2指向的動(dòng)態(tài)內(nèi)存printf(%dn, *pN1);delete pN1;/釋放掉pN1指向的動(dòng)態(tài)內(nèi)存, 出現(xiàn)錯(cuò)誤在這里pN1和pN2指向的內(nèi)存是同一塊,釋放一次之后,該內(nèi)存塊已經(jīng)釋
18、放,再釋放就會出現(xiàn)錯(cuò)誤。malloc/free 和 new/delete的異同點(diǎn):malloc和free一般用于語言中的,而且它們是函數(shù)。delete和new通常用于C+中,它們是運(yùn)算符。malloc和new相同點(diǎn):都能動(dòng)態(tài)的分配內(nèi)存空間不同點(diǎn):new分配內(nèi)存空間時(shí)會自動(dòng)的調(diào)用構(gòu)造函數(shù)對成員變量進(jìn)行初始化,而malloc不會調(diào)用構(gòu)造函數(shù)。free和delete相同點(diǎn):都能釋放動(dòng)態(tài)分配的內(nèi)存空間不同點(diǎn):delete釋放內(nèi)存空間時(shí)會自動(dòng)調(diào)用該類的析構(gòu)函數(shù),而free不會。1.13 指針常量和常量指針int i = 1; int j = 2;/指針常量(即指針指向的內(nèi)容是常量,不能被修改)const int *pa = &i;/const放在指針之前,有什么作用?保護(hù)指針指向的內(nèi)存塊不能被修改*pa = 7; /非法pa = &j; /合法/常量指針(指針本身是常量,不能再指向其它的地址)int* const pb = &i;/const放在指針之后,有什么作用?保護(hù)指針變量對應(yīng)的內(nèi)存塊不能改變*pb = 7; /合法pb = &j; /非法如果是下面這種情況:const int * const pa = &i;/第一個(gè)c
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年江蘇省南京十三中物理高一下期末考試試題含解析
- 2025年河北省唐山市十一中物理高一第二學(xué)期期末質(zhì)量檢測試題含解析
- 公司員工個(gè)人試用期工作總結(jié)
- 2025年浙江省金華市金華十校物理高一第二學(xué)期期末學(xué)業(yè)質(zhì)量監(jiān)測試題含解析
- 兒童影樓活動(dòng)策劃方案
- 保險(xiǎn)理賠年終工作總結(jié)
- 低碳環(huán)?;顒?dòng)總結(jié)
- 以上員工培訓(xùn)自我鑒定
- 盆腔乳糜囊腫護(hù)理課件
- 額顳葉癡呆的健康宣教
- GB/T 17213.1-2015工業(yè)過程控制閥第1部分:控制閥術(shù)語和總則
- 護(hù)理文件書寫原因魚骨圖
- 男友測試卷試題
- 10kV電氣試驗(yàn)方案
- 2022年干部基礎(chǔ)理論知識應(yīng)知必會試題-脫貧攻堅(jiān)與鄉(xiāng)村振興有效銜接專題100題
- 新生兒肺動(dòng)脈高壓
- 計(jì)算機(jī)硬件購銷合同
- 2019年GJB9001C-2017組織內(nèi)外部環(huán)境因素風(fēng)險(xiǎn)和機(jī)遇識別評價(jià)分析及應(yīng)對措施一覽表備用
- 氬氣安全周知卡
- 《印染行業(yè)定型機(jī)廢氣排放限量》DB330621T059-2022
- 太鋼不銹鋼產(chǎn)品介紹
評論
0/150
提交評論