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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!1 J2 }+ ?5 q+ K; J
    * Y+ e4 g# a. e+ U* `, \
    4 T: }* v: m! g8 f7 Q
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。# D) @& H8 ]0 g" n/ X8 f
      快速排序的原型:7 m4 ?5 [" w/ ~8 G# H
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); 4 G( t) ]" K7 E. U. \+ M6 ]0 B- A
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    , `& z* @; y# P# p8 l' ` #include <stdio.h>
    - U' q: E) f1 c  b6 h: Z# A& t- j#include
    <stdlib.h>
    6 z9 R: K0 J' H5 u+ qint sort_function( const9 P) X0 f. P( ^; t3 |
    void
    0 N$ c% j5 N0 Q* W5 b*a, const
    & q' @& S6 n: z3 d( Vvoid
    2 m0 u4 \- ~- L4 W* C*b);
    ( ?! ^. Y9 Z2 u/ g/ N! I2 M, e
    int list[5] = { 54, 21, 11, 67, 22 }; : J0 b; O/ q) k9 v

    , B/ d! ^6 ?* P( l7 K/ N/ ~1 F
    int main(void)
    4 a/ _, j  _6 `) J{
    ( _$ z& K$ s! z4 T   
    int x;
    ( G: F* [, C! S3 p6 {
    9 G; {* Q% _& T% s$ |- w7 g8 y$ {   qsort((
    void+ L$ H# @- K; |7 y8 ]+ Y- i; w3 e
    *)list, 5, sizeof(list[0]), sort_function);
    6 L5 p  }1 I) N2 s   
    for (x =
    3 R/ I- w- E1 Z5 Y1 V1 P0; x <
    ! L& s2 w1 n7 R3 R: i8 R: c9 B) Q+ o7 Q5; x++)
    8 B& r* u3 j8 D, h% @   printf(
    "%i\n", list[x]);
    3 G2 }1 G+ _4 v  D- F   
    return' S* [2 e: P, R: m& k7 L. q2 X% I5 {
    0;
    0 k  P/ E) K# p* a! k: z}
    8 v" h: G) j% b, v( l+ G4 ?- E6 _$ r$ B- v
    int sort_function( const
    % n: {4 F8 \' J3 v. gvoid) S- P1 Y5 K! J* m1 Y* ?% p1 Q  q
    *a, const
    1 M, E$ D5 @  Z! ^$ P0 C8 evoid
    & @( v, w2 e5 ^3 Q*b) ' S7 N' t9 v% i+ A& t
    { 0 O. t9 F4 g$ a0 H( v& U
       
    return) N. X  }$ |# E9 A& l0 ~
    *(int*)a-*(int*)b;
    " E5 W) }5 I; K- j6 M2 B( p}

    , T5 C" B5 [5 p3 C( N
    ! g! D- j# y* @4 s
    2 P4 F2 p& q1 ^$ p" @
    & z) z+ q3 T( R1 Z  p0 f+ i  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。7 x  Q# u; U8 V  L) E/ D% o
      下面的代码说明了函数名和函数指针的关系:#include<stdio.h>* ?& M: K" E2 B8 U7 P9 J+ P; k
    . Z1 F$ W7 U" W* @+ M( _3 l

    ) c0 K' y2 f" [  Q2 M0 Lvoid MyFun(int x);
    # w5 P* c" f0 v- Q9 B! Atypedef
    void (*FunP)(int); 4 ?2 G6 r, l) k; i$ {
    . y, N( v( B, n4 g" f) }
    FunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;9 i5 v/ m1 s( Y! z( s! h. ?

    ( T( G2 Q/ @; c) h( _% W# k5 ]+ H& x
    int main(int argc, char* argv[])
    . q) Y3 m+ _( y. z% z{0 R3 e: G9 ?: ]+ |
       MyFun(
    10);                        //这里是调用MyFun(10);函数+ ?2 p/ j  _7 T$ J

    , a5 o! F1 O: x6 q  I* M6 B6 }4 j   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量9 K# r8 f6 w7 ~4 {# @1 V
      (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        ( e: Q# f$ N) }; L; A! \( Y" f

    , K# Q6 k/ E0 B* S8 Z! X   fp2
    =&MyFun;                        ) l. v* d( v' t0 i2 B
       fp2(
    30);   
    % V9 e! |# O4 L/ _/ M* t
    2 Y) }  z5 d; F  T7 m' O   fp3
    =MyFun;                        ! w3 t; Y# G+ Y0 G% W
       fp3(
    40);    ' U7 e  ]" k( y4 g. E4 a
    / j/ x! ?3 P8 P( y" ^9 `
       fp4
    =MyFun;  
    1 [7 K  H4 w' Q  J- @1 s   (
    *fp4)(50);   . W* M# Q0 \) L1 ?. @4 H8 T& A
    . \7 d, g: u% |% E, I$ H6 o
       
    return
    ; L  ]+ v" b1 z: p0;3 H5 c4 Y, t8 F) L
    }
    $ r! |9 M$ Z3 [( t8 j' g) N. ^: H9 g
    void MyFun(int x)                     //这里定义一个MyFun函数1 L! `5 T: ?( s& y! n* B
    {- y9 Z  N' j; Q
       printf(
    "%d\n",x);
    ( n# t$ [9 c: F+ V8 }. @}
    : ]' D5 P( `  s4 W; s8 i( n
    4 u) z/ e6 x' D6 g' H

    1 i- E3 C" Z! r1 S& ]4 C1 b# G
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    8 n6 u" a3 Q" D# t2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。7 r* Y) j& F) u7 l5 R
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。# R$ o4 z; U3 |& i# A5 V0 P% {, D
    4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-4-5 18:25

    Powered by Discuz! X3.4 Licensed

    © 2001-2026 Discuz! Team.

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