最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析C語言中函數(shù)指針的定義與使用

 更新時(shí)間:2016年04月20日 15:01:09   作者:慧可  
這篇文章主要介紹了C語言中函數(shù)指針的定義與使用,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下

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

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

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

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

  int function(int x,int y); /* 聲明一個(gè)函數(shù) */

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

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

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

2.函數(shù)指針使用的例子 
知道了如何定義一個(gè)函數(shù)指針,但如何來使用它呢?先看如下例子:

#include <stdio.h>
#include <string.h>
 
char * fun(char * p1,char * p2)
{
  int i = 0;
  i = strcmp(p1,p2);
 
  if (0 == i)
  {
    return p1;
  }
  else
  {
    return p2;
  }
}
 
int main()
{
  char * (*pf)(char * p1,char * p2);
  pf = &fun;
  (*pf) ("aa","bb");
  return 0;
}

  我們使用指針的時(shí)候,需要通過鑰匙(“*”)來取其指向的內(nèi)存里面的值,函數(shù)指針使用也如此。通過用(*pf)取出存在這個(gè)地址上的函數(shù),然后調(diào)用它。

  這里需要注意到是,在Visual C++6.0里,給函數(shù)指針賦值時(shí),可以用&fun或直接用函數(shù)名fun。這是因?yàn)楹瘮?shù)名被編譯之后其實(shí)就是一個(gè)地址,所以這里兩種用法沒有本質(zhì)的差別。這個(gè)例子很簡單,就不再詳細(xì)討論了。

3.*(int*)&p ----這是什么?

  也許上面的例子過于簡單,我們看看下面的例子:

void Function()
{
  printf("Call Function!\n");
}<br>
int main()
{
  void (*p)();
  *(int*)&p=(int)Function;
  (*p)();
  return 0;
} 

這是在干什么?*(int*)&p=(int)Function;表示什么意思?
別急,先看這行代碼:

void (*p)();

這行代碼定義了一個(gè)指針變量p,p指向一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)和返回值都是void。
&p是求指針變量p本身的地址,這是一個(gè)32位的二進(jìn)制常數(shù)(32位系統(tǒng))。
(int*)&p表示將地址強(qiáng)制轉(zhuǎn)換成指向int類型數(shù)據(jù)的指針。
(int)Function表示將函數(shù)的入口地址強(qiáng)制轉(zhuǎn)換成int類型的數(shù)據(jù)。
分析到這里,相信你已經(jīng)明白*(int*)&p=(int)Function;表示將函數(shù)的入口地址賦值給指針變量p。


那么(*p) ();就是表示對函數(shù)的調(diào)用。


講解到這里,相信你已經(jīng)明白了。其實(shí)函數(shù)指針與普通指針沒什么差別,只是指向的內(nèi)容不同而已。
使用函數(shù)指針的好處在于,可以將實(shí)現(xiàn)同一功能的多個(gè)模塊統(tǒng)一起來標(biāo)識,這樣一來更容易后期的維護(hù),系統(tǒng)結(jié)構(gòu)更加清晰?;蛘邭w納為:便于分層設(shè)計(jì)、利于系統(tǒng)抽象、降低耦合度以及使接口與實(shí)現(xiàn)分開。

4.(*(void(*) ())0)()------這是什么?

是不是感覺上面的例子太簡單,不夠刺激?好,那就來點(diǎn)刺激的,看下面這個(gè)例子:

(*(void(*) ())0)();

這是《C Traps and Pitfalls》這本經(jīng)典的書中的一個(gè)例子。沒有發(fā)狂吧?下面我們就來分析分析:

第一步:void(*) (),可以明白這是一個(gè)函數(shù)指針類型。這個(gè)函數(shù)沒有參數(shù),沒有返回值。
第二步:(void(*) ())0,這是將0強(qiáng)制轉(zhuǎn)換為函數(shù)指針類型,0是一個(gè)地址,也就是說一個(gè)函數(shù)存在首地址為0的一段區(qū)域內(nèi)。
第三步:(*(void(*) ())0),這是取0地址開始的一段內(nèi)存里面的內(nèi)容,其內(nèi)容就是保存在首地址為0的一段區(qū)域內(nèi)的函數(shù)。
第四步:(*(void(*) ())0)(),這是函數(shù)調(diào)用。

好像還是很簡單是吧,上面的例子再改寫改寫:

(*(char**(*) (char **,char **))0) ( char **,char **);

如果沒有上面的分析,肯怕不容易把這個(gè)表達(dá)式看明白吧。不過現(xiàn)在應(yīng)該是很簡單的一件事了。讀者以為呢?

5.函數(shù)指針數(shù)組

現(xiàn)在我們清楚表達(dá)式

char * (*pf)(char * p);

定義的是一個(gè)函數(shù)指針pf。既然pf是一個(gè)指針,那就可以儲存在一個(gè)數(shù)組里。把上式修改一下:

char * (*pf[3])(char * p);

這是定義一個(gè)函數(shù)指針數(shù)組。

它是一個(gè)數(shù)組,數(shù)組名為pf,數(shù)組內(nèi)存儲了3個(gè)指向函數(shù)的指針。這些指針指向一些返回值類型為指向字符的指針、參數(shù)為一個(gè)指向字符的指針的函數(shù)。

這念起來似乎有點(diǎn)拗口。不過不要緊,關(guān)鍵是你明白這是一個(gè)指針數(shù)組,是數(shù)組。函數(shù)指針數(shù)組怎么使用呢?這里也給出一個(gè)非常簡單的例子,只要真正掌握了使用方法,再復(fù)雜的問題都可以應(yīng)對。

如下:

#include <stdio.h>
#include <string.h>
<br>char * fun1(char * p)
{
  printf("%s\n",p);
  return p;
}
 
char * fun2(char * p)
{
  printf("%s\n",p);
  return p;
}
char * fun3(char * p)
{
  printf("%s\n",p);
  return p;
}
<br>int main()
{
  char * (*pf[3])(char * p);
  pf[0] = fun1; //可以直接用函數(shù)名
  pf[1] = &fun2; //可以用函數(shù)名加上取地址符
  pf[2] = &fun3;<br>
  pf[0]("fun1");
  pf[0]("fun2");
  pf[0]("fun3");
  return 0;
} 

 

6.函數(shù)指針數(shù)組的指針


  看著這個(gè)標(biāo)題沒發(fā)狂吧?函數(shù)指針就夠一般初學(xué)者折騰了,函數(shù)指針數(shù)組就更加麻煩,現(xiàn)在的函數(shù)指針數(shù)組指針就更難理解了。
其實(shí),沒這么復(fù)雜。前面詳細(xì)討論過數(shù)組指針的問題,這里的函數(shù)指針數(shù)組指針不就是一個(gè)指針嘛。只不過這個(gè)指針指向一個(gè)數(shù)組,這個(gè)數(shù)組里面存的都是指向函數(shù)的指針。僅此而已。


下面就定義一個(gè)簡單的函數(shù)指針數(shù)組指針:

char * (*(*pf)[3])(char * p);

注意,這里的pf和上一節(jié)的pf就完全是兩碼事了。上一節(jié)的pf并非指針,而是一個(gè)數(shù)組名;這里的pf確實(shí)是實(shí)實(shí)在在的指針。這個(gè)指針指向一個(gè)包含了3個(gè)元素的數(shù)組;這個(gè)數(shù)字里面存的是指向函數(shù)的指針;這些指針指向一些返回值類型為指向字符的指針、參數(shù)為一個(gè)指向字符的指針的函數(shù)。

  這比上一節(jié)的函數(shù)指針數(shù)組更拗口。其實(shí)你不用管這么多,明白這是一個(gè)指針就ok了。其用法與前面講的數(shù)組指針沒有差別。下面列一個(gè)簡單的例子:

#include <stdio.h>
#include <string.h>
 
char * fun1(char * p)
{
  printf("%s\n",p);
  return p;
}
 
char * fun2(char * p)
{
  printf("%s\n",p);
  return p;
}
 
char * fun3(char * p)
{
  printf("%s\n",p);
  return p;
}
 
int main()
{
  char * (*a[3])(char * p);
  char * (*(*pf)[3])(char * p);
  pf = &a;
 
  a[0] = fun1;
  a[1] = &fun2;
  a[2] = &fun3;
 
  pf[0][0]("fun1");
  pf[0][1]("fun2");
  pf[0][2]("fun3");
  return 0;
}

相關(guān)文章

  • 淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用

    淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用

    下面小編就為大家?guī)硪黄獪\談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • C++學(xué)校運(yùn)動(dòng)會(huì)管理系統(tǒng)的實(shí)現(xiàn)

    C++學(xué)校運(yùn)動(dòng)會(huì)管理系統(tǒng)的實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了C++如何實(shí)現(xiàn)學(xué)校運(yùn)動(dòng)會(huì)管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • C 語言插入排序算法及實(shí)例代碼

    C 語言插入排序算法及實(shí)例代碼

    本文主要介紹C語言插入排序,這里給大家詳細(xì)介紹插入排序的思想并舉例說明,還有實(shí)現(xiàn)代碼,有需要的朋友可以參考下
    2016-07-07
  • C語言 自定義類型全面系統(tǒng)理解

    C語言 自定義類型全面系統(tǒng)理解

    在C語言中自定義類型主要有結(jié)構(gòu)體類型、位段、枚舉類型、聯(lián)合體類型,自定義類型是面試常會(huì)碰到的內(nèi)容,本篇文章帶你徹底解決自定義類型
    2022-02-02
  • Linux 軟件看門狗 watchdog使用介紹

    Linux 軟件看門狗 watchdog使用介紹

    這篇文章主要介紹了Linux 軟件看門狗 watchdog使用介紹,需要的朋友可以參考下
    2016-10-10
  • C語言實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì)

    C語言實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)圖書管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • C語言模擬實(shí)現(xiàn)庫函數(shù)詳解

    C語言模擬實(shí)現(xiàn)庫函數(shù)詳解

    C語言庫函數(shù)是把自定義函數(shù)放到庫里,是別人把一些常用到的函數(shù)編完放到一個(gè)文件里,供程序員使用,下面讓我們一起來詳細(xì)了解它
    2022-07-07
  • C語言手寫多級時(shí)間輪定時(shí)器

    C語言手寫多級時(shí)間輪定時(shí)器

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)手寫多級時(shí)間輪定時(shí)器,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-09-09
  • 關(guān)于C語言位運(yùn)算的簡單示例

    關(guān)于C語言位運(yùn)算的簡單示例

    這篇文章主要介紹了關(guān)于C語言位運(yùn)算的簡單示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • C++使用sort對容器排序的實(shí)現(xiàn)

    C++使用sort對容器排序的實(shí)現(xiàn)

    C++ STL 標(biāo)準(zhǔn)庫中的sort()函數(shù)專門用來對容器或普通數(shù)組中指定范圍內(nèi)的元素進(jìn)行排序,本文就詳細(xì)的介紹一下怎么實(shí)現(xiàn),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評論

格尔木市| 广南县| 苍山县| 渭源县| 乐陵市| 南开区| 宁河县| 保康县| 定远县| 武川县| 无棣县| 徐闻县| 富顺县| 安泽县| 长丰县| 广宁县| 修水县| 绥江县| 应城市| 龙州县| 微博| 娄烦县| 恭城| 正阳县| 浮山县| 林口县| 耒阳市| 华容县| 公安县| 万山特区| 湟中县| 梅州市| 巴青县| 锡林郭勒盟| 丹巴县| 云梦县| 榆林市| 长乐市| 察隅县| 玉林市| 滨州市|