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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    : \% ?, e4 M6 C  a& Z3 e
    & `4 q1 F" q3 K+ i# p* ^5 `) D. g* J  \( Q( A2 W% }5 b1 X
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。0 P* i: g3 W; C4 a! q# ]( C8 c
      快速排序的原型:+ u; G' J, V6 O5 }1 O; R
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    * g6 k2 _* T5 n/ y% U. Q( q+ u  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    ' d1 N; P# V2 C4 w! H- B #include <stdio.h> ! L  E2 P% r# K9 @# y( }2 F' M2 X
    #include
    <stdlib.h>
    + |9 c+ L. g! s% P' T% I4 C( rint sort_function( const5 \; w! T" l# W9 r$ Q
    void
    . \6 @$ T9 T- }*a, const
    7 Y: O: U# t# Z# Evoid9 `9 |$ Z2 n0 i* J$ `
    *b); ) l7 e. E7 g+ t! C% w+ M
    int list[5] = { 54, 21, 11, 67, 22 };
    8 z3 A% D! Y! j9 k
    4 _- N1 t% x$ P" z& P
    int main(void) : R' N7 x6 x, D+ C# j
    { 5 O2 m$ A: m; ~0 G
       
    int x; & o: L. c% ?9 |( n) Z( V

    ; [  B* Y/ o' `' [9 E   qsort((
    void
    6 Y" q8 P) a* a7 @% B0 b) u) R8 ~*)list, 5, sizeof(list[0]), sort_function);
    3 @8 x  C8 e1 t2 i! J+ a/ A   
    for (x =+ ^  Q4 q" z4 u& f
    0; x <
    # d/ ~: z- p+ m9 @2 H8 d" Q5 r3 b5; x++)
      }" i1 M! y7 \; r   printf(
    "%i\n", list[x]);
    ! P! o6 @5 e& n6 `$ z6 R6 T   
    return$ s8 q: w3 L5 g8 t- M
    0;
    $ W$ H' l2 d* Y7 b8 e} * r8 h" Z) r0 F2 M9 X

    5 U1 F3 Y* u. U6 u5 Y4 U
    int sort_function( const* S3 \: Z+ w$ l' |/ V, k
    void  t* u8 q+ T9 R  [( M3 G; _2 z2 Y
    *a, const3 W* W' t( R# f* l
    void" H* L9 ^; Q) o- g3 _$ I) n
    *b) 9 S" d9 F4 `. p; R
    { / \. h& \! _5 e! T% n( E
       
    return
    ; g- E. G2 w7 G; s( `4 N! ^*(int*)a-*(int*)b; 7 j5 @% d1 Q; d" P! D/ P
    }

    5 s" q2 V8 F$ X/ z" ?/ _
    ) p; T9 A, v' C) H$ [  g
    : q' C9 N% U; X: `, ]% a1 v4 N' \; T* Q. z8 H4 V
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。* J5 a' a% m! p( C) X, T
      下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    * I$ u* i! v  P6 k( d1 z
    - K% e! `* M/ _! Q) q3 Q! ~; ]7 V; _+ V  u
    void MyFun(int x);' u. n  n( W4 ^: H7 j* |
    typedef
    void (*FunP)(int); 6 k: E* N; `7 m  |2 d) j

    2 I' C* d7 d% S  \* L% G8 L  L6 UFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    0 G- {, b: N5 D2 m7 R1 D0 c
    - @8 Y& f  V: D8 |
    int main(int argc, char* argv[])$ Y4 ~' H2 A! R- a. O% Z* {
    {
    9 k. T+ _1 s& ]: y5 k% A' P   MyFun(
    10);                        //这里是调用MyFun(10);函数
    8 P: I' S/ ?" e' D9 o! \3 _8 w; ^7 Y5 n) p. Z
       fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量0 p. l; h1 M( [6 g7 B( f
      (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    ' ^& Y6 p/ F% d  ?1 t4 E; c4 \" f! R/ L
       fp2
    =&MyFun;                        
    ! C4 K+ t9 m8 ?: t   fp2(
    30);   
    0 _: n/ J) j# p  O6 d  L% J4 S- N- y5 z( m. I4 P! V
       fp3
    =MyFun;                        / }( h* H0 t- z7 x1 y( r
       fp3(
    40);   
    + B& R/ E7 U7 Q: m2 x! C' j$ T2 u/ D
      L& c3 ?1 J" J, N" P( w   fp4
    =MyFun;  
    , a( A$ f" y' n! W; e# p   (
    *fp4)(50);   ( b' `  {9 I  N$ t
    : y1 ?5 ~) y6 j& x! C
       
    return
    * j9 _' w2 M; x" P3 h0;0 Q" a2 m; \. R- E, f
    }/ x/ O8 U1 [) F3 d7 Z# y

    , L/ c2 N% X8 Q7 y1 S8 F
    void MyFun(int x)                     //这里定义一个MyFun函数
    + X, {6 d! n  q{( ]. v9 B: T2 y1 o
       printf(
    "%d\n",x);# C& K5 L/ Z5 U7 k5 h
    }
    ; d: J" H+ [/ w/ b+ T1 `) H
    2 [2 p0 {, c; R3 `

    9 w( ]0 k0 z1 y: r% a- N8 z! d7 v% U0 n; T/ Y+ @# ^& U
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    9 H" {( I2 q! Y/ y' u3 v% x# }2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。
    9 I6 W4 W% |$ \3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。# O  b0 X) W* m
    4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-8-14 10:14

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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