1. 程式人生 > >函數指針 與指針hanshu

函數指針 與指針hanshu

-a using abs oct 並且 是否 n) bsp mon

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