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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    3 s: \4 x1 o% C2 b6 c9 g2 j/ S! T- Z4 G3 U4 ?/ b2 c: I+ v

    0 c, G* B; C  b" R在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    + C: ^& l+ S5 ?% [7 J  u  快速排序的原型:, z6 s1 ?5 X, c+ ?0 w  ?
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    ' R  n$ [, W! c' {  b3 ^1 D5 x  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    5 j2 i" t. F9 M2 z3 g/ ? #include <stdio.h> 6 U9 k: }( ?& ~0 C  X. d& I  i
    #include
    <stdlib.h>: m0 R* ~- ~, a- A  j
    int sort_function( const6 J6 ^. }) y6 U# w- G
    void
    8 q( [  P' S. o, n*a, const
    : Y) R1 \/ [9 I  f8 j9 Kvoid, e0 X0 D( F9 m! _0 t% k
    *b);   E! v2 f; l. f6 ?
    int list[5] = { 54, 21, 11, 67, 22 };
    8 x% x# t  g. F* |& T8 a, R0 A( i* b2 Y
    int main(void) 5 p8 G+ ~6 \: e9 c+ a
    {   _" {- s# B1 k  H
       
    int x;
    ; n% b& }8 E' E* Y+ y' g7 D% g
    : B( {/ i, P  }2 c% \   qsort((
    void/ X8 {. y+ O( l' l4 n  K8 A
    *)list, 5, sizeof(list[0]), sort_function);
    , m* N/ k: a: g2 i3 [   
    for (x =
    8 k% y) F' a# A- i' d( f3 U0; x <+ E5 _- U9 Z0 L. _
    5; x++) . R; a' F( s# J9 _: J
       printf(
    "%i\n", list[x]); 9 j3 o/ b2 k' u1 R5 v# x9 D
       
    return
    ) z1 j8 i  [/ U* a0;
    7 K+ K/ G7 x! h: |} 1 a. d, R6 z* \+ ]4 M/ v! }

    4 _4 n- i/ m) w  M+ Y/ H. J! e1 R  n
    int sort_function( const" T; p+ F3 v/ O' V8 C: k; p5 e
    void
    4 j% y2 G, q; W+ U+ S" l*a, const9 f. ?6 w$ X, V' l& j' Z9 {
    void
    5 n. p5 n# E! Z. K*b) % s8 X/ K" M8 Z1 t/ ~% n4 ]: l
    {
      N6 L" P6 \' Z( u  |   
    return: N; T$ n$ D  s& s& g4 h
    *(int*)a-*(int*)b; / h1 K; ?. |" m! Y; j+ ^! w; x
    }

    7 a; X6 H& q& {! `9 L* i2 Q# r
    9 m; v/ N; G: H2 {* t4 f! F7 \; q; B* W: z4 ?6 _
    ( H$ t2 H9 `  S$ l
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    # G$ q: q$ Z4 E* Y- W0 O8 F0 @- ^  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    # g# u4 w3 U  H# L/ d) ~/ S0 C+ Q6 j

    + u; Z% N. u& s8 K/ l) Y, ]void MyFun(int x);
    & m4 t' C+ I/ \, E  {  `5 Wtypedef
    void (*FunP)(int);
    ' C1 F6 p/ n! C& B0 X* x! _5 I+ K- w
    FunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    4 s  u. e# V" O6 y: k. p  `3 f' Y* ~& s, n% f5 ?( J5 Y& p* t
    int main(int argc, char* argv[])
    ) J' l$ ]0 [: V{" n5 _0 K! r2 `" y/ h/ t
       MyFun(
    10);                        //这里是调用MyFun(10);函数
    ! n2 X' c; o8 R: Z- r
    : |# |& a7 [2 Y; w. D- K   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    . s: q) D$ e; E1 E+ L' ]- W/ Z  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        ! v! ^5 P& i" @5 h6 l# Y; [8 m! ]

    . Y. Y( q# `6 c8 L   fp2
    =&MyFun;                        , z! s1 z" b) P! u
       fp2(
    30);    ; s" L& Z6 p. V4 e  L* o. l
    , g) z; F9 J8 E; K* C8 B
       fp3
    =MyFun;                        * f2 I+ E( \6 ^
       fp3(
    40);   
    2 N4 w3 B. p) B4 x, B6 R+ [5 K; X  Z6 W  j
       fp4
    =MyFun;    K5 h! N+ Q. ?: y9 ]6 G/ {2 ~4 r
       (
    *fp4)(50);   0 `  U- F( k# z
    ' [9 \3 q0 G& s
       
    return
    # L; y) e% o( P3 U" N; K0;
    / `$ |3 ?- S& M: n! h}) T! |' z! w3 N( ]3 F

    " E: ]3 e% v) P& I$ T
    void MyFun(int x)                     //这里定义一个MyFun函数/ N& N# u. R$ y& _2 W4 m
    {
    " K7 `! M3 P% O   printf(
    "%d\n",x);
      n1 H) z7 I: H}
      J/ M0 v) O  B! b
    $ F; q# P* {) O; Z- |! d
    : D' O% r( @* ]% O
    * U( p8 C* g/ |8 U$ U0 h0 w
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    5 f" h3 L  q" _' `* `/ F2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。/ S  h2 H5 o" v4 W/ A
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    ) C: X/ J1 g6 D# Z& G2 B4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-10-10 03:37

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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