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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    7 \. a3 j' K5 _& q- r/ ]) H3 v4 k5 W$ o/ }5 u
    : A3 p# j1 ~$ G# |& ?8 T6 b& L
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    . c: N' p2 @, q" m! p; s  快速排序的原型:
    1 q9 X) E5 |/ }  void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); * x5 ?( z. U9 n/ `- R/ o5 K
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?, I- G' N3 L1 o: o
    #include <stdio.h>
    ) \! P7 o9 _; e* g2 h( r#include
    <stdlib.h>& Q% M. ]  Z# f7 y$ D' p& ~, `
    int sort_function( const
    6 y  C" I. O# Z1 \. V& evoid, |2 d, t6 [4 u; a
    *a, const
    . F9 y. e$ `. }0 ]3 evoid& w8 _# \1 q3 {% C( p
    *b); # ?3 ?; C, Y. u$ d0 _
    int list[5] = { 54, 21, 11, 67, 22 }; ! t' X0 ~8 R- ]
    ( l% n5 o% r9 K0 s
    int main(void) 6 @) [0 V3 h' _, A
    { 1 _6 d. E9 f$ L% }% p+ Y0 s
       
    int x; 6 o/ W2 u9 ]' k

    . D0 `9 l/ b: c! i# Y7 B   qsort((
    void0 f( f% b  Q0 T0 k1 z
    *)list, 5, sizeof(list[0]), sort_function); 9 E7 Z, ^' F4 h
       
    for (x =7 \! M: u/ W3 i! {# `8 g
    0; x <' [1 }" _- M/ P1 M$ V
    5; x++)
    8 H: a. V+ m" E6 ~; N" x: C6 ^9 R   printf(
    "%i\n", list[x]);   k9 O' ~6 A  J& ]
       
    return
    1 C5 J1 J8 f- q9 I4 ]0; * |3 u' o- r: ^2 h* p2 n
    }
    7 a6 A6 r' ~  ^9 ]
    " D9 o- z' @: v! R$ X
    int sort_function( const
    ) {) k6 O# ?7 Z& [- [' D8 y# Ivoid
    " H) ~  J& d2 y& A*a, const
    ; K0 }+ W! j; l0 E0 o& fvoid
    ; W* U6 X( W7 z7 b" G% |2 A8 p*b)
    4 B) G) f& Y# W7 ?5 m: G{
    ; e7 k  O! @* ?   
    return
    & @: A( r& D& `' M3 t2 \' W, T0 B*(int*)a-*(int*)b;
    2 ]6 \1 X8 L% H8 G( @}

    7 Q$ D) }5 p8 S0 ^: d
    + q- I+ {' p! _1 X8 K4 n. C+ h$ i, @

    . S' a! r: }6 o. f4 Q5 `  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    " l5 Z" q- k& H2 u9 o  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    ; B9 \8 t# [# a' f! K* @
      k) z8 ~: b& ]/ \
    ; L7 }; d/ `  Q% h! R" [/ Mvoid MyFun(int x);" {3 v. f8 q# g; J# R
    typedef
    void (*FunP)(int);
    + g' M7 ?  c- P0 d4 L3 F3 R( R8 g
    FunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;( t& H3 B6 T& i) [  X, A+ g
    + k4 {, S) V5 C& y' K; b
    int main(int argc, char* argv[])
    % [/ e* g7 W: ]3 ^& V" N: J2 M5 |# |{
    . V2 z# q9 R% p/ J5 E: c, R   MyFun(
    10);                        //这里是调用MyFun(10);函数
    , `* R2 [2 E- l, ?1 h5 U
    % s  k' h; P) I. D/ s" v( }   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量5 J' Y6 N3 a) M: D
      (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    $ M, n9 B* _( ^+ k' T7 \1 x$ a
    . E0 _" n0 c2 L6 A! Y   fp2
    =&MyFun;                        5 c+ c0 g0 ]" i& d
       fp2(
    30);   
    + Y0 J7 a* a- {: x, Y' |
    $ c+ @+ z! r+ b7 W- O# K   fp3
    =MyFun;                        - m" T) y9 m" u
       fp3(
    40);    # p+ e/ J# W8 L; I1 k/ a

    : A0 s) s" P; r. ?$ ^+ r* a   fp4
    =MyFun;  / V/ f  j0 ~0 ~5 C8 i% a. H
       (
    *fp4)(50);   
    7 m3 e5 D" t% w, |; f$ J# ]
    $ w/ n4 G$ Y2 z. V- Y' R) I   
    return
    0 a, z3 o: E7 ]# g) U6 }0;9 x) T' g2 Z  }" |
    }
    6 V# T2 U( Z* B- z3 q, i# z/ T, [  I" c0 v
    void MyFun(int x)                     //这里定义一个MyFun函数) Q. g' f7 p! o" ^. \- W
    {
    / q2 P2 @' ]3 {# F7 ]% ~% g( l% H   printf(
    "%d\n",x);% m9 c1 Z4 ]3 U' N* l, ~! ~7 J3 i
    }

    % v- b2 o3 H* X" ]$ b# r
    5 Z* ^" M0 j/ e6 n: p: m
    2 ]( C0 p; l; z. Q' B
    - q" V0 u3 o! z3 Y1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    . y0 Q# S0 u7 n5 u* R1 [2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。* @+ |1 u, q. p1 q0 L
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    ; X1 g9 t8 K1 Q( p+ x/ X  V! ]4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-10-9 10:55

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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