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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    8 S2 H  \0 u% [( U' W! |! E# Q4 {
    , o" z3 j  {% _9 o& M) U* K# Y$ m( p! b/ h3 @5 [* {
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。! @. G6 D/ X* _! b+ [8 T
      快速排序的原型:) w7 r) r/ e4 ^* ]8 ]
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    * {; V7 {4 N. f" \$ i, |  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?8 q/ y4 c2 M* Y' p
    #include <stdio.h> 8 s0 l* v1 X9 I
    #include
    <stdlib.h>
    " F. p. ~  Z9 ]1 j4 m1 ~int sort_function( const
    0 h- q9 O2 t0 ~, c& W. Tvoid6 |3 A8 u/ c% V  M2 I+ X& w/ f
    *a, const
    # M% @# ~# Z) f. B( zvoid
    3 o; m; O0 n2 g7 y5 u*b);
    & b- l( ^# w* O# N* ?2 f( s
    int list[5] = { 54, 21, 11, 67, 22 };
    + E4 s: V- c1 |$ @1 ]
    0 Y& N3 k; N! Y. M+ U: N+ ]9 b
    int main(void)   b! [) P$ S* A
    {
    - ^6 C9 v  Z7 W) o+ E   
    int x;
    * A* S# L* `% X8 {$ ?0 _  e
    " x7 E7 V$ e' P0 t9 }! \   qsort((
    void
    8 Q" j$ F( ^7 |+ M*)list, 5, sizeof(list[0]), sort_function); ( p8 f$ s) ?5 ?- `; n, _' C
       
    for (x =* o% S0 i  A. N  E9 f2 `' M$ ], F
    0; x <
    - p& m" o2 p) y8 ]8 ]6 U5; x++) & p, X" E3 g$ P  B7 q7 D4 [
       printf(
    "%i\n", list[x]);
    ( ^' a  x9 @' R( o0 x   
    return
    / b7 I4 G6 f% M: q: x0 b0; / \) D5 l+ J8 A( J
    } $ N4 `, V9 k% W& R

    ; p8 _; X, w0 U- {
    int sort_function( const
    , t5 y, c% P" H3 [/ [9 i9 Qvoid8 c/ \8 m, H2 q6 C
    *a, const
    " R! n; {1 v6 U: v' }8 a/ Jvoid
    ! x# a! c; E: r! y6 l*b)
    ) y, a$ _+ b# X2 |1 m: n/ V{ & r- l5 J1 ~2 u( L4 S- g" t
       
    return
    . k2 ], l) f, F- q6 _4 f3 L1 |*(int*)a-*(int*)b;
    8 R' t6 P. Z) L; T}
    / b7 H* D/ d) r, ]9 ?+ i; i

    2 m" h6 `/ a3 {! a& r
    ; l8 h8 [1 s0 ]
    9 ]) [$ N: V" s  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。$ i. V* R4 _- E1 H+ a
      下面的代码说明了函数名和函数指针的关系:#include<stdio.h>9 q7 x+ {5 q& t' J. }

    ; g7 h" O. }: S; q+ |" u. l% N7 Q, C4 }( v
    void MyFun(int x);
    0 ^$ g! |( Z( U+ M; Ntypedef
    void (*FunP)(int); 1 S% l  ~0 _1 l! R. U

    7 E9 Q. J3 |8 c% H! k% M6 q! VFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    , Y( q5 G" O% n/ t9 U" x, p* {1 ~2 L/ E1 K
    int main(int argc, char* argv[]); ~# Q  a% k& B. I# N
    {" `# f; R- V% [
       MyFun(
    10);                        //这里是调用MyFun(10);函数' s6 R" Z9 v" y8 y! P8 s
    * X0 y/ L4 m) I) b1 n3 {7 P
       fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量4 K) y* p- {7 u$ p+ \  [
      (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        * s& n! J& h2 q+ [$ n, l! g: }

    3 m: f2 M& |# W6 z4 ]   fp2
    =&MyFun;                        3 T$ ~6 Z7 k1 d& `7 B
       fp2(
    30);   
    * v- Q6 `: m6 j: N
    ! ^) c' Y' F% M- U$ k   fp3
    =MyFun;                        - a. s# n2 q$ _  d9 _0 P
       fp3(
    40);    7 `0 k0 E* i: r! k; i7 l' Z4 K+ Y

    7 `. H4 i0 I4 P5 _2 q   fp4
    =MyFun;  
    % ]3 ]) V) b. B, D$ l) ]* b2 i   (
    *fp4)(50);   2 d  c, q: E+ u

    ) S  K  c' y. ]   
    return
    0 e$ k1 v- y" J2 ^4 Q# X( N/ w0;
    5 y: l' }/ |/ t}
    ) n$ z$ D- L- t( D( b& f
    + q$ G+ m4 y# H  P" [
    void MyFun(int x)                     //这里定义一个MyFun函数' E8 ~  a, T! M1 H5 I& e: a
    {" j/ Q* N8 R9 B) c
       printf(
    "%d\n",x);
    5 i; A; K" G0 g1 Z9 N  D}

    / p/ o/ N7 Q' I! q- y5 D# f* F$ R5 g5 }0 F" e( C

    1 Z: Z: p2 J. ?" ^. Q6 P% N( h% D) z6 @2 u) \
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。% _) P* s( I  [! {7 j' ~
    2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。
    * r! S" `3 L. U0 W, ]: H3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。3 g1 B# B/ O; y3 |% _; Z! G
    4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-10-29 22:39

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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