| 導購 | 订阅 | 在线投稿
分享
 
 
 

C/C++中函數指針的含義

來源:互聯網  2008-06-01 02:03:46  評論

函數存放在內存的代碼區域內,它們同樣有地址,我們如何能獲得函數的地址呢?

假如我們有一個int test(int a)的函數,那麽,它的地址就是函數的名字,這一點如同數組一樣,數組的名字就是數組的起始地址。

定義一個指向函數的指針用如下的形式,以上面的test()爲例: int (*fp)(int a);//這裏就定義了一個指向函數的指針 函數指針不能絕對不能指向不同類型,或者是帶不同形參的函數,在定義函數指針的時候我們很輕易犯如下的錯誤。int *fp(int a);//這裏是錯誤的,因爲按照結合性和優先級來看就是先和()結合,然後變成了一個返回整形指針的函數了,而不是函數指針,這一點尤其需要注重! 下面我們來看一個具體的例子:#include <iostream>

#include <string>

using namespace std;

int test(int a);

void main(int argc,char* argv[])

{

cout<<test<<endl;//顯示函數地址

int (*fp)(int a);

fp=test;//將函數test的地址賦給函數學指針fp

cout<<fp(5)<<""<<(*fp)(10)<<endl;

//上面的輸出fp(5),這是標准c++的寫法,(*fp)(10)這是兼容c語言的標准寫法,兩種同意,但注重區分,避免寫的程序産生移植性問題!

cin.get();

}

int test(int a)

{

return a;

}typedef定義可以簡化函數指針的定義,在定義一個的時候感覺不出來,但定義多了就知道方便了,上面的代碼改寫成如下的形式:#include <iostream>

#include <string>

using namespace std;

int test(int a);

void main(int argc,char* argv[])

{

cout<<test<<endl;

typedef int (*fp)(int a);//注重,這裏不是生命函數指針,而是定義一個函數指針的類型,這個類型是自己定義的,類型名爲fp

fp fpi;//這裏利用自己定義的類型名fp定義了一個fpi的函數指針!

fpi=test;

cout<<fpi(5)<<""<<(*fpi)(10)<<endl;

cin.get();

}

int test(int a)

{

return a;

}


C/C++中函數指針的含義
更多內容請看C/C++技術專題專題,或

函數指針同樣是可以作爲參數傳遞給函數的,下面我們看個例子,仔細閱讀你將會發現它的用處,稍加推理可以很方便我們進行一些複雜的編程工作。

//-------------------該例以上一個例子作爲基礎稍加了修改-----------------------------

#include <iostream>

#include <string>

using namespace std;

int test(int);

int test2(int (*ra)(int),int);

void main(int argc,char* argv[])

{

cout<<test<<endl;

typedef int (*fp)(int);

fp fpi;

fpi=test;//fpi賦予test 函數的內存地址

cout<<test2(fpi,1)<<endl;//這裏調用test2函數的時候,這裏把fpi所存儲的函數地址(test的函數地址)傳遞了給test2的第一個形參

cin.get();

}

int test(int a)

{

return a-1;

}

int test2(int (*ra)(int),int b)//這裏定義了一個名字爲ra的函數指針

{

int c=ra(10)+b;//在調用之後,ra已經指向fpi所指向的函數地址即test函數

return c;

} 利用函數指針,我們可以構成指針數組,更明確點的說法是構成指向函數的指針數組,這麽說可能就輕易理解的多了。#include <iostream>

#include <string>

using namespace std;

void t1(){cout<<"test1";}

void t2(){cout<<"test2";}

void t3(){cout<<"test3";}

void main(int argc,char* argv[])

{

void* a[]={t1,t2,t3};

cout<<"比較t1()的內存地址和數組a[0]所存儲的地址是否一致"<<t1<<""<<a[0]<<endl;

cout<<a[0]();//錯誤!指針數組是不能利用數組下標操作調用函數的

typedef void (*fp)();//自定義一個函數指針類型

fp b[]={t1,t2,t3}; //利用自定義類型fp把b[]定義趁一個指向函數的指針數組

b[0]();//現在利用指向函數的指針數組進行下標操作就可以進行函數的間接調用了;

cin.get();

} 仔細看上面的例子可能不用我多說大家也會知道是怎麽一會事情了,最後我們做一個重點小結,只要記住這一點,對于理解利用函數指針構成數組進行函數間接調用就很輕易了! void* a[]={t1,t2,t3};

cout<<"比較t1()的內存地址和數組a[0]所存儲的地址是否一致"<<t1<<""<<a[0]<<endl;

cout<<a[0]();//錯誤!指針數組是不能利用數組下標操作調用函數的 上面的這一小段中的錯誤行,爲什麽不能這麽調用呢?

前一篇教程我們已經說的很清楚了,不過在這裏我們還是複習一下概念,指針數組元素所保存的只是一個內存地址,既然只是個內存地址就不可能進行a[0]()這樣地址帶括號的操作,而函數指針不同它是一個例外,函數指針只所以這麽叫它就是因爲它是指向函數指向內存的代碼區的指針,它被系統授予答應與()括號操作的權利,進行間接的函數調用,既然函數指針答應這麽操作,那麽被定義成函數指針的數組就一定是可以一樣的操作的。

C/C++中函數指針的含義
更多內容請看C/C++技術專題專題,

  函數存放在內存的代碼區域內,它們同樣有地址,我們如何能獲得函數的地址呢?   假如我們有一個int test(int a)的函數,那麽,它的地址就是函數的名字,這一點如同數組一樣,數組的名字就是數組的起始地址。   定義一個指向函數的指針用如下的形式,以上面的test()爲例: int (*fp)(int a);//這裏就定義了一個指向函數的指針   函數指針不能絕對不能指向不同類型,或者是帶不同形參的函數,在定義函數指針的時候我們很輕易犯如下的錯誤。int *fp(int a);//這裏是錯誤的,因爲按照結合性和優先級來看就是先和()結合,然後變成了一個返回整形指針的函數了,而不是函數指針,這一點尤其需要注重!   下面我們來看一個具體的例子:#include <iostream> #include <string> using namespace std; int test(int a); void main(int argc,char* argv[]) { cout<<test<<endl;//顯示函數地址 int (*fp)(int a); fp=test;//將函數test的地址賦給函數學指針fp cout<<fp(5)<<""<<(*fp)(10)<<endl; //上面的輸出fp(5),這是標准c++的寫法,(*fp)(10)這是兼容c語言的標准寫法,兩種同意,但注重區分,避免寫的程序産生移植性問題! cin.get(); } int test(int a) { return a; }  typedef定義可以簡化函數指針的定義,在定義一個的時候感覺不出來,但定義多了就知道方便了,上面的代碼改寫成如下的形式:#include <iostream> #include <string> using namespace std; int test(int a); void main(int argc,char* argv[]) { cout<<test<<endl; typedef int (*fp)(int a);//注重,這裏不是生命函數指針,而是定義一個函數指針的類型,這個類型是自己定義的,類型名爲fp fp fpi;//這裏利用自己定義的類型名fp定義了一個fpi的函數指針! fpi=test; cout<<fpi(5)<<""<<(*fpi)(10)<<endl; cin.get(); } int test(int a) { return a; } [url=/bbs/detail_1785275.html][img]http://image.wangchao.net.cn/it/1323424044603.gif[/img][/url] 更多內容請看C/C++技術專題專題,或   函數指針同樣是可以作爲參數傳遞給函數的,下面我們看個例子,仔細閱讀你將會發現它的用處,稍加推理可以很方便我們進行一些複雜的編程工作。 //-------------------該例以上一個例子作爲基礎稍加了修改----------------------------- #include <iostream> #include <string> using namespace std; int test(int); int test2(int (*ra)(int),int); void main(int argc,char* argv[]) { cout<<test<<endl; typedef int (*fp)(int); fp fpi; fpi=test;//fpi賦予test 函數的內存地址 cout<<test2(fpi,1)<<endl;//這裏調用test2函數的時候,這裏把fpi所存儲的函數地址(test的函數地址)傳遞了給test2的第一個形參 cin.get(); } int test(int a) { return a-1; } int test2(int (*ra)(int),int b)//這裏定義了一個名字爲ra的函數指針 { int c=ra(10)+b;//在調用之後,ra已經指向fpi所指向的函數地址即test函數 return c; }   利用函數指針,我們可以構成指針數組,更明確點的說法是構成指向函數的指針數組,這麽說可能就輕易理解的多了。#include <iostream> #include <string> using namespace std; void t1(){cout<<"test1";} void t2(){cout<<"test2";} void t3(){cout<<"test3";} void main(int argc,char* argv[]) { void* a[]={t1,t2,t3}; cout<<"比較t1()的內存地址和數組a[0]所存儲的地址是否一致"<<t1<<""<<a[0]<<endl; cout<<a[0]();//錯誤!指針數組是不能利用數組下標操作調用函數的 typedef void (*fp)();//自定義一個函數指針類型 fp b[]={t1,t2,t3}; //利用自定義類型fp把b[]定義趁一個指向函數的指針數組 b[0]();//現在利用指向函數的指針數組進行下標操作就可以進行函數的間接調用了; cin.get(); }   仔細看上面的例子可能不用我多說大家也會知道是怎麽一會事情了,最後我們做一個重點小結,只要記住這一點,對于理解利用函數指針構成數組進行函數間接調用就很輕易了! void* a[]={t1,t2,t3}; cout<<"比較t1()的內存地址和數組a[0]所存儲的地址是否一致"<<t1<<""<<a[0]<<endl; cout<<a[0]();//錯誤!指針數組是不能利用數組下標操作調用函數的   上面的這一小段中的錯誤行,爲什麽不能這麽調用呢?   前一篇教程我們已經說的很清楚了,不過在這裏我們還是複習一下概念,指針數組元素所保存的只是一個內存地址,既然只是個內存地址就不可能進行a[0]()這樣地址帶括號的操作,而函數指針不同它是一個例外,函數指針只所以這麽叫它就是因爲它是指向函數指向內存的代碼區的指針,它被系統授予答應與()括號操作的權利,進行間接的函數調用,既然函數指針答應這麽操作,那麽被定義成函數指針的數組就一定是可以一樣的操作的。 [url=/bbs/detail_1785275.html][img]http://image.wangchao.net.cn/it/1323424044647.gif[/img][/url] 更多內容請看C/C++技術專題專題, 或
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有