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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    ) p4 @9 a2 E4 [* U& c5 V3 t: _# l, |
    + f" C0 B# U9 G/ D* V
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    / N# o7 n- T) x* v  快速排序的原型:6 C. I( A# P, e' i4 c+ W# i
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    6 @9 `1 @8 x) X- [* i" Y& n  F  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    2 |1 F+ h' m2 A/ H( H% p #include <stdio.h> . K# L. G' u' ]% Y
    #include
    <stdlib.h>/ t7 x/ w& V% b/ ]( P- X" E. Q, o4 Y
    int sort_function( const
    ' }) k0 @8 x3 s# t, Tvoid$ g" p% V+ r7 a- l+ b, M
    *a, const* i" v% M: U) N$ t% z
    void
    , d8 J8 \9 `5 c6 q) A! p7 d*b); . E% ~" k$ p1 Y* A. R4 b1 N
    int list[5] = { 54, 21, 11, 67, 22 };
    * z& ]# g7 e, \) b; i! G1 a& U& g1 s. _9 g4 O7 X
    int main(void) ! P/ z2 a/ a! u; t3 f% ^$ t. ]
    {
    3 C/ x* O$ r- i# X. P+ \7 T, P   
    int x;
    . P% k' `) v( b5 a$ c4 a
    2 J7 ]4 {2 ]! T5 b4 V   qsort((
    void+ S; W9 U' t5 N3 ]
    *)list, 5, sizeof(list[0]), sort_function);
    ' E, J9 u- \# n0 R# F. |1 S   
    for (x =9 t" ~/ {  J" ~, {
    0; x <
    & a- R8 c; K5 |8 d+ T5; x++)
    8 T- e/ N9 e$ q9 k) Z   printf(
    "%i\n", list[x]);
    " F) F' G- w) J. ?8 S- H. F0 H! p   
    return
    ' F2 U. k* _1 l0;
    ( B2 b8 J$ K8 y4 ~" g}
    5 Y$ ~& g3 t9 @9 z7 U( k$ Y( v* I1 v$ E' @& m
    int sort_function( const
    ; D( z4 Z: c: R0 o7 K) I" Uvoid
    : u6 h+ f/ e, v( Q! b7 G/ M*a, const
    ( J/ ^8 q- K; O  ^2 g2 p; Qvoid
    # \2 }+ s! P7 ~  z, i*b)
    ( s1 Z( x# p' W% ^3 u* J$ I0 e{
    $ Y6 K+ o3 z! C& F$ B. J& q& n3 X   
    return
    7 o$ e; T1 o+ c7 q*(int*)a-*(int*)b; 7 s9 R7 i( |6 I  O
    }
    & k8 w) _* i0 x) ?

    + p5 i) M- v# M/ T9 n0 q7 J. r8 ^* A$ G) D

    . y5 j2 q7 L4 r' w" D* h  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    1 L1 Q: o, |, `& F% q  ~* i9 |6 V  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    ' h2 T6 d- U, R! p6 o) t% v9 S/ a1 U4 ?+ d! J8 S3 S% ^- {3 [
    0 m" G( _, b6 `# N: r/ D$ V
    void MyFun(int x);
    % C" r" Z  t! K3 l+ r; C" jtypedef
    void (*FunP)(int);
    ; \  a( b, r3 G# W/ Z& _. F) V* F/ f& U( s7 r4 H' H3 J
    FunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    : z" @. z; |( y1 O: p+ M
    / n& D9 S  k. c0 D, m6 S
    int main(int argc, char* argv[])) J1 h% ^% D- C0 h$ u( S8 U
    {
    5 Y# @6 ^' X8 s) \3 _( |2 D   MyFun(
    10);                        //这里是调用MyFun(10);函数0 Z% `: z- b1 W: w+ |4 l
    7 |; l% S# f; @- k0 |8 F
       fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    - s: ?3 M- k* D/ h! Z2 L  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    9 g; a2 a- }* a9 J) \
    3 l( \; z2 r4 F% ~! a, u   fp2
    =&MyFun;                        ; G& ]4 i+ Z" C% m! C# Y1 ~( L
       fp2(
    30);   
    1 v  b- O7 m$ C0 E5 n! l. N6 O0 |7 q1 I. _$ s  N! S4 O
       fp3
    =MyFun;                        0 s" v% N  {; B; v  j5 H* @* q
       fp3(
    40);    * v# J3 ?  @  M
    % t& ~- W+ v& o2 U/ g
       fp4
    =MyFun;  
    0 Z# Y# u( \  b3 V7 A# w   (
    *fp4)(50);   : }3 {) ?  \& U  N) n
    & X4 P! D1 a, @2 ~4 j. i3 [+ ]
       
    return
    * j; E; {; Y% W1 l2 D. v0;
    ; l$ c8 F; Q6 ^}
    ; \- V# Y; F  N. Z* |
    ! i4 j  u. p: r- H: R
    void MyFun(int x)                     //这里定义一个MyFun函数
    ! g! k. f( C. M' W{1 Z6 G  U3 V7 S
       printf(
    "%d\n",x);
    ' @$ I* k% v1 l8 _; [5 W0 y9 z1 `& W# W" t}
    5 I* M* L7 q2 c3 K

    1 `6 T" ^7 M  q0 S+ ^/ S" @3 \8 r
    , j7 z+ ], @8 `& o7 R: i& u
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。/ z" @2 J' k7 c3 q! u3 M3 D, H/ |
    2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。% ^2 ~* y: d& l* Y2 P: P+ g
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
      U1 c; f5 H  L; |! p4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-3-16 08:34

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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