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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!2 i& W6 ]2 f' ~1 h
    : S. P, m# D& i( y+ o& v% a* b5 L

      x! u% f# {  \" L在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    3 C9 I: ^' v' ~- C  快速排序的原型:) y8 W9 y5 P7 `5 ?. c$ {9 F2 Z& n
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); 2 S- _6 f- C1 b* f
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    4 Z3 i4 ?# o2 z. w4 T #include <stdio.h> 0 s9 P( Y+ @' D/ T- {& [
    #include
    <stdlib.h>
    3 Z( B+ B2 |( K5 \int sort_function( const" a- T6 j8 x5 J- n
    void
    6 ~6 K& E7 V! I0 A% U) ^*a, const
    2 U. C% Z) v9 T0 O2 Tvoid. E: X% S& W9 }* ~' n: M% S
    *b);
    % W: g1 K+ A+ V* a, v: b, F
    int list[5] = { 54, 21, 11, 67, 22 };
    ( q( |( X. R5 x* |. D: Z- D& \0 N$ g: k0 j& q- u
    int main(void)
    7 P7 f3 [0 l9 X) A; W{
    8 L( c8 k$ q. E$ T! s7 r8 y3 a! i   
    int x;
    6 X% y$ S; @8 @6 G( r0 S
    3 ]' `# B/ g7 q3 |5 l# b, ]   qsort((
    void
    2 a8 p/ q4 E& E( [3 `*)list, 5, sizeof(list[0]), sort_function);
    , Z' N( q- L: a7 h; t   
    for (x =
    6 O# m3 q# C# l$ d6 E, p0; x <
    % f8 c$ N6 f7 T' L5; x++) 2 f  i* L' J: b- B
       printf(
    "%i\n", list[x]); 1 v$ b) O9 T6 @9 c
       
    return
    & x' M# T2 Q: P8 K, l4 }( Z; K0; & y5 d/ i; k2 I9 ]2 U
    }
    ; P4 g6 z! I7 s  m9 o3 g8 m
    * Q4 B) }& K) G' |, t
    int sort_function( const0 v- i% f: A2 m; t8 g6 n6 N
    void/ J7 V$ P0 O$ c5 k
    *a, const& W9 `# X. E5 M. R. {" w& ~" h
    void
    ' n5 G3 H$ K4 j3 K*b)
    : }: V! V6 K) w/ \$ o, F{   \% r1 w! e2 o
       
    return! N  N5 g3 p8 n5 [1 o$ l
    *(int*)a-*(int*)b; $ c6 \+ ^7 N: L  s
    }

    1 @' n# y( e+ c" q) ?7 J: k. W" h+ W; j+ w2 r" Y. V% Y& H' @1 n

    4 e. V6 H/ Q" P) B7 `/ g( S( m' f+ f3 V! M8 N8 a  S
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。" G6 ~/ _' q2 d- m* \- j) Q
      下面的代码说明了函数名和函数指针的关系:#include<stdio.h>3 [9 j& m# G+ U  ]# M
    ! l- c6 H  }8 K; k, l: D
    ' R- a) u1 F/ q. s4 |, _9 C8 ^
    void MyFun(int x);
    / K! l5 Z& A( W+ Vtypedef
    void (*FunP)(int);
      ^$ H& D' ^+ L( [3 a0 k$ N% e5 Q3 ?2 k7 g$ i% @* Y0 J
    FunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    7 _0 I+ G' L7 _( M3 `+ Z4 z7 B4 I6 e, h4 x" c. |: a/ L- b' z
    int main(int argc, char* argv[])' i9 d/ g1 V# B* V
    {
    % V% P7 n8 P( k+ ~   MyFun(
    10);                        //这里是调用MyFun(10);函数2 [) J) }( r1 Z/ @& N

    ' l( |  q% E  |; }: ^" N   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    , N# i; r/ X9 z+ q4 L* P4 \3 |  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    9 A, ~. D. n0 k* }- W2 n. H* A1 L
    " _3 t8 M* A1 t! r: K7 j+ H   fp2
    =&MyFun;                        
    8 N, l. f3 d8 F3 f/ L- l   fp2(
    30);   
    ; K! j, T/ S" d  }% ?3 V, W# e7 P' ?
       fp3
    =MyFun;                        6 b5 H5 ~0 V# r  M' O: G
       fp3(
    40);   
    6 Y' V' i0 _, V/ P$ w6 V
      d2 k3 A( F+ F; U   fp4
    =MyFun;    ~9 }+ l  E+ m8 J/ e! J
       (
    *fp4)(50);   4 ~+ ^: b- l1 W. a

      S2 a$ ~+ j; Q" y5 [% k0 \0 X   
    return
    6 t$ e: b8 M# ^' B0;
    0 Q. y6 V; E8 I3 K3 P8 u+ o" `}
    4 {) B/ `8 M" L5 s. l) m1 X6 c$ c' W5 k- O8 d! V* ]
    void MyFun(int x)                     //这里定义一个MyFun函数
    , L# R+ L' d# E$ O{# E8 E0 d$ S! R; s
       printf(
    "%d\n",x);
    - m' n/ B9 Z5 }! A}

    5 E7 L2 a6 S% i2 j7 c$ D/ `: P0 I1 T2 f3 \5 Y

    # ~1 O9 D% T' y5 D- @& K9 W8 A4 J8 h  \
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    ! }( _9 U; A; j% ~7 |! k$ ]% A2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。7 ^9 n/ t& W- \
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    6 E1 u4 r, T+ G6 r, y4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2025-4-25 02:45

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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