设为首页收藏本站|繁體中文 快速切换版块

 找回密码
 立即加入
搜索
查看: 888|回复: 0

函数与函数指针 (必须弄清楚)

[复制链接]
  • TA的每日心情
    慵懒
    2016-4-21 12:07
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    累计签到:3 天
    连续签到:1 天
    发表于 2010-5-14 07:04:59 | 显示全部楼层 |阅读模式

    马上加入,结交更多好友,共享更多资料,让你轻松玩转电力研学社区!

    您需要 登录 才可以下载或查看,没有账号?立即加入

    ×
    C中最重要 最难的就是 指针咯!9 S; U/ Q: |1 n* h, V: l

    ' _2 d4 ~5 b) H. ^0 C* H! J3 _1 m5 q
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    . ~2 v4 j* l7 g  快速排序的原型:1 X6 x' C: P3 H, d  h
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    # K# l! Z6 `5 x9 \) ?: r/ X  V' @  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    ( j2 v. Z4 U* e3 y8 Z #include <stdio.h> # C/ C! t6 h, a: C0 ]: W
    #include
    <stdlib.h>
    2 r  E& t% T0 eint sort_function( const
    . p' U9 ?9 [: N6 }" Y% n; |void
    $ t: {& c8 z. B1 K*a, const
    / P: ~( c% t( ?1 yvoid$ n! h! E! Y% V) A3 f9 n
    *b);
    , Y' N" V0 X) J
    int list[5] = { 54, 21, 11, 67, 22 };
    0 o3 ~; n# k7 D2 t5 E* F; h+ [0 X2 ^/ [  B2 w2 {" ^. A7 \$ D
    int main(void) 6 p6 @  r* r  b/ ?) d
    { % M% m4 h0 ?, w( V; R
       
    int x; ! g$ ~! A" E5 |* G6 R$ |7 i, B
    3 h# Z( F3 s$ F. H9 @- M
       qsort((
    void9 h* a/ e0 P% l1 m& }
    *)list, 5, sizeof(list[0]), sort_function);
    / E% ^* o% M- b9 k4 Q   
    for (x =
    . D: L% s+ J% {% T! j* w) n7 l0; x <4 C/ {$ K& A. m9 J5 d" ^
    5; x++) - ]: j1 t+ @( @4 G' r* Z
       printf(
    "%i\n", list[x]); 0 T# V" `$ u$ {; [! |
       
    return7 n/ M1 U6 @2 u0 q; f6 k- M
    0; * J+ u- J& m! ~3 u+ I6 _/ k! S
    }
    ' @9 r/ W& N# E7 y. {' d9 z
    / r8 ?) A4 `$ `
    int sort_function( const
    ( ?& O! Z: Q3 K* ovoid+ t5 _$ R4 J" t6 ~' L
    *a, const! B" F/ U! o; q. u$ [
    void
    , I' [" k; q3 [2 c3 N*b)
    4 u4 ?) _# K+ O% c{
      m2 N( ^- G* m! N   
    return9 t- k8 c4 S  ^) N
    *(int*)a-*(int*)b; 0 Y0 N( }$ w4 Y2 F5 \$ x
    }
    4 s7 O% G0 t  m, Q/ @+ \3 t
    , @1 O3 b- z5 [2 x. U$ q+ M

    5 b# m3 p/ @9 T
    7 k' s5 P/ L9 r! {1 F* H" A  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    2 I5 o) \; C2 V) Z$ _+ w% g! i  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>1 [+ I& C8 ?- J8 G8 a- \* J, c
      ~/ k# s) }$ n1 |1 w5 O+ N' d
    # h% a- R: l7 x
    void MyFun(int x);7 q( S3 b4 ?. F9 g
    typedef
    void (*FunP)(int);
    0 o" t+ }5 w) V) x; X7 G5 U; G8 I9 X. W8 f
    FunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;/ m% U5 z$ t; B; ?) y
    5 S* l" v8 m- D- `  U+ B3 n3 F# q
    int main(int argc, char* argv[])
    6 F. T% {5 `8 c9 J  O{) }$ \8 W  h9 ?0 r! |: ?
       MyFun(
    10);                        //这里是调用MyFun(10);函数' @/ D3 z1 \& k2 t% g* Q
    + A2 J0 M' a% \+ o/ C& I+ r, T
       fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    ! }* |  ~" i) m3 r: [! i" j: N/ x  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        ) u, e+ o% t0 t& r

    3 o0 K5 t* q( `; D% k1 a- `& e2 q   fp2
    =&MyFun;                        $ T# H4 L0 T! F! @
       fp2(
    30);    : \3 g8 B. K+ v
    * v8 _  n1 @8 @
       fp3
    =MyFun;                        , L5 M4 p" u/ j. ^# o& D7 m7 ]. O  W
       fp3(
    40);   
    # U4 Z/ ?0 @- Y- Y, v
    9 x6 }0 |3 O) y) w' Y   fp4
    =MyFun;  
    ; v4 j0 d  R# T* o: J. P; R   (
    *fp4)(50);   
    # }& P( B& f: r) u! Q" r) L; _7 H8 h6 |- L. r9 s1 |# `2 n
       
    return
    4 i  Y  j7 \4 B$ H% I/ H0;
    ( r. @% q, h8 T' A# d( t}. _, X/ k/ P* x$ L7 k$ O# {

    & L, S7 N) M% c! n
    void MyFun(int x)                     //这里定义一个MyFun函数
    7 d3 U5 m" T7 `( a4 v8 L$ _, X+ R. Y{
    " q( o3 R; x4 O! @: }9 {   printf(
    "%d\n",x);$ c; x0 W+ Z7 K
    }

    5 E3 ?4 i. w+ u/ X$ S5 J' Y' G3 m) l) U+ O! |
    : c  g2 g* X2 j/ Y6 t6 ]
    1 E8 t! ]* M9 J0 t0 L: o0 n5 x
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。& t5 ]3 p1 Q8 \! j! e$ C* y
    2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。4 I4 P3 d# P2 }1 s3 v7 S, z# D* W
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。/ H& h5 n% z/ E7 H! J
    4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

    小黑屋|手机版|APP下载(beta)|Archiver|电力研学网 ( 赣ICP备12000811号-1|赣公网安备36040302000210号 )|网站地图

    GMT+8, 2024-5-3 04:01

    Powered by Discuz! X3.5 Licensed

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表