成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C語(yǔ)言的那些小秘密之函數(shù)指針

開(kāi)發(fā) 后端
我們經(jīng)常會(huì)聽(tīng)到這樣的說(shuō)法,不懂得函數(shù)指針就不是真正的C語(yǔ)言高手。我們不管這句話(huà)對(duì)與否,但是它都從側(cè)面反應(yīng)出了函數(shù)指針的重要性,所以我們還是有必要掌握對(duì)函數(shù)指針的使用。先來(lái)看看函數(shù)指針的定義吧。

函數(shù)是由執(zhí)行語(yǔ)句組成的指令序列或者代碼,這些代碼的有序集合根據(jù)其大小被分配到一定的內(nèi)存空間中,這一片內(nèi)存空間的起始地址就成為函數(shù)的地址,不同的函數(shù)有不同的函數(shù)地址,編譯器通過(guò)函數(shù)名來(lái)索引函數(shù)的入口地址,為了方便操作類(lèi)型屬性相同的函數(shù),c/c++引入了函數(shù)指針,函數(shù)指針就是指向代碼入口地址的指針,是指向函數(shù)的指針變量。 因而“函數(shù)指針”本身首先應(yīng)該是指針變量,只不過(guò)該指針變量指向函數(shù)。這正如用指針變量可指向整形變量、字符型、數(shù)組一樣,這里是指向函數(shù)。C在編譯時(shí),每一個(gè)函數(shù)都有一個(gè)入口地址,該入口地址就是函數(shù)指針?biāo)赶虻牡刂贰S辛酥赶蚝瘮?shù)的指針變量后,可用該指針變量調(diào)用函數(shù),就如同用指針變量可引用其他類(lèi)型變量一樣,在這些概念上是一致的。函數(shù)指針有兩個(gè)用途:調(diào)用函數(shù)和做函數(shù)的參數(shù)。

[[128816]]

函數(shù)指針的聲明方法為:

數(shù)據(jù)類(lèi)型標(biāo)志符 (指針變量名) (形參列表);

“函數(shù)類(lèi)型”說(shuō)明函數(shù)的返回類(lèi)型,由于“”的優(yōu)先級(jí)高于“*”,所以指針變量名外的括號(hào)必不可少,后面的“形參列表”表示指針變量指向的函數(shù)所帶的參數(shù)列表。例如:

  1. int function(int x,int y); /* 聲明一個(gè)函數(shù) */ 
  2. int (*f) (int x,int y); /* 聲明一個(gè)函數(shù)指針 */ 

f=function; /* 將function函數(shù)的首地址賦給指針f */

賦值時(shí)函數(shù)function不帶括號(hào),也不帶參數(shù),由于function代表函數(shù)的首地址,因此經(jīng)過(guò)賦值以后,指針f就指向函數(shù)function(int x,int y);的代碼的首地址。

下面的程序說(shuō)明了函數(shù)指針調(diào)用函數(shù)的方法:

例一、

 

  1. #include 
  2.  
  3. int max ( int x, int y){ return x>y?x:y;} 
  4.  
  5. int min ( int x, int y){ return x 
  6.  
  7. void main 
  8.  
  9. int ( *f ) ( int x, int y)=max; 
  10.  
  11. //f=&max; 
  12.  
  13. printf ( "%d,%d\t", max (2,6), (f)(5,4)); 
  14.  
  15. f=min; 
  16.  
  17. printf (" %d,%d\t" , min (2,6), (f)(5,4)); 
  18.  

 

注意:以上代碼的紅色部分我們將會(huì)在接下來(lái)的代碼分析部分進(jìn)行講解,讀者也可以思考下如果運(yùn)行注釋部分,結(jié)果是否還是正確的呢?

f是指向函數(shù)的指針變量,所以可把函數(shù)max賦給f作為f的值,即把max的入口地址賦給f,以后就可以用f來(lái)調(diào)用該函數(shù),實(shí)際上f和max都指向同一個(gè)入口地址,不同就是f是一個(gè)指針變量,不像函數(shù)名稱(chēng)那樣是死的,它可以指向任何函數(shù),就看你想怎么做了。在程序中把哪個(gè)函數(shù)的地址賦給它,它就指向哪個(gè)函數(shù)。而后用指針變量調(diào)用它,因此可以先后指向不同的函數(shù)。不過(guò)注意,指向函數(shù)的指針變量沒(méi)有++和--運(yùn)算,用時(shí)要小心。

函數(shù)括號(hào)中的形參可有可無(wú),視情況而定,不過(guò),在某些編譯器中這是不能通過(guò)的。這個(gè)例子的補(bǔ)充如下。

1.定義函數(shù)指針類(lèi)型:

  1. typedef int (*fun_ptr)(int,int); 

2.申明變量,賦值:

  1. fun_ptr max_func=max; 

也就是說(shuō),賦給函數(shù)指針的函數(shù)應(yīng)該和函數(shù)指針?biāo)傅暮瘮?shù)原型是一致的。

例二、

 

  1. #include 
  2.  
  3. void FileFunc 
  4.  
  5.  
  6. printf("FileFunc\n"); 
  7.  
  8.  
  9. void EditFunc 
  10.  
  11.  
  12. printf("EditFunc\n"); 
  13.  
  14.  
  15. void main 
  16.  
  17.  
  18. typedef void (*funcp); 
  19.  
  20. funcp pfun= FileFunc; 
  21.  
  22. pfun; 
  23.  
  24. pfun = EditFunc; 
  25.  
  26. pfun; 
  27.  

看了上面兩段代碼,應(yīng)該都知道如何用函數(shù)指針來(lái)調(diào)用函數(shù)了,但是我們剛剛在上面的描述中留下過(guò)一個(gè)問(wèn)題,就是運(yùn)行注釋部分f=&max;結(jié)果是否還是正確的呢?下面我就給出上面兩個(gè)運(yùn)行結(jié)果的對(duì)別,然后來(lái)分析下原因。

C語(yǔ)言的那些小秘密之函數(shù)指針

 

把注釋部分加進(jìn)去的運(yùn)行結(jié)果為:

C語(yǔ)言的那些小秘密之函數(shù)指針

 

對(duì)比以上的運(yùn)行結(jié)果可以看出,f=&max語(yǔ)句被執(zhí)行時(shí)的結(jié)果和沒(méi)有被執(zhí)行時(shí)的結(jié)果是一樣的。為什么會(huì)出現(xiàn)這樣的結(jié)果呢?答案是這是編譯器處理的,max本身就是個(gè)地址,它沒(méi)有放到任何變量里,自然沒(méi)有取它的地址一說(shuō)。所以我們可以看看在調(diào)試的過(guò)程中&max的值和max的值是一樣的。調(diào)試代碼如下:

 

  1. root@ubuntu:/home/shiyan# gdb ss 
  2.  
  3. GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2 
  4.  
  5. Copyright (C) 2010 Free Software Foundation, Inc. 
  6.  
  7. License GPLv3+: GNU GPL version 3 or later 
  8.  
  9. This is free software: you are free to change and redistribute it. 
  10.  
  11. There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
  12.  
  13. and "show warranty" for details. 
  14.  
  15. This GDB was configured as "i686-linux-gnu"
  16.  
  17. For bug reporting instructions, please see: 
  18.  
  19. ... 
  20.  
  21. Reading symbols from /home/shiyan/ss...done. 
  22.  
  23. (gdb) list 
  24.  
  25. 1 #include 
  26.  
  27. 2 int max ( int x, int y){ return x>y?x:y;} 
  28.  
  29. 3 int min ( int x, int y){ return x 
  30.  
  31. 4 void main 
  32.  
  33. 5 { int ( *f ) ( int x, int y)=max; 
  34.  
  35. 6 //f=&max; 
  36.  
  37. 7 printf ( "%d,%d\t", max (2,6), (f)(5,4)); 
  38.  
  39. 8 f=min; 
  40.  
  41. 9 printf (" %d,%d\t" , min (2,6), (f)(5,4)); 
  42.  
  43. 10 } 
  44.  
  45. (gdb) b 4 
  46.  
  47. Breakpoint 1 at 0x80483ec: file hanshu.c, line 4
  48.  
  49. (gdb) r 
  50.  
  51. Starting program: /home/shiyan/ss 
  52.  
  53. Breakpoint 1, main at hanshu.c:5 
  54.  
  55. (gdb) print max 
  56.  
  57. $1 = {int (intint)} 0x80483c4 
  58.  
  59. (gdb) print f 
  60.  
  61. $2 = (int (*)(intint)) 0xbffff6c8 
  62.  
  63. (gdb) s 
  64.  
  65. (gdb) 
  66.  
  67. max (x=5, y=4) at hanshu.c:2 
  68.  
  69. 2 int max ( int x, int y){ return x>y?x:y;} 
  70.  
  71. (gdb) print max 
  72.  
  73. $3 = {int (intint)} 0x80483c4 
  74.  
  75. (gdb) print &max 
  76.  
  77. $4 = (int (*)(intint)) 0x80483c4 
  78.  
  79. (gdb) print *max 
  80.  
  81. $5 = {int (intint)} 0x80483c4 
  82.  
  83. (gdb) s 
  84.  
  85. max (x=2, y=6) at hanshu.c:2 
  86.  
  87. (gdb) s 
  88.  
  89. main at hanshu.c:8 
  90.  
  91. 8 f=min; 
  92.  
  93. (gdb) print min 
  94.  
  95. $6 = {int (intint)} 0x80483d3 
  96.  
  97. (gdb) print &min 
  98.  
  99. $7 = (int (*)(intint)) 0x80483d3 
  100.  
  101. (gdb) print *min 
  102.  
  103. $8 = {int (intint)} 0x80483d3 
  104.  
  105. (gdb) s 
  106.  
  107. 9 printf (" %d,%d\t" , min (2,6), (f)(5,4)); 
  108.  
  109. (gdb) print f 
  110.  
  111. $9 = (int (*)(intint)) 0x80483d3 
  112.  
  113. (gdb) print &f 
  114.  
  115. $10 = (int (**)(intint)) 0xbffff6ac 
  116.  
  117. (gdb) print *f 
  118.  
  119. $11 = {int (intint)} 0x80483d3 
  120.  
  121. (gdb) s 
  122.  
  123. min (x=5, y=4) at hanshu.c:3 
  124.  
  125. 3 int min ( int x, int y){ return x 
  126.  
  127. (gdb) s 
  128.  
  129. min (x=2, y=6) at hanshu.c:3 
  130.  
  131. (gdb) print min 
  132.  
  133. $12 = {int (intint)} 0x80483d3 
  134.  
  135. (gdb) s 
  136.  
  137. main at hanshu.c:10 
  138.  
  139. 10 } 

在調(diào)試的過(guò)程中我print了很多的信息,細(xì)心的讀者肯定能獲得更多的收獲,尤其是對(duì)變量f的print,讀者可以自己閱讀,學(xué)到更多的東西。我給出的只是一個(gè)參考的調(diào)試方式,希望讀者能夠舉一反三,自己對(duì)代碼進(jìn)行實(shí)際的調(diào)試,加深理解。

上面說(shuō)的都是用指針來(lái)實(shí)現(xiàn)函數(shù)的調(diào)用,接下來(lái)我們看一個(gè)用函數(shù)指針作為參數(shù)的用法。

  1. #include 
  2.  
  3. using namespace std; 
  4.  
  5. typedef int (*print)(int ); 
  6.  
  7. int fun1(int i) 
  8.  
  9.  
  10. return (int)i; 
  11.  
  12.  
  13. void fun2(int j,print prt) 
  14.  
  15.  
  16. for(int k=0;k 
  17.  
  18. cout<<'\t'
  19.  
  20.  
  21. void main 
  22.  
  23.  
  24. int i=10; 
  25.  
  26. fun2(i,fun1); 
  27.  

運(yùn)行結(jié)果如下:

 

 

看了上面的描述,我想都對(duì)函數(shù)指針的概念有了大致的了解,另外一個(gè)希望大家不要混淆的概念就是指針函數(shù),,這兩個(gè)概念都是簡(jiǎn)稱(chēng),指針函數(shù)是指帶指針的函數(shù),即本質(zhì)是一個(gè)函數(shù)。我們知道函數(shù)都又有返回類(lèi)型(如果不返回值,則為無(wú)值型,即為void),只不過(guò)指針函數(shù)返回類(lèi)型是某一類(lèi)型的指針。

其定義格式如下所示:

返回類(lèi)型標(biāo)識(shí)符 *返回名稱(chēng)(形式參數(shù)表)

{ 函數(shù)體}

返回類(lèi)型可以是任何基本類(lèi)型和復(fù)合類(lèi)型。返回指針的函數(shù)的用途十分廣泛。事實(shí)上,每一個(gè)函數(shù),即使它不帶有返回某種類(lèi)型的指針,它本身都有一個(gè)入口地址,該地址相當(dāng)于一個(gè)指針。比如函數(shù)返回一個(gè)整型值,實(shí)際上也相當(dāng)于返回一個(gè)指針變量的值,不過(guò)這時(shí)的變量是函數(shù)本身而已,而整個(gè)函數(shù)相當(dāng)于一個(gè)“變量”,關(guān)于函數(shù)的返回值問(wèn)題我將在下一章來(lái)講解,本章到此為止。希望以上內(nèi)容對(duì)你有所幫助!

C語(yǔ)言博大精深,由于本人水平有限,博客中的不妥或錯(cuò)誤之處在所難免,殷切希望讀者批評(píng)指正。同時(shí)也歡迎讀者共同探討相關(guān)的內(nèi)容,如果樂(lè)意交流的話(huà)請(qǐng)留下你寶貴的意見(jiàn)。

責(zé)任編輯:王雪燕 來(lái)源: 電子產(chǎn)品世界
相關(guān)推薦

2015-04-14 09:46:09

Apple Watch秘密

2019-08-30 08:39:33

WebSocketNginx服務(wù)器

2019-07-22 09:46:28

WebSocketNginx服務(wù)器

2025-03-19 08:40:00

2019-09-10 16:25:19

Python內(nèi)存空對(duì)象

2015-11-27 10:13:19

數(shù)據(jù)中心

2019-06-05 12:49:07

云辦公

2016-01-08 14:23:55

2012-03-23 10:27:08

觸屏手機(jī)點(diǎn)擊區(qū)域

2017-12-15 21:46:45

2010-05-13 00:03:44

2013-11-25 10:43:32

谷歌微軟

2018-08-15 08:47:20

2011-12-09 17:41:56

2010-10-12 12:10:52

增強(qiáng)無(wú)線(xiàn)網(wǎng)絡(luò)信號(hào)

2016-03-31 14:51:33

多云計(jì)算多云部署多云管理

2023-12-12 08:50:22

MySQL隱式轉(zhuǎn)換varchar

2015-03-06 10:33:02

2021-06-10 05:17:52

QQ應(yīng)用手機(jī)QQ

2015-11-09 11:24:48

數(shù)據(jù)中心數(shù)據(jù)中心優(yōu)化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩网站在线观看 | 亚洲国产精品人人爽夜夜爽 | 羞羞视频在线免费 | 亚洲日韩中文字幕一区 | 中文字幕一区二区三区四区 | 91精品导航 | 久久精品a级毛片 | 日韩午夜影院 | 亚洲免费在线播放 | 中文字幕亚洲视频 | 国产综合av| 91精品国产色综合久久 | 免费三级黄 | 亚洲成人一区 | 欧美一级片在线 | 亚洲一av| 日韩av在线免费 | 久久精品免费一区二区三 | 精品国产免费一区二区三区五区 | 成人国产免费观看 | 麻豆成人在线视频 | 欧美极品在线视频 | 色综合九九 | 毛片链接| 国产一二区免费视频 | 欧美国产大片 | 国产精品永久免费观看 | 亚州午夜精品 | 国产一区二区在线91 | www成人免费视频 | 人和拘一级毛片c | 色免费视频 | 国产探花在线精品一区二区 | 成人做爰www免费看 午夜精品久久久久久久久久久久 | 中文字字幕一区二区三区四区五区 | 国产精品久久久久久久久免费桃花 | 亚洲视频一区在线观看 | 黄色一级片在线播放 | 中文字幕免费 | 日韩免费一二三区 | 男女视频91 |