指針是一個(gè)特殊的變量,它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。數(shù)據(jù)在內(nèi)存中的地址也稱為指針,如果一個(gè)變量存儲(chǔ)了一份數(shù)據(jù)的指針,我們就稱它為指針變量。
成都創(chuàng)新互聯(lián)公司專注于文安網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供文安營銷型網(wǎng)站建設(shè),文安網(wǎng)站制作、文安網(wǎng)頁設(shè)計(jì)、文安網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造文安網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供文安網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
計(jì)算機(jī)中所有的數(shù)據(jù)都必須放在內(nèi)存中,不同類型的數(shù)據(jù)占用的字節(jié)數(shù)不一樣,例如 int 占用 4 個(gè)字節(jié),char 占用 1 個(gè)字節(jié)。
為了正確地訪問這些數(shù)據(jù),必須為每個(gè)字節(jié)都編上號(hào)碼,就像門牌號(hào)、身份證號(hào)一樣,每個(gè)字節(jié)的編號(hào)是唯一的,根據(jù)編號(hào)可以準(zhǔn)確地找到某個(gè)字節(jié)。
C語言用變量來存儲(chǔ)數(shù)據(jù),用函數(shù)來定義一段可以重復(fù)使用的代碼,它們最終都要放到內(nèi)存中才能供 CPU 使用。數(shù)據(jù)和代碼都以二進(jìn)制的形式存儲(chǔ)在內(nèi)存中,計(jì)算機(jī)無法從格式上區(qū)分某塊內(nèi)存到底存儲(chǔ)的是數(shù)據(jù)還是代碼。
當(dāng)程序被加載到內(nèi)存后,操作系統(tǒng)會(huì)給不同的內(nèi)存塊指定不同的權(quán)限,擁有讀取和執(zhí)行權(quán)限的內(nèi)存塊就是代碼,而擁有讀取和寫入權(quán)限(也可能只有讀取權(quán)限)的內(nèi)存塊就是數(shù)據(jù)。
CPU 只能通過地址來取得內(nèi)存中的代碼和數(shù)據(jù),程序在執(zhí)行過程中會(huì)告知 CPU 要執(zhí)行的代碼以及要讀寫的數(shù)據(jù)的地址。
如果程序不小心出錯(cuò),或者開發(fā)者有意為之,在 CPU 要寫入數(shù)據(jù)時(shí)給它一個(gè)代碼區(qū)域的地址,就會(huì)發(fā)生內(nèi)存訪問錯(cuò)誤。這種內(nèi)存訪問錯(cuò)誤會(huì)被硬件和操作系統(tǒng)攔截,強(qiáng)制程序崩潰,程序員沒有挽救的機(jī)會(huì)。
變量名和函數(shù)名為我們提供了方便,讓我們?cè)诰帉懘a的過程中可以使用易于閱讀和理解的英文字符串,不用直接面對(duì)二進(jìn)制地址,那場(chǎng)景簡(jiǎn)直讓人崩潰。
需要注意的是,雖然變量名、函數(shù)名、字符串名和數(shù)組名在本質(zhì)上是一樣的,它們都是地址的助記符,但在編寫代碼的過程中,我們認(rèn)為變量名表示的是數(shù)據(jù)本身,而函數(shù)名、字符串名和數(shù)組名表示的是代碼塊或數(shù)據(jù)塊的首地址。
擴(kuò)展資料
指針使用(* 和 )
*a可以理解為*(a),a表示取變量 a 的地址(等價(jià)于 pa),*(a)表示取這個(gè)地址上的數(shù)據(jù)(等價(jià)于 *pa),繞來繞去,又回到了原點(diǎn),*a仍然等價(jià)于 a。
*pa可以理解為(*pa),*pa表示取得 pa 指向的數(shù)據(jù)(等價(jià)于 a),(*pa)表示數(shù)據(jù)的地址(等價(jià)于 a),所以*pa等價(jià)于 pa。
對(duì)星號(hào)*的總結(jié)
在我們目前所學(xué)到的語法中,星號(hào)*主要有三種用途:
1、表示乘法,例如int a = 3, b = 5, c; ?c = a * b;,這是最容易理解的。
2、表示定義一個(gè)指針變量,以和普通變量區(qū)分開,例如int a = 100; ?int *p = a;。
3、表示獲取指針指向的數(shù)據(jù),是一種間接操作,例如int a, b, *p = a; ?*p = 100; ?b = *p;。
學(xué)習(xí)了數(shù)組之后,我們知道數(shù)組是在內(nèi)存中申請(qǐng)一塊內(nèi)存空間;數(shù)組名代表內(nèi)存塊的首地址,通過數(shù)組名可以訪問內(nèi)存塊中的數(shù)據(jù)。
那么,對(duì)于函數(shù),它也是存放在內(nèi)存塊中的一段數(shù)據(jù)。例如下面的函數(shù):
void func( int a )
{
printf( "in func, a = %d " , a );
}
此時(shí),定義了一個(gè)函數(shù)名是func的函數(shù)。可以如下調(diào)用該函數(shù):
func(100);
此時(shí),就進(jìn)入了func函數(shù)的函數(shù)體中執(zhí)行。可以看到, 函數(shù)名如同數(shù)組名一樣,代表函數(shù)所在內(nèi)存塊的首地址 。通過數(shù)組名可以訪問數(shù)組在內(nèi)存塊中申請(qǐng)的內(nèi)存,同理,通過函數(shù)名,可以訪問函數(shù)在內(nèi)存中存放的數(shù)據(jù)。
所以,函數(shù)名就代表了該函數(shù)在內(nèi)存塊中存放的首地址。那么,函數(shù)名是表示一個(gè)地址,就可以把這個(gè)地址值存放在某一個(gè)指針變量中,然后,通過指針變量訪問函數(shù)名指向的函數(shù)。
在C語言中,提供了函數(shù)指針變量,可以存放函數(shù)名表示的地址。函數(shù)指針變量的定義格式如下:
返回?cái)?shù)據(jù)類型 (*函數(shù)指針變量名)(形參列表)
對(duì)比函數(shù)的定義如下:
返回?cái)?shù)據(jù)類型 函數(shù)名(形參列表)
可以看到,函數(shù)指針變量的定義,與函數(shù)的定義格式基本一樣,唯一的區(qū)別是把“函數(shù)名”轉(zhuǎn)換為“*(函數(shù)指針變量名)”;總結(jié)如下:
(1) 使用指針降級(jí)運(yùn)算符*來定義,表示這個(gè)是一個(gè)指針。
(2) 指針降級(jí)運(yùn)算符*不可以靠近返回?cái)?shù)據(jù)類型,例如“返回?cái)?shù)據(jù)類*”就表示函數(shù)的返回類型是一個(gè)指針。那么,為了讓指針降級(jí)運(yùn)算符*能夠修飾函數(shù)指針變量,就用小括號(hào)()把指針降級(jí)運(yùn)算符*與函數(shù)指針變量名包含起來。
定義了函數(shù)指針變量之后,可以把函數(shù)名賦給函數(shù)指針變量。因?yàn)椋瘮?shù)名就表示函數(shù)在內(nèi)存塊中的首地址,所以,可以直接把一個(gè)地址賦值給函數(shù)指針變量。格式如下:
函數(shù)指針變量 = 函數(shù)名;
最終,可以通過函數(shù)指針變量調(diào)用函數(shù),調(diào)用的格式與通過函數(shù)名調(diào)用完全一樣,通過函數(shù)指針變量調(diào)用函數(shù),有如下形式:
方法1:函數(shù)指針變量(實(shí)參列表);
方法2:(*函數(shù)指針變量名)(實(shí)參列表);
很多情況下,我們更傾向于使用第一種形式,因?yàn)椋氖褂梅绞礁咏谕ㄟ^函數(shù)名調(diào)用函數(shù)。
下面根據(jù)程序測(cè)試?yán)觼砜纯丛趺礃討?yīng)用函數(shù)指針變量。
深入學(xué)習(xí),可以交個(gè)朋友,工人人人號(hào):韋凱峰linux編程學(xué)堂
程序運(yùn)行結(jié)果如下:
深入學(xué)習(xí),可以交個(gè)朋友,工人人人號(hào):韋凱峰linux編程學(xué)堂
可以看到,我們定義了func函數(shù)和函數(shù)指針變量pfunc,然后,把函數(shù)名func設(shè)置給函數(shù)指針變量pfunc,最終,通過函數(shù)指針變量pfunc調(diào)用函數(shù)。
因?yàn)楹瘮?shù)指針變量存放的就是函數(shù)名表示的地址,所以,函數(shù)指針變量與函數(shù)名一樣,可以直接通過函數(shù)指針變量調(diào)用函數(shù)。
注意:我們?cè)趯W(xué)習(xí)指針的時(shí)候,可以把一個(gè)int類型的變量地址賦值給int類型的指針;但是,不可以把int類型變量的地址,賦值給double類型的指針。這就是變量數(shù)據(jù)類型不一致的問題。
同樣的道理,定義函數(shù)的時(shí)候,函數(shù)的返回?cái)?shù)據(jù)類型和形參列表都不一樣,所以,函數(shù)指針變量能夠接收的函數(shù)名,它們定義的 函數(shù)返回?cái)?shù)據(jù)類型和形參列表必須一致 ,此時(shí),就如同變量與指針變量類型一致時(shí),才可以把變量的地址賦值給指針變量一樣。
如下是一個(gè)測(cè)試?yán)樱?/p>
深入學(xué)習(xí),可以交個(gè)朋友,工人人人號(hào):韋凱峰linux編程學(xué)堂
程序編譯結(jié)果如下:
深入學(xué)習(xí),可以交個(gè)朋友,工人人人號(hào):韋凱峰linux編程學(xué)堂
可以看到,我們把func函數(shù)的形參列表修改為double,但是,函數(shù)指針變量pfunc定義的形參列表為int類型,此時(shí),函數(shù)和函數(shù)指針變量的定義格式不一致,所以,不可以把函數(shù)名表示的地址設(shè)置給函數(shù)指針變量。我們來總結(jié)一下:
(1) 在Ubuntu系統(tǒng)中,使用GCC編譯,提示warning警告,但是,程序可以編譯通過,可以運(yùn)行。
(2) 在Windows系統(tǒng)中,使用Visual Studio工具,無法編譯該代碼,提示類型不一致。
(3) 從代碼的嚴(yán)謹(jǐn)方面來說,是不可以設(shè)置類型不一致的數(shù)據(jù)。所以,我們應(yīng)該編寫嚴(yán)謹(jǐn)?shù)拇a,函數(shù)定義的類型,與函數(shù)指針類型不一致的時(shí)候,不可以把函數(shù)名,賦值給函數(shù)指針變量。
函數(shù)指針變量的定義很重要,我們需要牢記和理解它們使用的方式。下面多舉幾個(gè)例子說明函數(shù)指針變量的定義和使用。
int func( void );
int (*pfunc)( void );
pfunc = func;
此時(shí),定義func函數(shù),它的返回值類型是int類型,形參列表是void,那么,定義pfunc函數(shù)指針變量的時(shí)候,它的返回值類型與形參列表都必須與func一樣。
char * func1( int x, int y, int x);
char * (*pfunc1)( int , int , int );
pfunc1 = func1;
char * (*pfunc1)( int x, int y, int x);
我們?cè)倏偨Y(jié)一下:
(1) 函數(shù)名表示函數(shù)在內(nèi)存塊中的首地址,可以直接把函數(shù)名賦值給函數(shù)指針變量;
(2) 定義函數(shù)指針變量的時(shí)候,函數(shù)返回?cái)?shù)據(jù)類型和形參列表必須與要指向函數(shù)的定義一致;
01
指針函數(shù)通常是指函數(shù)返回值是指針的一類函數(shù),如圖所示。
02
函數(shù)指針是指指向某個(gè)具體函數(shù)的指針變量,在程序設(shè)計(jì)時(shí)可以用來調(diào)用某個(gè)特定函數(shù)或者做某個(gè)函數(shù)的參數(shù)。其形式一般如圖:
03
指針函數(shù)與函數(shù)指針本質(zhì)上的區(qū)別是,指針函數(shù)是一個(gè)帶指針的函數(shù),總的來說還是一個(gè)函數(shù),如圖就是一個(gè)帶*name指針的函數(shù)
04
函數(shù)指針是指向函數(shù)的指針變量,本質(zhì)上還是一個(gè)指針,其格式如下,可以看到和指針函數(shù)的格式非常像,所以一定要用心留意。
當(dāng)前標(biāo)題:c語言函數(shù)指針講解 c語言函數(shù)指針用法
分享地址:http://www.chinadenli.net/article46/dddoehg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站收錄、App設(shè)計(jì)、網(wǎng)站營銷、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)