日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

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

 My鏡像站 2011-12-26

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

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

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

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

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

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

=========================注意事項(xiàng)=========================

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

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

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

      我們以這樣一個(gè)程序?yàn)槔涸摮绦虻墓δ苁怯?jì)算三角形的矩形的面積。其中,三角形的長(zhǎng)和高,矩形的長(zhǎng)和寬由用戶自己輸入,并且我們提供一個(gè)交換函數(shù),用來交換用戶輸入的長(zhǎng)和高(寬)。

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);//設(shè)定長(zhǎng)寬(高)
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<<"自定義長(zhǎng)寬(高)為:\n";
    cout<<"長(zhǎng)為:";
    cin>>x;
    cout<<"寬或者高為:";
    cin>>y;
    return 0.0;
}
 
int main()
{
    bool quit=false;//初始化退出的值為否
    double a=2,b=3;//初始化兩個(gè)參數(shù)a和b
    char choice;
    while(quit==false)
    {
        cout<<"退出(q); 設(shè)定長(zhǎng)、寬或高(1); 三角形面積(2); 矩形面積(3); 交換長(zhǎng)寬或高(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<<"請(qǐng)按規(guī)矩出牌!"<<endl;
        }
    }
    return 0;
}

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

      下面,我們來看看如果采用函數(shù)指針,效果會(huì)是怎樣?由于我們?cè)谇懊娣治鲞^了,函數(shù)指針就是一個(gè)指向函數(shù)的指針。那么我們?cè)谡{(diào)用函數(shù)的時(shí)候,就可以運(yùn)用指針 來調(diào)用這個(gè)函數(shù)。而且,周所周知,指針可以作為一個(gè)函數(shù)的參數(shù),那么函數(shù)指針也不應(yīng)該例外。這樣就好了,我們可以講函數(shù)的指針作為函數(shù)參數(shù)來調(diào)用。對(duì)于一 個(gè)普通要調(diào)用指針的函數(shù)而言,聲明應(yīng)該是這個(gè)樣子的:

type func(type*, type , type)

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

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

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

      這樣一來,我們就可以利用函數(shù)指針把函數(shù)作為另外一個(gè)函數(shù)的參數(shù)調(diào)入到那個(gè)函數(shù)中使用了。對(duì)于上面這個(gè)例子,我故意把所有的函數(shù)都生聲明為帶有兩個(gè) double類型的變量,且返回值均為double。這樣做的原因只是為了讓后面我們?cè)诶煤瘮?shù)指針調(diào)用的時(shí)候方便一些。因?yàn)槲覀冎恍枰獙⒑瘮?shù)指針聲明成 與之想匹配的函數(shù)就行了。從上面這個(gè)例子看出,它麻煩就麻煩在每次輸出的時(shí)候都需要在case語句中進(jìn)行操作,那么我們能不能利用函數(shù)指針將其一并簡(jiǎn)化到 print函數(shù)中呢,請(qǐng)看下例:

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);//設(shè)定長(zhǎng)寬(高)
// 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<<"自定義長(zhǎng)寬(高)為:\n";
    cout<<"長(zhǎng)為:";
    cin>>x;
    cout<<"寬或者高為:";
    cin>>y;
    return 0.0;
}
 
int main()
{
    bool quit=false;//初始化退出的值為否
    double a=2,b=3;//初始化兩個(gè)參數(shù)a和b
    char choice;
    //聲明的p為一個(gè)函數(shù)指針,它所指向的函數(shù)帶有梁個(gè)double類型的參數(shù)并且返回double
    double (*p)(double &,double &);
    while(quit==false)
    {
        cout<<"退出(q); 設(shè)定長(zhǎng)、寬或高(1); 三角形面積(2); 矩形面積(3); 交換長(zhǎng)寬或高(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<<"請(qǐng)按規(guī)矩出牌!"<<endl;
        }
    }
    return 0;
}

      在例2中,我們采用了函數(shù)指針的方式,可以看到,在case語句中只需要制定每個(gè)函數(shù)指針?biāo)赶虻暮瘮?shù)是什么,那么在print函數(shù)中,我們就可以調(diào)用這個(gè)函數(shù)了。輸出如下所示:

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

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

     那么編譯器會(huì)報(bào)錯(cuò):
    func_pointer.cpp(84) : error C2440: “=”: 無法從“double”轉(zhuǎn)換為“double (__cdecl *)(double &,double &)
    這個(gè)錯(cuò)誤的原因就是因?yàn)槲覀兺浟嗽谖恼乱婚_頭所講的函數(shù)指針的一句話:函數(shù)名也是指向函數(shù)第一條指令的常量指針。因?yàn)楹瘮?shù)指針就是指向其函數(shù)的地址的,那么我們就應(yīng)該利用函數(shù)指針來指向函數(shù)名就可以了。

=========================補(bǔ)充一點(diǎn)哈 ^_^=========================

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

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

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

vp p;

  而且,我們?cè)诼暶骱投xprint_area()函數(shù)的時(shí)候,就可以程序的第10行和第33行換成:

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

  好了,關(guān)于函數(shù)指針就總結(jié)到這里,更多內(nèi)容請(qǐng)關(guān)注“唯一的天空”其他內(nèi)容,謝謝 ^_^。

敬請(qǐng)期待:博文《函數(shù)指針及其的運(yùn)用(下)——函數(shù)指針的擴(kuò)展》

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多