小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

函數(shù)指針及其的運用(上)——何為函數(shù)指針

 My鏡像站 2011-12-26

=========================引子=========================

      我們都知道,數(shù)組名就是指向數(shù)組第一個元素的常量指針(詳見《數(shù)組拾遺》)。同理,對于一個函數(shù)而言,函數(shù)名也是指向函數(shù)第一條指令的常量指針。而編譯器要做的就是在程序編譯之后,為每個函數(shù)分配一個首地址,即該函數(shù)第一條指令的地址。一般情況下,我們可以用一個指針來保存這個地址,而這個指針就是函數(shù)指針,該指針可以看作是它指向函數(shù)的別名,所以我們可以用該指針來調用這個函數(shù)。

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

type (*func)(type &,type &)

  該語句聲明了一個指針func,它指向了一個函數(shù),這個函數(shù)帶有了2個type型參數(shù)并返回一個type的值。

p.s. type類型可以被看成是int啊或者是floast等C++的類型。     

=========================注意事項=========================

  1. 一個指向函數(shù)的指針必須確保該函數(shù)被定義且分配了內存,否則它將指向一個空地址,這個可是大忌!
  2. 特別注意第一個括號的位置。如果我們不寫括號,如下:
type *func(type ,type)

  這就不是一個指向函數(shù)的指針了,而是聲明了一個函數(shù),該函數(shù)返回一個type類型的指針 

 =========================函數(shù)指針應用示例=========================

      我們以這樣一個程序為例:該程序的功能是計算三角形的矩形的面積。其中,三角形的長和高,矩形的長和寬由用戶自己輸入,并且我們提供一個交換函數(shù),用來交換用戶輸入的長和高(寬)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//例1 普通函數(shù)示例
#include <iostream>
using namespace std;
//函數(shù)聲明
double triangle_area(double &x,double &y);//三角形面積
double rectangle_area(double &x,double &y);//矩形面積
double swap_value(double &x,double &y);//交換值
double set_value(double &x,double &y);//設定長寬(高)
double print_area(double &x,double &y);//輸出面積
//函數(shù)定義
double triangle_area(double &x,double &y)
{
    return x*y*0.5;
}
 
double rectangle_area(double &x,double &y)
{
    return x*y;
}
 
double swap_value(double &x,double &y)
{
    double temp;
    temp=x;
    x=y;
    y=temp;
    return 0.0;
}
 
double print_area(double &x,double &y)
{
    cout<<"執(zhí)行函數(shù)后:\n";
    cout<<"x="<<x<<"  y="<<y<<endl;
    //coming soon in e.g.2...
    return 0.0;
}
 
double set_value(double &x,double &y)
//注意參數(shù)一定要定義成引用,要不是傳不出去哈!
{
    cout<<"自定義長寬(高)為:\n";
    cout<<"長為:";
    cin>>x;
    cout<<"寬或者高為:";
    cin>>y;
    return 0.0;
}
 
int main()
{
    bool quit=false;//初始化退出的值為否
    double a=2,b=3;//初始化兩個參數(shù)a和b
    char choice;
    while(quit==false)
    {
        cout<<"退出(q); 設定長、寬或高(1); 三角形面積(2); 矩形面積(3); 交換長寬或高(4)."<<endl;
        cin>>choice;
        switch(choice)
        {
            case 'q':
                quit=true;
                break;
            case '1':
                set_value(a,b);
                print_area(a,b);
                break;
            case '2':
                print_area(a,b);
                cout<<"三角形的面積為:\t"<<triangle_area(a,b)<<endl;
                break;
            case  '3':
                print_area(a,b);
                cout<<"矩形的面積為:\t"<<rectangle_area(a,b)<<endl;
                break;
            case '4':
                swap_value(a,b);
                print_area(a,b);
                break;
            default:
                cout<<"請按規(guī)矩出牌!"<<endl;
        }
    }
    return 0;
}

  在這個例子中,我們采用普通函數(shù)大方法,來輸出三角形和矩形的值,輸出如下:

      下面,我們來看看如果采用函數(shù)指針,效果會是怎樣?由于我們在前面分析過了,函數(shù)指針就是一個指向函數(shù)的指針。那么我們在調用函數(shù)的時候,就可以運用指針 來調用這個函數(shù)。而且,周所周知,指針可以作為一個函數(shù)的參數(shù),那么函數(shù)指針也不應該例外。這樣就好了,我們可以講函數(shù)的指針作為函數(shù)參數(shù)來調用。對于一 個普通要調用指針的函數(shù)而言,聲明應該是這個樣子的:

type func(type*, type , type)

  那么由上面這句話就可以看出來,這個函數(shù)func的第一個參數(shù)就是一個指向type類型的指針,而后面兩個參數(shù)就是兩個類型為type的形式參數(shù)。結合本文一開始所列的函數(shù)參數(shù)的聲明格式,那么函數(shù)指針作為函數(shù)參數(shù)的一般形式就是:

type func(type(*p)(type &, type &),type &,type &);

  該函數(shù)func有3個參數(shù),第一個參數(shù)為type(*p)(type &, type &),這就是一個函數(shù)指針,他指向一個帶有兩個type類型的參數(shù)并且返回type值的函數(shù),另外兩個參數(shù)都是type類型的引用。

      這樣一來,我們就可以利用函數(shù)指針把函數(shù)作為另外一個函數(shù)的參數(shù)調入到那個函數(shù)中使用了。對于上面這個例子,我故意把所有的函數(shù)都生聲明為帶有兩個 double類型的變量,且返回值均為double。這樣做的原因只是為了讓后面我們在利用函數(shù)指針調用的時候方便一些。因為我們只需要將函數(shù)指針聲明成 與之想匹配的函數(shù)就行了。從上面這個例子看出,它麻煩就麻煩在每次輸出的時候都需要在case語句中進行操作,那么我們能不能利用函數(shù)指針將其一并簡化到 print函數(shù)中呢,請看下例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//例2 函數(shù)指針示例
#include <iostream>
using namespace std;
//函數(shù)聲明
double triangle_area(double &x,double &y);//三角形面積
double rectangle_area(double &x,double &y);//矩形面積
double swap_value(double &x,double &y);//交換值
double set_value(double &x,double &y);//設定長寬(高)
// double print_area(double &x,double &y);//輸出面積
double print_area(double(*p)(double&,double&), double &x,double &y);//利用函數(shù)指針輸出面積
//函數(shù)定義
double triangle_area(double &x,double &y)
{
    cout<<"三角形的面積為:\t"<<x*y*0.5<<endl;
    return 0.0;
}
 
double rectangle_area(double &x,double &y)
{
    cout<<"矩形的面積為:\t"<<x*y<<endl;
    return 0.0;
}
 
double swap_value(double &x,double &y)
{
    double temp;
    temp=x;
    x=y;
    y=temp;
    return 0.0;
}
 
double print_area(double(*p)(double &x,double &y), double &x,double &y)
{
    cout<<"執(zhí)行函數(shù)前:\n";
    cout<<"x="<<x<<"  y="<<y<<endl;
    //it is coming!...
    p(x,y);
    cout<<"函數(shù)指針傳值后:\n";
    cout<<"x="<<x<<"  y="<<y<<endl;
    return 0.0;
}
 
double set_value(double &x,double &y)
//注意參數(shù)一定要定義成引用,要不是傳不出去哈!
{
    cout<<"自定義長寬(高)為:\n";
    cout<<"長為:";
    cin>>x;
    cout<<"寬或者高為:";
    cin>>y;
    return 0.0;
}
 
int main()
{
    bool quit=false;//初始化退出的值為否
    double a=2,b=3;//初始化兩個參數(shù)a和b
    char choice;
    //聲明的p為一個函數(shù)指針,它所指向的函數(shù)帶有梁個double類型的參數(shù)并且返回double
    double (*p)(double &,double &);
    while(quit==false)
    {
        cout<<"退出(q); 設定長、寬或高(1); 三角形面積(2); 矩形面積(3); 交換長寬或高(4)."<<endl;
        cin>>choice;
        switch(choice)
        {
        case 'q':
            quit=true;
            break;
        case '1':
            p=set_value;
            print_area(p,a,b);
            break;
        case '2':
            p=triangle_area;
            print_area(p,a,b);         
            break;
        case  '3':
            p=rectangle_area;
            print_area(p,a,b);
            break;
        case '4':
            p=swap_value;
            print_area(p,a,b);
            break;
        default:
            cout<<"請按規(guī)矩出牌!"<<endl;
        }
    }
    return 0;
}

      在例2中,我們采用了函數(shù)指針的方式,可以看到,在case語句中只需要制定每個函數(shù)指針所指向的函數(shù)是什么,那么在print函數(shù)中,我們就可以調用這個函數(shù)了。輸出如下所示:

      在該程序的第61行,我們就聲明了一個函數(shù)指針??梢钥吹?,在程序的case語句中,我們只需要把這個函數(shù)指針傳遞到print_area()函數(shù)里面就 可以了。這樣十分方便。而且我們可以看到,其實只要在print_area()中,即程序的第38行加上對這個函數(shù)指針的調用,我們就可以利用指針所指向 的函數(shù)了。這十分方便。但是有幾個小知識點應該注意一下:

  1. 聲明函數(shù)指針時,其返回值,參數(shù)個數(shù),參數(shù)類型應該與需要它指向的函數(shù)保持一致;否則,編譯器會報錯,無法從“***”轉換到“***”;
  2. 利用函數(shù)指針只想某個函數(shù)的時候,我們只用,也只能給出該函數(shù)的函數(shù)名,不能把參數(shù)一并給出了。比如說在上例中,如果我們把程序的第84行改成:
    p=swap_value(a,b);

     那么編譯器會報錯:
    func_pointer.cpp(84) : error C2440: “=”: 無法從“double”轉換為“double (__cdecl *)(double &,double &)
    這個錯誤的原因就是因為我們忘記了在文章一開頭所講的函數(shù)指針的一句話:函數(shù)名也是指向函數(shù)第一條指令的常量指針。因為函數(shù)指針就是指向其函數(shù)的地址的,那么我們就應該利用函數(shù)指針來指向函數(shù)名就可以了。

=========================補充一點哈 ^_^=========================

如果你認為上面所訴的函數(shù)指針的聲明格式有點羅嗦,那么我們也可以利用typedef來簡化聲明和定義的操作。比如說在上例2的第61行,那么長一串。我們完全可以在在程序一開始利用typedef來代替:

typedef double (*vp)(double &,double &);

  這樣一來,我們就可以把程序的第61行簡化成:

vp p;

  而且,我們在聲明和定義print_area()函數(shù)的時候,就可以程序的第10行和第33行換成:

//函數(shù)聲明
double print_area(vp,double &x,double &y);
//函數(shù)定義
double print_area(vp p, double &x,double &y)

  好了,關于函數(shù)指針就總結到這里,更多內容請關注“唯一的天空”其他內容,謝謝 ^_^。

敬請期待:博文《函數(shù)指針及其的運用(下)——函數(shù)指針的擴展》

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多