版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第15章 再論指針,通過本章的學(xué)習(xí),需要掌握以下知識(shí)點(diǎn): 指針和數(shù)組的區(qū)別; 使用指針訪問數(shù)組,使用指針作為形參在函數(shù)中傳遞數(shù)組; 指針型數(shù)組和數(shù)組指針 使用指針訪問二維數(shù)組,使用指針作為形參在函數(shù)中傳遞二維數(shù)組; 使用字符指針來處理字符; 字符串?dāng)?shù)組和字符指針數(shù)組使用上的區(qū)別。,15.1 指針與數(shù)組,C語言中,指針和數(shù)組存在很多相似點(diǎn),是學(xué)習(xí)的難點(diǎn)。指針也可以用來指向數(shù)組或指向數(shù)組中的一個(gè)元素。當(dāng)指針指向一個(gè)數(shù)組時(shí),可以通過指針來訪問數(shù)組中的元素。本節(jié)將討論指針和數(shù)組組合而成的一些數(shù)據(jù)類型的概念和使用方法,以使讀者能夠理解指針和數(shù)組之間的區(qū)別。,15.1.1 指向數(shù)組元素的指針,指向數(shù)組元素
2、的指針是指一個(gè)指針變量,其指向的空間屬于一個(gè)數(shù)組中的某一個(gè)元素。例如,有一個(gè)int型array數(shù)組,其定義如下: int array10 = 0; 其第0個(gè)元素的地址為,15.1.1 指向數(shù)組元素的指針,這樣,指針變量p0便指向數(shù)組的第0個(gè)元素。由于數(shù)組的第0個(gè)元素的地址就是數(shù)組的地址。因此,該語句也等效于: int *p0 = array; 此時(shí),指針變量p0就是一個(gè)指向數(shù)組array的指針變量。類似地,指向其他數(shù)組元素的指針可以賦值如下: int * p1 = int * pi = 02printf(“%dn”, *(array + 2);/* 輸出array2的值 */ 上述語句中*(a
3、rray + 2)可以訪問array數(shù)組中的第2個(gè)元素。但是,數(shù)組元素型指針與數(shù)組變量在很多方面是不同的,如下面內(nèi)容所示。,15.1.3 數(shù)組元素型指針和數(shù)組變量,1值的可改變性不同 數(shù)組元素型指針的值是可變的,而數(shù)組變量的值是不能改變的。例如,數(shù)組元素型指針可以改變其指向的數(shù)組,以下行為是允許的。 int array_120 = 0; int array_220 = 0; int * p = array_1; p = array_2;/* 使指針指向另一個(gè)數(shù)組 */ p+;/* 使指針指向數(shù)組array_21 */ 但不能對數(shù)組做類似操作,以下行為是錯(cuò)誤的。 /* 接上 */ array_1
4、+;/* 試圖使array_1的內(nèi)容為array11,錯(cuò)誤用法 */ array_1 = array_2;/* 錯(cuò)誤用法 */,15.1.3 數(shù)組元素型指針和數(shù)組變量,2占用空間不同 數(shù)組元素型指針變量占用的空間都是固定的,由系統(tǒng)決定,32位機(jī)一般是4字節(jié)。而數(shù)組變量的占用空間則是由程序決定的,為數(shù)組容量與所存數(shù)據(jù)類型字長的積。例如,以上例子中,系統(tǒng)為數(shù)組變量array_1和array_2都分配(sizeof(int)20)個(gè)字節(jié),它們的內(nèi)容就是所有的數(shù)組元素。而系統(tǒng)只為指針變量p分配(sizeof(int)個(gè)字節(jié)(一般情況下,int型的字長等于系統(tǒng)地址的字長),其內(nèi)容為p指向的內(nèi)存空間的地址
5、,當(dāng)其指向數(shù)組array_1時(shí),其值為array_1的值,即數(shù)組首地址。,15.1.3 數(shù)組元素型指針和數(shù)組變量,3訪問方式不同 數(shù)組元素型指針訪問方式為間接訪問,而數(shù)組變量為直接訪問。使用數(shù)組變量時(shí),直接以數(shù)組變量名對應(yīng)的地址加上地址偏移量來找到目標(biāo)空間。而使用數(shù)組元素型指針,則先要從數(shù)組元素型指針名得到其對應(yīng)的地址,從該地址取得數(shù)組元素型指針的值,再從以該值為地址的內(nèi)存空間上獲取內(nèi)容。 實(shí)際上,索引法也被編譯系統(tǒng)轉(zhuǎn)換為數(shù)組名加上地址偏移量的形式。例如,a_inti運(yùn)行時(shí)等效于*(a_int + i)。這也是為什么數(shù)組的索引要從0開始編號(hào)的原因。,15.1.4 聲明數(shù)組形參的三種方式,當(dāng)數(shù)組
6、作為函數(shù)形參時(shí),數(shù)組的地址可以用做函數(shù)調(diào)用的實(shí)參。通過數(shù)組地址的傳遞,在函數(shù)內(nèi)便可以對該數(shù)組進(jìn)行訪問和修改。在C語言中,數(shù)組形參的聲明有3種基本形式,本節(jié)將對它們進(jìn)行逐一介紹,并比較各自的特點(diǎn)。在函數(shù)一章中已經(jīng)使用過含有數(shù)組形參的函數(shù),其聲明形式如下: void print_array(int arraySIZE);/* 形式1 */,15.1.4 聲明數(shù)組形參的三種方式,使用的函數(shù)調(diào)用語句一般為: #define SIZE 10 int arraySIZE = 0; print_array(array); 對于讀程序的人來說,形式1中聲明的array是一個(gè)可以存儲(chǔ)SIZE個(gè)int型數(shù)據(jù)的數(shù)組
7、。而對于編譯器而言,這個(gè)形參聲明則意味著array是一個(gè)指針。函數(shù)聲明中的SIZE實(shí)際上是毫無用處的,即使SIZE和真實(shí)的數(shù)組容量不用也是合法且執(zhí)行正常的,如下所示。 void print_array(int array1000); void print_array(int array1);,15.1.4 聲明數(shù)組形參的三種方式,以上兩個(gè)函數(shù)聲明都能正常執(zhí)行函數(shù)功能。寫成形式1唯一的好處是可以提高程序可讀性。它還可以寫成以下兩種形式: void print_array(int array);/* 形式2 */ void print_array(int * array); /* 形式3 */,1
8、5.1.5 使用三種聲明方式,從上面的范例中可以看到,對于編譯器,這三種形式的處理方式是完全一致,都會(huì)將array作為一個(gè)指向一個(gè)int型空間的指針變量來對待。但是,如果用來傳遞數(shù)組,那么形式2和形式3的信息顯然是不夠的,沒有辦法獲得該數(shù)組的容量,一般將形式2和形式3寫為如下形式: void print_array(int array, int size);/* 形式4 */ void print_array(int * array, int size); /* 形式5 */,15.1.6 調(diào)用含數(shù)組形參的函數(shù),調(diào)用含數(shù)組形參的函數(shù)時(shí),數(shù)組變量和數(shù)組元素型指針變量都可以作為實(shí)參。但不論是數(shù)組變
9、量和數(shù)組元素型指針變量,它們的值都是數(shù)組的首地址。調(diào)用函數(shù)時(shí),指針變量型數(shù)組的形參會(huì)被賦值為數(shù)組的首地址。C語言也允許傳遞其他數(shù)組元素的地址來實(shí)現(xiàn)部分?jǐn)?shù)組元素的訪問。,15.2 指針與二維數(shù)組,指針除了可以指向一維數(shù)組外,還可以指向二維數(shù)組。本節(jié)將討論指針與二維數(shù)組的關(guān)系和使用。與指針相關(guān)的二維數(shù)組的表示和使用比一維數(shù)組要復(fù)雜,而且二維數(shù)組的很多特性都由一維數(shù)組衍生而來。因此在學(xué)習(xí)本節(jié)前,應(yīng)當(dāng)好好掌握15.1節(jié)的內(nèi)容。,15.2.1 二維數(shù)組的地址,在前面關(guān)于二維數(shù)組的討論中,已經(jīng)知道C語言中的二維數(shù)組可以看做是元素為一維數(shù)組的一維數(shù)組,其在內(nèi)存中是轉(zhuǎn)換為一維數(shù)組的形式來存儲(chǔ)的。例如: int
10、 a32 = 1, 2, 11, 12, 21, 22; 那么,二維數(shù)組變量a可以看作是可存儲(chǔ)3個(gè)一維數(shù)組元素的一維數(shù)組,其中存儲(chǔ)的一維數(shù)組可以存儲(chǔ)2個(gè)int型數(shù)據(jù),如下圖所示(假設(shè)數(shù)組的首地址的16進(jìn)制值為001E)。,15.2.1 二維數(shù)組的地址,可以看到,該32數(shù)組在數(shù)組中的存儲(chǔ)形式上與含有6個(gè)元素的一維數(shù)組的存儲(chǔ)形式是一樣的。二維數(shù)組的首地址有很多種表示形式,如下所示。 將二維數(shù)組看作一個(gè)整體,其地址為 int * p = *a;/* 即,15.2.2 指針法訪問二維數(shù)組,雖然,p也會(huì)被賦值為數(shù)組的首地址,但由于a的類型為二維數(shù)組,這是不同類型間的賦值,是有風(fēng)險(xiǎn)的。編譯器會(huì)對此警告,V
11、isual Studio 2005環(huán)境下會(huì)有如下信息: warning C4047: initializing : int * differs in levels of indirection from int (*)4 注意:是將數(shù)組第0個(gè)元素的地址賦值給指針變量,而不是將數(shù)組首地址賦值給指針變量。數(shù)組第0個(gè)元素的地址值與數(shù)組首地址值相同,但是數(shù)組首地址有很多種表示形式,各種形式的數(shù)據(jù)類型不同,不可隨意混用。 由于32二維數(shù)組中第m行第n列元素可以表示為如下形式。 *(*a + i * 2 + j) 使用p代替*a,可得表達(dá)式如下: *(p + i * 2 + j),15.2.2 指針法訪問
12、二維數(shù)組,2. 使用一維數(shù)組型指針 與前一種方法相似,首先需要找出使用一維數(shù)組型指針變量表示所有數(shù)組元素的表達(dá)式。對于一維數(shù)組型指針,應(yīng)該將其賦值為數(shù)組第0個(gè)一維數(shù)組的地址。例如: int a32 = 1, 2, 11, 12, 21, 22; int (* p)2 = a;/* 即 int (*p)32 = /* a為二維數(shù)組, 其中的p為一維數(shù)組型指針,可以存儲(chǔ)COL_SIZE個(gè)int型數(shù)據(jù)。由于p的類型聲明中已有列數(shù)的信息,因此不必再包含列數(shù)。在fun函數(shù)中,二維數(shù)組中第m行第n列元素可以使用以下方式訪問: (*(p + m) + n),15.2.3 二維數(shù)組形參,3. 使用二維數(shù)組型指
13、針 還可以使用二維數(shù)組型指針作為形參來傳遞二維數(shù)組。例如有以下函數(shù)聲明: void fun(int (*p)ROW_SIZECOL_SIZE); 其中的p為二維數(shù)組型指針,指向ROW_SIZECOL_SIZE的int型數(shù)組。由于p的聲明中含有了數(shù)組的行數(shù)和列數(shù),因此不需要再包含行數(shù)和列數(shù)的參數(shù)。此時(shí)在fun函數(shù)中,可以使用如下表達(dá)式來訪問二維數(shù)組中第m行第n列元素: *(*p + m) + n 或 *(*p + m * COL_SIZE + n),15.2.3 二維數(shù)組形參,其中,*p表示二維數(shù)組中第0個(gè)一維數(shù)組的地址,*p表示二維數(shù)組第0個(gè)元素的地址。下面來分析如何得到以上兩種地址的表示。例
14、如,有如下代碼: 01int array32 = 021, 2, 0311, 12, 0421, 22 05; 06. 07fun(,15.3 指針與字符,字符處理是數(shù)據(jù)處理中十分常見的情況,使用指針變量來處理字符可以提供很多便利。本節(jié)先介紹字符指針的概念和使用,然后討論如何使用字符指針作為形參的問題,還將討論字符串?dāng)?shù)組和字符指針數(shù)組等內(nèi)容,最后會(huì)介紹如何使用字符指針數(shù)組來作為形參。,15.3.1 字符指針,字符指針就是指向字符型內(nèi)存空間的指針變量,一般的定義語句如下: char * p = NULL; 使用字符指針可以訪問字符數(shù)組和字符串。,15.3.1 字符指針,1. 訪問字符數(shù)組 只要將
15、字符指針賦值為字符數(shù)組的首地址便可以實(shí)現(xiàn)對字符數(shù)組的訪問。例如: char str = “Hello, world!”; char *p = str; 此時(shí),p被初始化為字符數(shù)組str的首地址,使用p可以訪問數(shù)組str的每一個(gè)元素。例如,打印str數(shù)組中的第i個(gè)元素: printf(“%c”, *(p + i);/* 推薦做法 */ 或 printf(“%c”, pi);/* 不推薦做法 */,15.3.1 字符指針,2. 訪問字符串 可以將字符指針賦值為字符串常量的首地址。例如: char *p = “Hello, world!”; 此時(shí),p被初始化為字符串的首地址??梢允褂妙愃频姆绞皆L問字
16、符串中的各個(gè)字符。例如,打印字符常量中的第i個(gè)字符: printf(“%c”, *(p + i); 可以使用以下方式輸出整個(gè)字符串。 printf(“%s”, p);,15.3.1 字符指針,由于字符串常量是不可改變的,因此不能使用p來改變字符串的內(nèi)容,如下操作是非法的。 for(i = 0; i sizeof(str); +i) *(p + i) = 0; 注意:C語言中的字符串常量存儲(chǔ)在常量區(qū),程序中所有相同的字符串使用的是相同的字符串。,15.3.2 使用字符指針,本節(jié)將討論如何在程序中使用字符指針來進(jìn)行字符串處理。 1. 字符串的比較 要求使用字符指針實(shí)現(xiàn)字符串的比較功能,字符串間的大
17、小比較規(guī)則與strncmp函數(shù)相同。對于該問題,可以使用兩個(gè)字符指針分別賦值為兩個(gè)字符串的首地址。在一個(gè)循環(huán)結(jié)果中比較它們當(dāng)前指向的結(jié)果,每一次比較后都講兩個(gè)指針后移一位以指向下一個(gè)字符元素,直至找到第一個(gè)不相等的字符。,15.3.2 使用字符指針,2. 字符串的復(fù)制 要求使用字符指針將一個(gè)字符串的內(nèi)容復(fù)制到另一個(gè)字符數(shù)組中。同樣使用兩個(gè)字符指針,將它們初始化為源字符串和目的字符串的首地址。每一次循環(huán)將目的字符指針的內(nèi)容復(fù)制到源字符指針指向的空間中,并同時(shí)將字符指針后移一位。,15.3.3 字符串?dāng)?shù)組和字符指針數(shù)組,字符串?dāng)?shù)組是以字符串作為數(shù)組元素的數(shù)組,其實(shí)質(zhì)上是一個(gè)二維字符數(shù)組。下面是一個(gè)
18、字符串?dāng)?shù)組的定義: 01char namesNUMLENGTH = /* 定義并初始化二維數(shù)組 */ 02“Nelson Aldrich”, 03“A. Piatt Andrew”, 04“Frank Vanderlip”, 05“Henry P.Davison”, 06“Charles D.Norton” 07,15.3.3 字符串?dāng)?shù)組和字符指針數(shù)組,數(shù)組變量names被定義為含有NUM個(gè)字符串的數(shù)組。由于每個(gè)字符串所占最大空間為LENGTH,因此要求每個(gè)字符串的最大有效長度要小于LENGTH(要考慮字符串最后的0)。與其余數(shù)組的定義類似,可以省略NUM,這樣names的可容納的字符串?dāng)?shù)由初始化列表中的字符串個(gè)數(shù)決定;但是,LENGTH不可省略。,15.3.3 字符串?dāng)?shù)組和字符指針數(shù)組,但是,一個(gè)程序中處理的數(shù)組的長度經(jīng)常會(huì)不一致,有的甚至相差很大。如果把它們一起保存在一個(gè)數(shù)組中會(huì)使每一個(gè)字符串的空間都至少擴(kuò)大為最長字符串所占的空間,這樣做十分浪費(fèi)資源。這時(shí)候,可以選擇使用字符指針數(shù)組。,15.3.3 字符串?dāng)?shù)組和字符指針數(shù)組,在數(shù)組中保存字符指針,每個(gè)指針指向需要的字符常量。例如: char * p_nameNUM = NULL;/* 定義并初始化指針數(shù)組 */ p_name 0 = “Nelson Aldrich”;/* 為第一個(gè)元素賦值 */ p_name 1 = “
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026寧夏警官職業(yè)學(xué)院自主招聘博士研究生專任教師30人參考題庫附答案
- 六年級上學(xué)期語文綜合測評卷2026
- 出家道教申請書
- 事業(yè)單位個(gè)人申請書范文
- 廣州轉(zhuǎn)學(xué)申請書范本
- 產(chǎn)業(yè)園區(qū)修建道路申請書
- 文學(xué)社退休申請書
- 復(fù)旦大學(xué)休學(xué)申請書范文
- 14天內(nèi)住院申請書
- 入團(tuán)申請書父母版本
- 物流行業(yè)安全生產(chǎn)會(huì)議記錄范文
- 橫向課題可行性報(bào)告
- GB/T 44253-2024巡檢機(jī)器人安全要求
- 電力電子技術(shù)(廣東工業(yè)大學(xué))智慧樹知到期末考試答案章節(jié)答案2024年廣東工業(yè)大學(xué)
- 汽車網(wǎng)絡(luò)與新媒體營銷課件
- DB32T3834-2020水利工程螺桿式啟閉機(jī)檢修技術(shù)規(guī)程
- 提高臥床患者踝泵運(yùn)動(dòng)的執(zhí)行率
- 傷寒論條文(全398條)
- 資料3b SIG康美包無菌灌裝流程及特征分段介紹
- 鉗工技能訓(xùn)練(第4版)PPT完整全套教學(xué)課件
- 電力工程課程設(shè)計(jì)-某機(jī)床廠變電所設(shè)計(jì)
評論
0/150
提交評論