




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、第2-5講 指針1基本概念介紹指針的基本概念指針與數(shù)組指針與字符串指針與函數(shù)指針與結構體引用的概念及應用15.1 指針的概念一、指針與地址指針是C語言中的一個重要概念。掌握指針的用法,可使程序簡潔、高效、靈活。例如:尋寶游戲66 1000P2111000 P為指針變量,1000(地址)是指針變量的值。 指針變量就是用來存放另一變量地址的變量2計算機的內(nèi)存是一些“存儲單元”的系列集。每個單元(字節(jié))有一個稱為地址的數(shù)字與之關聯(lián)。地址都是從0開始依次編號的。最后一個地址編號取決于內(nèi)存的大小。64K 65535當聲明一個變量時,系統(tǒng)會在內(nèi)存中分配適當?shù)拇鎯臻g,以保存該變量的值。內(nèi)存單元地址0123
2、4567.655353 指針是建立在下面3個基本概念的基礎上的: 計算機的內(nèi)存地址是指針常量(pointer constant)。我們不能修改它們,只能用來存儲數(shù)據(jù)值。 不能直接保存地址的值,只能利用地址運算符(&)來獲取變量的地址。這樣獲得的值稱為指針值(pointer value,也就是變量的地址)。指針值在程序每次運行時都會發(fā)生變化。 包含指針值的變量稱為指針變量(pointer variable)指針相關的基本概念 指針常量 指針值 指針變量 指針4二、指針變量的聲明 聲明形式: 數(shù)據(jù)類型 * 指針變量名; “ * ” 表示這里聲明的是一個指針類型的變量。 “ 數(shù)據(jù)類型” 是指針所指向
3、的變量的類型。一個指針變量只能指向同一個類型的變量。 例如: int * point_a; / 聲明了一個指向 int 型數(shù)的指針變量 兩種理解:1)(int *) point_a; / point_a 為 int * (整數(shù)指針)2) int (*point_a); / *point_a 為一個整數(shù) 注意: int * point_a, point_b; / point_b為intint * point_a, * point_b; / point_b為int *5在C/C+中,每個指針均有兩方面的含義:內(nèi)存存儲單元和對存儲單元內(nèi)容的解釋內(nèi)存存儲單元就是地址 指針本身只包含地址,要使用指針指向
4、的數(shù)據(jù),必須先到達那個地址,提取并按一定規(guī)則解釋該內(nèi)存單元的內(nèi)容。內(nèi)存單元只不過是一些0/1位的組合。解釋的基礎依賴于指針的類型 整數(shù)指針表示指針指向一個整數(shù),其真實含義是:程序從指針提供的單元地址提取整數(shù)所占字節(jié)數(shù)的0/1組合,即按整數(shù)編碼規(guī)則解釋。 例如:對同一存儲單元,用幾種方法解釋得到不同的結果。6假設內(nèi)存單元為(16進制): 0a 61 62 63 64 65 66 67 68 69 6a解釋結果: int * :提取 0a 61char * :提取 0a float * :提取 0a 61 62 63long * :提取 0a 61 62 637三、與指針相關的運算符: & 和 *
5、 “ & ” 為取地址(引用)運算符,用來得到一個變量的地址。位于變量之前的地址運算符將可返回該變量的地址。運算符“&”只能用于單個變量或一個數(shù)組元素。&125 非法!指向了常量int x10 &x 非法!指向了數(shù)組名&(x+y) 非法!指向了表達式8必須確保指針變量總是指向相應的數(shù)據(jù)類型。 float a, b; int x, *p; p = &a; 錯!可以把初始化和聲明組合在一起。 int a, b; int *pt1, *pt2=&b; / 把變量b的地址賦給指針變量pt2 pt1 = &a; / 把變量a的地址賦給指針變量pt1唯一要求的是變量必須在初始化之前就已經(jīng)聲明過了。可以在定
6、義指針變量時帶有一個初始值NULL或零。 int *p=NULL; /定義p為指向整形變量的指針變量, / 并初始化為0 int *p=0;9“ * ” 為間接訪問運算符(或稱“反引用”運算符),表示指針所指向的變量的值。 在聲明語句中,“ * ” 表示聲明的變量是一個指針。 int *point_a; 在執(zhí)行語句中或聲明語句的初值表達式中,表示訪問指針所指對象的內(nèi)容。例如: printf(%d, *point_a); / 輸出指針 point_a 所指向的內(nèi)容int a, *pt, b;a = 100;pt = &a; / 將a 的地址賦給指針變量ptb = *pt; / *pt返回的是變量
7、a的值a = *(&a) = *pt = n&a = &(*pt)10例5-1,通過指針變量訪問整型變量 11指針的賦值在聲明指針的同時進行初始化賦值 數(shù)據(jù)類型 * 指針名 = 初始地址;int a = 100;int *pt = &a; / 聲明并用變量名來初始化指針int array10;int *pt = array; / 聲明并用數(shù)組名來初始化指針 在聲明之后,單獨使用賦值語句 指針名 = 地址;int a = 100, x;int *pt;pt = &a; / 把變量 a 的地址賦給指針 pt可以通過指針變量 pt 間接訪問變量ax = *pt; / 等價于: x = a;12指針變
8、量和一般變量一樣, 對于同一類型,存放在它們之中的值是可以改變的, 也就是說可以改變它們的指向 int a, b, *pt1, *pt2; a = 100; b = 200; pt1 = &a; / 把變量 a 的地址賦給指針 pt1 pt2 = pt1; / 使pt2 與pt1指向同一對象 pt2 = &b; / 把變量 b 的地址賦給指針 pt2 *pt2 = *pt1; / 表示把pt1指向的內(nèi)容賦給pt2所指的區(qū)域pt2bpt1a200100&a100&b&a13對運算符& 和 * 的幾點說明:1)如pt1 = &a; ,若&*pt1,則按自右而左方向結合(優(yōu)先級相同),因此先進行 *
9、pt1運算,就是變量a,再執(zhí)行&運算,即為變量a的地址。pt2 &*pt1; / 它的作用是將&a賦給pt2,等價于 pt2 = &a; 如果pt2原來指向b,經(jīng)過重新賦值后,它已不再指向b了。pt2b&apt1a&a&b142)*&a :先進行&a 運算,得a 的地址,再進行* 運算。與a等價3)(*pt)+ 相當于 a+如果沒有(),相當于*(pt+)。即先做pt+,再求*。而 pt+ 為后加,故先對pt做*pt 操作,得到a,再使pt加1,這樣,pt就不再指向a了四、指針鏈把一個指針指向另一個指針,從而形成如下所示的指針鏈多重間接(multiple indirection) 地址2pt2
10、地址1 pt1值變量15指向指針的指針變量必須在名稱前面添加額外的間接運算符。例如:int *pt; / pt 是指向int 類型的指針的指針可以使用兩次間接運算符,用指向指針的指針來間接地訪問目標值。例5-2,通過指向指針的指針變量訪問整型變量16五、指針表達式與其它變量一樣,指針變量也可用于表達式中。還可以使用關系運算符對指針進行比較。p1 = p2p1 != p2對單獨變量的指針進行比較沒有意義。指針比較一般用于處理數(shù)組或字符串 合法 合法 合法 合法 錯!17指針可以進行遞增、遞減運算p1 = p1 + 1;p1 = p2 + 2;當指針進行遞增(減)時,所增加的值為該指針指向的數(shù)據(jù)類
11、型的“長度”字符char1字節(jié)整數(shù)int2字節(jié)浮點數(shù)float4字節(jié)長整數(shù)long4字節(jié)雙精度數(shù)double8字節(jié)18 1)可以把另一個變量的地址賦給指針變量。 2)可以把一個指針變量的值賦給另一個指針變量。 3)可以使用NULL或零值來初始化指針變量。 4)可以在指針變量的前面或后面添加遞增或遞減運算符。 5)指針變量可以與整數(shù)值進行加減運算。 6)當兩個指針指向相同數(shù)據(jù)類型的對象時,可以使用關系運算符對它們進行比較操作。 7)不能把指針變量與常量做乘法運算。 8)兩個獨立的指針變量不能做加法運算。 9)不能把一個數(shù)值賦給地址。(例如,&x=10 是非法的) 指針操作的規(guī)則195.2 指針與
12、數(shù)組一、指向數(shù)組元素的指針通過數(shù)組下標所能完成的任何操作都可以通過指針來實現(xiàn)。用指針編寫的程序比用數(shù)組下標編寫的程序執(zhí)行速度快,但理解起來稍微困難一些。例如:int a10, x;int *pa;pa = &a0; / pa指向數(shù)組a的第0個元素 pa=a;x = *pa; / 把a0中的內(nèi)容復制到變量x中pa = &a2; / pa=a+2;2018161412108642a0a9 pa:a:pa+1:pa+2:20二、通過指針引用數(shù)組元素如果pa = &a0; 則也可通過指針訪問數(shù)組元素ai *(a+i) *(pa+i)pai *(pa+i) 引用一個數(shù)組元素的方法:下標法,ai指針法,*
13、(pa+i) 或*(a+i)數(shù)組元素的地址是通過它的索引和數(shù)據(jù)類型的長度(比例因子)來計算的。xi的地址 = 基本地址 + (i 數(shù)據(jù)類型的比例因子)例5-3,設有一個int 型一維數(shù)組a,有10個元素。用三種方法輸出各元素。2122使用注意 通過指針訪問數(shù)組元素必須保證所有間接訪問都在合法范圍內(nèi)進行 由運算取得的指針值不能超出數(shù)組首元素和末元素的位置ai0* ( p + i )321a0a9 p:a:p+1, a+1:p+2, a+2:p+i, a+i:p+9, a+9:23 p = a;24三、地址算術運算如果p是一個指向數(shù)組中某個元素的指針,那么p+將對p進行自增運算,并指向下一個元素;
14、而p=p+i 將對p進行加i的增量運算,使其指向指針p當前指向的元素之后的第i個元素。*p+,自右向左結合,等價于*(p+)。作用是先得到p指向的變量的值(*p),然后再使p+1p。*(p+)與*(+p)作用不同。前者先取*p值,然后使p加1;后者使先使p加1,再取*p值。(*p)+,表示p所指向的元素值加1。*(p-)與*(-p)25指針在一定條件下,可進行比較。例如:兩個指針變量p, q指向同一數(shù)組, 則, =,=, =等關系運算符都能正常進行。 若p = = q為真, 則表示p, q 指向數(shù)組的同一元 素; 若pq 為真, 則表示p所指向的數(shù)組元素在q所指向的數(shù)組元素之前。兩個指針變量在
15、一定條件下, 可進行減法運算。例如:設p, q指向同一數(shù)組, 且pq,則p-q+1表示位于p和q指向的元素之間的元素的個數(shù)。指針與整數(shù)之間不能相互轉換,但0是唯一的例外。常量0可以賦值給指針,指針也可以和常量0進行比較。程序中經(jīng)常用符號常量NULL代替常量0。符號常量NULL定義在標準頭文件 中。26有效的指針運算包括:相同類型之間的賦值運算;指針同整數(shù)之間的加法或減法運算;指向相同數(shù)組中元素的兩個指針間的減法或比較運算;將指針賦值為0 (或NULL);指針與0 (或NULL)之間的比較運算。27四、指針使用中的常見錯誤指針使用靈活,用途廣泛,但容易出錯。 錯誤使用主要表現(xiàn)為:讀出操作,導致得
16、到無效的數(shù)據(jù)。 這是因為:一個指針在定義后而被賦值之前,其值是未知的。寫入操作,導致重寫其他數(shù)據(jù)甚至代碼段,這種錯誤的影響有時不會立即表現(xiàn)出來。使用指針的最常見錯誤是非法間接訪問,例如: int *p, n = 3; *p = n; / 錯!這個語句是個大錯誤,它可能引起的后果無法預料。28五、多維數(shù)組與指針多維數(shù)組元素的地址二維數(shù)組在內(nèi)存中是按行存放的int a33=1,2,3, 2,3,4, 3,4,5;543432321a2a1a0a(2000)a+1(2006)a+2(2012)a0(2000)a0+1(2002)a0+2(2004)29表示形式含義a二維數(shù)組名,指向第0行首地址a0,
17、 *(a+0), *a第0行第0列元素地址a+1, &a1第1行首地址a+i, &ai第i行首地址a1,*(a+1)第1行第0列元素a10的地址a1+1, *(a+1)+1, &a11第1行第1列元素a11的地址ai+j, *(a+i)+j, &aij第i行第j列元素aij的地址*(a1+1), *(*(a+1)+1), a11第1行第1列元素a11的值*(ai+j), *(*(a+i)+j), aij第i行第j列元素aij的值30例5-4,用指針實現(xiàn)二維數(shù)組的輸出31指向多維數(shù)組元素的指針變量 指向數(shù)組元素的指針 計算aij在數(shù)組中的相對位置(數(shù)組大小為mn)為:i*n+j例5-5,改寫例5
18、-4 32指向有m個元素組成的一維數(shù)組的指針變量int a3; int array23;int (*p)3; int a3; / p 所指的對象是一個包含3個元素的一維數(shù)組,p的值是該一維數(shù)組的首地址p = array(*p)2(*p)1(*p)0(*p)數(shù)組parray1array0pp+133例5-6,改寫例5-434六、指針數(shù)組的概念數(shù)組中的每個元素均為指針類型數(shù)據(jù)一維指針數(shù)組的定義形式為: 類型名 *數(shù)組名數(shù)組長度;int *p5;比較適于用來指向若干字符串,是字符串處理更加方便、靈活例如,圖書館查書,書名都是字符串且書名長度不同,若放在一個數(shù)組中且對它們進行排序,因此如設計一個二維字
19、符數(shù)組,需指定長度,浪費空間。可用指針數(shù)組來實現(xiàn)35例5-7,將若干字符串按字母順序(由小到大)輸出將字符串數(shù)組作為函數(shù)參數(shù)(sort函數(shù)實現(xiàn))sort函數(shù)的兩個參數(shù):string用來接收字符串數(shù)組,char *string n 用來接收該字符串數(shù)組的大小字符串排序算法(選擇排序法)基本思想:在某個位置i,找從該位置到最后一個元素之間最小的元素。找到后,如果這個元素不是位置i,則要把這個最小元素交換到i 位置。i 從1 到倒數(shù)第2個元素,重復進行上述選擇,就會完成數(shù)組中各元素的排序輸出一組字符串printf(%s%c, stringi, (i成員名 / - 稱為成員選擇運算符 (*p).成員名 p-.成員名65二、指向結構數(shù)組的指針例5
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 項目管理復雜問題解析試題及答案
- 產(chǎn)品銷售協(xié)議合同2025
- 中等職業(yè)教育聯(lián)合辦學協(xié)議
- 企業(yè)金融管理的變革方向試題及答案
- 未來展望2025年銀行從業(yè)資格證試題及答案
- 證券從業(yè)資格證考試復習材料的選擇與使用技巧試題及答案
- 微生物耐藥性檢測與解讀試題及答案
- 靈活運用項目管理考試的理論知識試題及答案
- 2025年證券從業(yè)資格考試要點試題及答案
- 分析細節(jié)2025年證券從業(yè)考試試題及答案
- 求是文章《開創(chuàng)我國高質量發(fā)展新局面》專題課件
- 古詩閱讀賞析泊船瓜洲
- 熔斷器安裝施工方案
- 智慧家庭健康監(jiān)測系統(tǒng)設計與實現(xiàn)
- 光伏項目施工總進度計劃表(含三級)
- 中深層無干擾地熱供熱系統(tǒng)應用技術規(guī)程
- 六年級下冊美術教學設計-第3課《記錄色彩》人教新課標
- 2024年江西省天然氣投資有限公司招聘筆試沖刺題(帶答案解析)
- 國開(山西)2024年《使用法律基礎》形考作業(yè)1-4答案
- 2024年鄭州鐵路職業(yè)技術學院單招職業(yè)適應性測試題庫附答案
- 充電樁安全管理規(guī)定(4篇)
評論
0/150
提交評論