秦玉平,冷強(qiáng)奎,李祥納
(1.渤海大學(xué) 數(shù)學(xué)科學(xué)學(xué)院,遼寧 錦州121013;2.渤海大學(xué) 信息科學(xué)與技術(shù)學(xué)院,遼寧 錦州121013;3.北京國電通網(wǎng)絡(luò)技術(shù)有限公司,北京100761)
內(nèi)存中每一個(gè)字節(jié)都有一個(gè)標(biāo)明其位置的地址.C語言編譯程序在對(duì)源程序編譯時(shí),為每個(gè)變量分配連續(xù)的一定字節(jié)數(shù)的存儲(chǔ)單元.變量所分配的存儲(chǔ)單元的第一字節(jié)的地址就是該變量的地址[1-2].
編譯程序在為變量分配存儲(chǔ)單元的時(shí),記錄下變量的名稱、變量的數(shù)據(jù)類型和變量的地址.在對(duì)變量進(jìn)行操作時(shí),先通過變量名查取變量的地址,再根據(jù)變量的數(shù)據(jù)類型到相應(yīng)的內(nèi)存單元存取數(shù)據(jù).由于地址起到尋找操作對(duì)象的作用,就像一個(gè)指向?qū)ο蟮闹羔?,所以把地址稱為“指針”.
程序離硬件越近,其執(zhí)行效率就越高.C語言中有指針類型,能夠直接訪問內(nèi)存,即直接對(duì)物理硬件進(jìn)行操作.因此,合理使用指針能有效提高C語言代碼的質(zhì)量,但使用不當(dāng)也會(huì)導(dǎo)致效率低下.指針是C語言教學(xué)的重點(diǎn),也是學(xué)習(xí)者學(xué)習(xí)的難點(diǎn)[3-5].為便于學(xué)習(xí)者快速掌握C語言指針知識(shí),并熟練使用指針進(jìn)行C語言程序設(shè)計(jì),本文對(duì)C語言中指針的定義、指向?qū)ο蟮囊眉白⒁馐马?xiàng)進(jìn)行詳細(xì)的闡述.
變量的指針是常量,可通過取地址符“&”得到.指針變量定義的一般形式為:
類型標(biāo)識(shí)符*變量名
用指針引用基本型變量的一般形式為:*指針變量名
注意:定義變量時(shí),變量名前加“*”,表示該變量為指針變量;使用指針變量時(shí),指針變量名前加“*”,表示該指針變量所指向的變量.
【例1】用指針引用基本類型變量舉例.
例1中,指針變量p指向整型變量a,此時(shí)可以用p引用變量a,即*p與a等價(jià).變量a、p的值及它們之間的關(guān)系如圖1所示.
圖1 變量a和p的值及其關(guān)系
指針變量的地址是指針變量所指向?qū)ο蟮亩?jí)指針(指針常量),可以定義二級(jí)指針變量,其一般形式為:
類型標(biāo)識(shí)符 **變量名
【例2】用二級(jí)指針引用操作對(duì)象舉例.
例2中,一級(jí)指針變量p指向變量a,二級(jí)指針變量pp指向一級(jí)指針變量p.此時(shí)可用pp引用變量a,即**pp與a等價(jià).變量a、p和pp的值及它們之間的關(guān)系如圖2所示.
圖2 變量a、p和pp的值及其關(guān)系
用結(jié)構(gòu)體(共用體)指針變量可以引用其所指向變量的成員,其引用方式為:
(*指針變量名).成員名 或 指針變量名->成員名
【例3】用指針引用結(jié)構(gòu)體變量舉例.
例3中,把變量stu的地址(&stu)賦給指針變量p,可用指針變量p引用變量stu的成員,此時(shí),(*p).name與stu.name等價(jià),p->score與stu.score等價(jià).
常用指針作函數(shù)的參數(shù)[6],此時(shí)形參和對(duì)應(yīng)實(shí)參指向同一對(duì)象,修改形參指向的對(duì)象相當(dāng)于修改實(shí)參指向的對(duì)象,通過一次函數(shù)調(diào)用可以得到多個(gè)返回值.另外,常用指針對(duì)鏈表操作.
【例4】用指針操作鏈表舉例.
例4中,函數(shù)max的功能是計(jì)算單鏈表中數(shù)據(jù)的最大值,用結(jié)構(gòu)體指針變量p遍歷單鏈表,用結(jié)構(gòu)體指針變量m指向最大值結(jié)點(diǎn),最后返回最大值結(jié)點(diǎn)的指針.
注意:由于鏈表的存儲(chǔ)空間不一定連續(xù),因此鏈表中的指針后移不能用自加運(yùn)算完成,而是用所指向結(jié)點(diǎn)的指針域值更新實(shí)現(xiàn).
C語言中,數(shù)組名代表數(shù)組的起始地址,是地址常量.數(shù)組元素的引用可以用數(shù)組名法,也可以用指針變量法.
用數(shù)組名引用數(shù)組元素的一般形式為:
*(數(shù)組名+表達(dá)式)
其中,表達(dá)式類型任意,一般為算術(shù)表達(dá)式,其值為數(shù)組元素的下標(biāo).
【例5】用一維數(shù)組名引用數(shù)組元素舉例.
例5中,*(a+i)表示a[i],在編譯時(shí),編譯系統(tǒng)自動(dòng)將下標(biāo)法轉(zhuǎn)換為數(shù)組名法,所以下標(biāo)法和數(shù)組名法的執(zhí)行效率相同.
指向一維數(shù)組元素的指針變量的定義與指向變量的指針變量的定義相同.用指針變量引用數(shù)組元素的一般形式為:
*(指針變量+表達(dá)式)或指針變量[表達(dá)式]
其中,表達(dá)式類型任意,一般為算術(shù)表達(dá)式.若指針變量指向數(shù)組的第一個(gè)元素,則表達(dá)式的值就是要引用的數(shù)組元素的下標(biāo),否則要引用的數(shù)組元素的下標(biāo)為:指針變量-數(shù)組名+表達(dá)式.
【例6】用指針變量引用一維數(shù)組元素舉例.
例6中,通過賦值運(yùn)算p=a,指針變量p指向數(shù)組a[0],*(p+2+2)表示數(shù)組元素a[4];通過賦值運(yùn)算p=&a[2],指針變量p指向數(shù)組a[2],p[1]表示數(shù)組元素a[3],p[-1]表示數(shù)組元素a[1];for語句中用指針變量p遍歷一維數(shù)組,因?yàn)閜是變量,所以可以進(jìn)行自加自減運(yùn)算.
C語言對(duì)二維數(shù)組的處理方法是將其分解成多個(gè)一維數(shù)組.
若有定義:int a[3][4];
則C語言對(duì)數(shù)組a的處理方法如圖3所示.即將每一行看作一個(gè)一維數(shù)組,數(shù)組名為a[i](0≤i≤2),元素依次為a[i][0]、a[i][1]、a[i][2]和a[i][3],把a(bǔ)看作由元素a[0]、a[1]和a[2]組成的一維數(shù)組.
圖3 二維數(shù)組a的處理方法
可以用一維數(shù)組名和二維數(shù)組名引用二維數(shù)組元素,也可用指針變量引用二維數(shù)組元素.
用一維數(shù)組名引用二維數(shù)組元素的一般形式為:
*(一維數(shù)組名+表達(dá)式)
其中,表達(dá)式的類型任意,一般為算術(shù)表達(dá)式,其值為二維數(shù)組元素的列標(biāo).
由于二維數(shù)組在內(nèi)存中按行連續(xù)存儲(chǔ),所以可以把二維數(shù)組a看成是數(shù)組名為a[0]的一維數(shù)組,二維數(shù)組元素a[i][j]可表示為:*(a[0]+i*列數(shù)+j).
【例7】用一維數(shù)組名引用二維數(shù)組元素舉例.
例7中,*(a[2]+3)、*(a[1]+7)和*(a[0]+11)都表示數(shù)組元素a[2][3],*(a[0]+2*4+1)表示數(shù)組元素a[2][1].
用二維數(shù)組的數(shù)組名引用二維數(shù)組元素的一般形式為:
*(*(數(shù)組名+表達(dá)式1)+表達(dá)式2)
其中,表達(dá)式1和表達(dá)式2的類型任意,一般為算術(shù)表達(dá)式.表達(dá)式1的值是行標(biāo),表達(dá)式2的值是列標(biāo).
【例8】用二維數(shù)組名引用二維數(shù)組元素舉例.
例8中,*(*(a+i)+j)表示數(shù)組元素a[i][j].編譯時(shí),編譯系統(tǒng)自動(dòng)將二維數(shù)組元素的下標(biāo)表示法轉(zhuǎn)換為數(shù)組名表示法.
指向二維數(shù)組元素的指針變量的定義與指向變量的指針變量的定義相同.用指向二維數(shù)組元素的指針變量引用二維數(shù)組元素的一般形式為:
*(指針變量+表達(dá)式)
其中,表達(dá)式的類型任意,一般為算術(shù)表達(dá)式.若指針變量指向二維數(shù)組的第一個(gè)元素,則引用的數(shù)組元素的行標(biāo)為:(表達(dá)式)/列數(shù),列標(biāo)為:(表達(dá)式)%列數(shù);否則引用的數(shù)組元素的行標(biāo)為:(指針變量-數(shù)組名[0]+表達(dá)式)/列數(shù),列標(biāo)為:(指針變量-數(shù)組名[0]+表達(dá)式)%列數(shù).
【例9】用指向二維數(shù)組元素的指針變量引用數(shù)組元素
例9中,通過賦值運(yùn)算p=a[0],p指向a[0][0],*(p+2+2)表示數(shù)組元素a[1][0];通過賦值運(yùn)算p=a[1],p指向a[1][0],p[1]表示數(shù)組元素a[1][1];for語句中用指針變量p遍歷數(shù)組,依次輸出二維數(shù)組元素值.
指向一維指數(shù)組指針變量定義的一般形式為:
類型標(biāo)識(shí)符(*指針變量名)[常量表達(dá)式]
其中,常量表達(dá)式的值是二維數(shù)組的列數(shù).
用指向一維數(shù)組的指針變量引用二維數(shù)組元素的一般形式為:
*(*(指針變量+表達(dá)式1)+表達(dá)式2)
其中,表達(dá)式1和表達(dá)式2的類型任意,一般為算術(shù)表達(dá)式.表達(dá)式2的值為要引用的二維數(shù)組元素列標(biāo).若指針變量指向第一行,則表達(dá)式1的值為要引用的二維數(shù)組元素行標(biāo);否則,要引用的二維數(shù)組元素行標(biāo)為:指針變量-二維數(shù)組名+表達(dá)式1.
【例10】用指向一維數(shù)組的指針變量引用二維數(shù)組元素.
例10中,p是向一維數(shù)組的指針變量,指向二維數(shù)組a的第一行,*(*(p+row)+col)表示數(shù)組元素a[row][col].用指向一維數(shù)組的指針變量引用二維數(shù)組元素時(shí),也可用下標(biāo)法表示,程序中的*(*(p+row)+col)可以寫成p[row][col].
C語言中沒有字符串變量,可以用字符數(shù)組實(shí)現(xiàn)字符串(對(duì)字符串中字符的引用與前面介紹的數(shù)組元素的引用相同),也可以用字符指針變量實(shí)現(xiàn)字符串.
【例11】用指針變量實(shí)現(xiàn)字符串舉例.
例11中,p是字符指針變量,并將字符串常量"china"的首地址賦給它,即p指向字符串的第一個(gè)字符“c”.程序的輸出結(jié)果是從p+2指向字符開始的子串"ina".
函數(shù)名代表函數(shù)的入口地址,是地址常量.指向函數(shù)的指針變量定義的一般形式為:
[返回值類型](*指針變量名)([形參表列])
可以用指向函數(shù)的指針變量調(diào)用函數(shù),其一般形式為:
(*指針變量名)([實(shí)參表列])或 指針變量名([實(shí)參表列])
【例12】用指向函數(shù)的指針變量調(diào)用函數(shù)舉例.
例12中,指針變量p指向函數(shù)max,函數(shù)調(diào)用(*p)(a,b)等價(jià)于max(a,b)).
用戶在使用文件時(shí),須將文件調(diào)入內(nèi)存,并通過一個(gè)結(jié)構(gòu)體類型的指針與其建立聯(lián)系,從而對(duì)文件進(jìn)行操作.這種結(jié)構(gòu)體類型的指針是對(duì)文件信息的描述,包括文件的描述符、緩沖區(qū)的大小、文件的長度、文件中當(dāng)前處理的數(shù)據(jù)位置等.文件指針變量定義的一般形式為:
FILE*指針變量;
【例13】用文件指針對(duì)文件操作舉例.
例13中,文件指針fp1與文件e1.txt建立了聯(lián)系,文件指針fp2與文件e2.txt建立了聯(lián)系,程序的功能是將文件e1.txt的內(nèi)容復(fù)制到文件e2.txt中.
注意:文件指針與文件位置指針不同,文件指針用來標(biāo)識(shí)文件,須在程序中定義說明,文件位置指針是指文件打開之后,在文件內(nèi)部進(jìn)行移動(dòng)的指針,用以指示文件內(nèi)部的當(dāng)前讀寫位置,每讀寫一次,文件位置指針自動(dòng)向后移動(dòng),它是系統(tǒng)設(shè)置的,不需要在程序中定義說明.
指針是C語言的精髓,合理利用指針能提高代碼的質(zhì)量,但使用不當(dāng)會(huì)導(dǎo)致效率低下.使用指針引用操作對(duì)象時(shí)需注意四點(diǎn):一是區(qū)分常量和變量,二是指向?qū)ο蟮臄?shù)據(jù)類型,三是對(duì)象引用方式,四是指針變量使用前是否被賦值.變量的指針是常量,常用指針變量引用所指向的變量.數(shù)組的指針是常量,常用指向數(shù)組元素和數(shù)組的指針變量引用數(shù)組元素.函數(shù)的指針是常量,可用指向函數(shù)的指針變量調(diào)用函數(shù).stdin、stdout和stderr是文件指針常量,分別指向標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)出錯(cuò)輸出文件,對(duì)文件進(jìn)行操作時(shí),需用文件指針變量與文件建立聯(lián)系.指針變量在使用前一定要賦初值,且類型一定要匹配,不能將基本類型數(shù)據(jù)(0除外)直接賦給指針變量,也不能將一個(gè)指針直接賦給與它類型不同的指針變量.
渤海大學(xué)學(xué)報(bào)(自然科學(xué)版)2021年1期