函數指針 與指針hanshu
1 函數指針 是指向函數的指針變量 程序在編譯時 每一個函數都有一個入口地址 該入口地址就是函數指針所指向的地址
函數指針有兩個用途 調用函數和做函數的參數
int fun(int x){return 0;} /// 定義一個函數
int main()
{
int(*pf)(int x);///聲明一個函數指針
pf=fun;/// 將函數首地址賦給指針 pf
cout<<fun<<endl;
printf("%x\n",fun);// 返回函數地址
cout<<pf<<endl;
}
或可以使用typedef 來定義函數指針
typedef int(*PF)(int x); 定義一個函數指針類型 PF pf 聲明 pf 變量 pf=fun 賦值
通過函數指針調用函數的例子
int maxone(int x,int y) { int z; z=(x>y)?x:y; return z; } int main() { int i,a,b; int(*p)(int ,int ); ///定義函數指針 cin>>a; p=maxone;///給函數指針 p 賦值 for(i=0;i<2;i++) { cin>>b; a=(*p)(a,b);/// 通過指針P 調用函數 } cout<<"the max number is"<<a<<endl; return 0; }
函數指針作為參數
#include<iostream> #include<cmath> using namespace std; double romb(double(*fun)(double),double a,double b,double eps)/// fun 就是一個函數指針 { double y[9],h,p,q,ep,s,l; int m,n,k,i; h=b-a; y[0]=h*((*fun)(a)+(*fun)(b))/2;/// 用函數指針來求取 a b 點的值 m=1; n=1; ep=eps+1; while(ep>=eps&&m<=9) { p=0; for(i=0;i<n;i++) { l=a+(i+0.5)*h; p+=(*fun)(l); } p=(y[0]+h*p)/2; s=1; for(k=1;k<m;k++) { s*=4; q=(s*p-y[k-1])/(s-1); y[k-1]=p; p=q; } ep=fabs(q-y[m-1]); m++; y[m-1]=q; n*=2; h/=2; } return q; } double fx(double x) { return sin(x); } int main() { printf("%f\n",romb(fx,0,3.1415926,0.0001)); return 0; }
被積函數作為積分函數的參數 也就是函數作為參數 即函數指針。
操作系統中經常會使用回調函數 callBack 函數,實際上所謂回調函數 本質上是函數指針。回調函數就是一個通過函數指針調用的函數。假如把函數指針作為參數傳遞給另一個函數 當這個指針被
調用時 我們就說這是回調函數
2 指針函數 是指返回值為指針的函數 即本質是一個函數
int *func(int x,int y) // 定義了一個函數 返回一個指向整型數的指針 * 號表明這是一個指針型函數 即返回值是一個指針
下例中 month 為一指針數組 數組中的每個指針指向一個字符串常量 trans 需要一個整型變量作為實參 返回一個字符型指針 再判斷m是否合法 這樣指針p就可以指向對應的字符串常量 變量p保存的是一個地址 函數返回該變量
#include<iostream> #include<cmath> using namespace std; char *month[]={"illegal month","January","February","March","April","May","June","July" "August","September","October","November","December"}; char *trans(int m) { char *p; if(m>=1&&m<=12) p=month[m]; else p=month[0]; return p; } int main() { int i; cin>>i; cout<<trans(i)<<endl; }
3 返回函數指針的函數
#include<iostream> using namespace std; int add(int x,int y) { int i=x+y; return i; } int (*funcptr())(int ,int ) { return add; } int main() { int(*fptr)(int,int)=funcptr(); cout<<fptr(10,10)<<endl; return 0; }
第二個函數funcptr 是這個函數的函數名稱,裏面的括號 是它本身的參數括號符 即該函數沒有參數 而它前面的* 表示返回的是一個指針,後面的() 表示這是一個函數指針,並且
該函數指針所指向的函數有兩個int型的參數 最前面的int 表示該函數指針所指向的函數返回值為int型 然後在main函數裏面定義了一個函數指針變量fptr 接收funcptr 返回的函數指針值
之後通過 fptr 調用函數add
typedef int(*RetFunptr)(int,int) RetFunptr fptr=funcptr();
4 函數指針實現重載 c語言
#include<iostream> using namespace std; typedef struct int_param { int param1; int param2; }INT_PARAM; typedef struct double_param { double param1; double param2; }DOUBLE_PARAM; typedef void *(*ADDFUNC)(void*); void *int_add_func(void *wparam) { INT_PARAM*lparam=(INT_PARAM*)wparam; int *res=new int; *res=lparam->param1+lparam->param2; return (void*)res; } void*double_add_func(void*wparam) { DOUBLE_PARAM*lparam=(DOUBLE_PARAM*)wparam; double *res=new double; *res=lparam->param1+lparam->param2; return (void*)res; } void *add_func(ADDFUNC f,void *wparam) { return f(wparam); } int main() { INT_PARAM val1={2,2}; DOUBLE_PARAM val2={3.3,3.3}; void *res1=add_func(int_add_func,&val1); int result1=*((int *)res1); cout<<result1<<endl; void *res2=add_func(double_add_func,&val2); double result2=*((double*)res2); cout<<result2<<endl; delete res1; delete res2; return 0; }
結構體中 int_param 中有兩個int型數據,結構體中 double_param 中有兩個double 型數據 程序要求對這兩個函數求和
typedef void *(*ADDFUNC)(void*);
ADDFUNC f
通過ADDFUNC定義了一個函數指針f
void *add_func(ADDFUNC f,void *wparam) { return f(wparam); }
add_func 是一個返回指針的函數 有兩個參數,第一個是一個函數指針,第二個是 void* 參數 調用 add_func 時 f指向了一個參數和返回值都是void *的函數
在add_func 中通過f來調用 int_add_func 和 double_add_func
void *int_add_func(void *wparam) { INT_PARAM*lparam=(INT_PARAM*)wparam; int *res=new int; *res=lparam->param1+lparam->param2; return (void*)res; } void*double_add_func(void*wparam) { DOUBLE_PARAM*lparam=(DOUBLE_PARAM*)wparam; double *res=new double; *res=lparam->param1+lparam->param2; return (void*)res; }
這兩個函數傳進來的參數 分別為 int_param 和 double——param 結構體變量中的指針 對傳過來的參數求和後 保存在堆區上創建的res中 之後將res 返回
在main函數中 res1 res2 分別接收 int_add_func 和 double_add_func 返回的指針 在程序結束時 delete 釋放堆上的內存
函數指針 與指針hanshu