【转】 指针函数与函数指针的区别
一、
在學(xué)習(xí)arm過程中發(fā)現(xiàn)這“指針函數(shù)”與“函數(shù)指針”容易搞錯(cuò),所以今天,我自己想一次把它搞清楚,找了一些資料,首先它們之間的定義:
1、指針函數(shù)是指帶指針的函數(shù),即本質(zhì)是一個(gè)函數(shù)。函數(shù)返回類型是某一類型的指針
???? 類型標(biāo)識符??? *函數(shù)名(參數(shù)表)
????? int *f(x,y);
?
首先它是一個(gè)函數(shù),只不過這個(gè)函數(shù)的返回值是一個(gè)地址值。函數(shù)返回值必須用同類型的指針變量來接受,也就是說,指針函數(shù)一定有函數(shù)返回值,而且,在主調(diào)函數(shù)中,函數(shù)返回值必須賦給同類型的指針變量。
表示:
float *fun();
float *p;
p = fun(a);
注意指針函數(shù)與函數(shù)指針表示方法的不同,千萬不要混淆。最簡單的辨別方式就是看函數(shù)名前面的指針*號有沒有被括號()包含,如果被包含就是函數(shù)指針,反之則是指針函數(shù)。
來講詳細(xì)一些吧!請看下面
?指針函數(shù):
????當(dāng)一個(gè)函數(shù)聲明其返回值為一個(gè)指針時(shí),實(shí)際上就是返回一個(gè)地址給調(diào)用函數(shù),以用于需要指針或地址的表達(dá)式中。
????格式:
?????????類型說明符?*?函數(shù)名(參數(shù))
????當(dāng)然了,由于返回的是一個(gè)地址,所以類型說明符一般都是int。
????例如:int?*GetDate();
??????????int?*?aaa(int,int);
????函數(shù)返回的是一個(gè)地址值,經(jīng)常使用在返回?cái)?shù)組的某一元素地址上。
????????int?*?GetDate(int?wk,int?dy);
????????main()
????????{
????????????int?wk,dy;
????????????do
????????????{
????????????????printf(Enter?week(1-5)day(1-7)\n);
????????????????scanf(%d%d,&wk,&dy);
????????????}
????????????while(wk<1||wk>5||dy<1||dy>7);
????????????printf(%d\n,*GetDate(wk,dy));
????????}
????????int?*?GetDate(int?wk,int?dy)
????????{
????????????static?int?calendar[5][7]=
????????????{
???????????????{1,2,3,4,5,6,7},
???????????????{8,9,10,11,12,13,14},
???????????????{15,16,17,18,19,20,21},
???????????????{22,23,24,25,26,27,28},
???????????????{29,30,31,-1}
????????????};
????????????return?&calendar[wk-1][dy-1];
????????}
????????程序應(yīng)該是很好理解的,子函數(shù)返回的是數(shù)組某元素的地址。輸出的是這個(gè)地址里的值。
?
?
?
2、函數(shù)指針是指向函數(shù)的指針變量,即本質(zhì)是一個(gè)指針變量。
int (*f) (int x); /* 聲明一個(gè)函數(shù)指針 */
f=func; /* 將func函數(shù)的首地址賦給指針f */
?
指向函數(shù)的指針包含了函數(shù)的地址,可以通過它來調(diào)用函數(shù)。聲明格式如下:
????????類型說明符?(*函數(shù)名)(參數(shù))
????其實(shí)這里不能稱為函數(shù)名,應(yīng)該叫做指針的變量名。這個(gè)特殊的指針指向一個(gè)返回整型值的函數(shù)。指針的聲明筆削和它指向函數(shù)的聲明保持一致。
????????指針名和指針運(yùn)算符外面的括號改變了默認(rèn)的運(yùn)算符優(yōu)先級。如果沒有圓括號,就變成了一個(gè)返回整型指針的函數(shù)的原型聲明。
????例如:
????????void?(*fptr)();
????把函數(shù)的地址賦值給函數(shù)指針,可以采用下面兩種形式:
????????fptr=&Function;
????????fptr=Function;
????取地址運(yùn)算符&不是必需的,因?yàn)閱螁我粋€(gè)函數(shù)標(biāo)識符就標(biāo)號表示了它的地址,如果是函數(shù)調(diào)用,還必須包含一個(gè)圓括號括起來的參數(shù)表。
????可以采用如下兩種方式來通過指針調(diào)用函數(shù):
????????x=(*fptr)();
????????x=fptr();
????第二種格式看上去和函數(shù)調(diào)用無異。但是有些程序員傾向于使用第一種格式,因?yàn)樗鞔_指出是通過指針而非函數(shù)名來調(diào)用函數(shù)的。下面舉一個(gè)例子:
????????void?(*funcp)();
????????void?FileFunc(),EditFunc();
????????main()
????????{
????????????funcp=FileFunc;
????????????(*funcp)();
????????????funcp=EditFunc;
????????????(*funcp)();
????????}
????????void?FileFunc()
????????{
????????????printf(FileFunc\n);
????????}
????????void?EditFunc()
????????{
????????????printf(EditFunc\n);
????????}
????????程序輸出為:
????????????FileFunc
????????????EditFunc
?
主要的區(qū)別是一個(gè)是指針變量,一個(gè)是函數(shù)。在使用是必要要搞清楚才能正確使用
?
二、指針的指針
????指針的指針看上去有些令人費(fèi)解。它們的聲明有兩個(gè)星號。例如:
????????char?**?cp;
????如果有三個(gè)星號,那就是指針的指針的指針,四個(gè)星號就是指針的指針的指針的指針,依次類推。當(dāng)你熟悉了簡單的例子以后,就可以應(yīng)付復(fù)雜的情況了。當(dāng)然,實(shí)際程序中,一般也只用到? 二級指針,三個(gè)星號不常見,更別說四個(gè)星號了。
????指針的指針需要用到指針的地址。
????????char?c='A';
????????char?*p=&c;
????????char?**cp=&p;
????通過指針的指針,不僅可以訪問它指向的指針,還可以訪問它指向的指針?biāo)赶虻臄?shù)據(jù)。下面就是幾個(gè)這樣的例子:
????????char?*p1=*cp;
????????char?c1=**cp;
????你可能想知道這樣的結(jié)構(gòu)有什么用。利用指針的指針可以允許被調(diào)用函數(shù)修改局部指針變量和處理指針數(shù)組。
????????void?FindCredit(int?**);
????????main()
????????{
????????????int?vals[]={7,6,5,-4,3,2,1,0};
????????????int?*fp=vals;
????????????FindCredit(&fp);
????????????printf(%d\n,*fp);
????????}
????????void?FindCredit(int?**?fpp)
????????{
????????????while(**fpp!=0)
????????????if(**fpp<0)?break;
????????????else?(*fpp)++;
????????}
????首先用一個(gè)數(shù)組的地址初始化指針fp,然后把該指針的地址作為實(shí)參傳遞給函數(shù)FindCredit()。FindCredit()函數(shù)通過表達(dá)式**fpp間接地得到數(shù)組中的數(shù)據(jù)。為遍歷數(shù)組以找到一個(gè)負(fù)值,FindCredit()函數(shù)進(jìn)行自增運(yùn)算的對象是調(diào)用者的指向數(shù)組的指針,而不是它自己的指向調(diào)用者指針的指針。語句(*fpp)++就是對形參指針指向的指針進(jìn)行自增運(yùn)算的。但是因?yàn)?運(yùn)算符高于++運(yùn)算符,所以圓括號在這里是必須的,如果沒有圓括號,那么++運(yùn)算符將作用于二重指針fpp上。
三、指向指針數(shù)組的指針
????指針的指針另一用法舊處理指針數(shù)組。有些程序員喜歡用指針數(shù)組來代替多維數(shù)組,一個(gè)常見的用法就是處理字符串。
????????char?*Names[]=
????????{
?????????????Bill,
?????????????Sam,
?????????????Jim,
?????????????Paul,
?????????????Charles,
?????????????0
????????};
????????main()
????????{
????????????char?**nm=Names;
????????????while(*nm!=0)?printf(%s\n,*nm++);
????????}
????先用字符型指針數(shù)組Names的地址來初始化指針nm。每次printf()的調(diào)用都首先傳遞指針nm指向的字符型指針,然后對nm進(jìn)行自增運(yùn)算使其指向數(shù)組的下一個(gè)元素(還是指針)。注意完成上述認(rèn)為的語法為*nm++,它首先取得指針指向的內(nèi)容,然后使指針自增。
????注意數(shù)組中的最后一個(gè)元素被初始化為0,while循環(huán)以次來判斷是否到了數(shù)組末尾。具有零值的指針常常被用做循環(huán)數(shù)組的終止符。程序員稱零值指針為空指針(NULL)。采用空指針作為終止符,在樹種增刪元素時(shí),就不必改動(dòng)遍歷數(shù)組的代碼,因?yàn)榇藭r(shí)數(shù)組仍然以空指針作為結(jié)束。
?
轉(zhuǎn):http://www.cnblogs.com/gmh915/archive/2010/06/11/1756067.html
轉(zhuǎn)載于:https://www.cnblogs.com/eleclsc/p/5877297.html
總結(jié)
以上是生活随笔為你收集整理的【转】 指针函数与函数指针的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: $(document).ready()
- 下一篇: 【解决办法】Oracle登录报错ORA-