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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!' ?4 j- P* Q* V3 y
    ( ?  G0 P! _; p* {, W  p: U7 B

    8 \' U! ~  ^+ `9 e1 {在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。4 X  @* j" A: i. i" W6 K! V/ g- q
      快速排序的原型:
    8 z4 ?9 o4 T/ I  void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); / d7 i& H$ j$ I  n
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?6 c$ a7 I; Q0 _8 Z  d
    #include <stdio.h>
    & r- ?$ Y0 s. c# v#include
    <stdlib.h>* G) ^+ n1 t1 i
    int sort_function( const' z. @. T, a" `& r  ^9 i9 Z$ J2 |3 O
    void
    % |. K/ V* _% b; p- |3 }0 r3 u$ p*a, const7 R4 A( A/ t5 D5 a
    void
    : S8 o0 `) ~$ i9 C, w*b); 4 z, L( d7 E' Y( z2 A1 Z2 [( m' r" W
    int list[5] = { 54, 21, 11, 67, 22 };
    0 I7 k3 X. Q, z0 m: k+ Z; H& R0 o
    int main(void) 4 @5 `0 E" S& A; z+ ]. G: W
    { % l9 T1 O( E/ ^- n. x# v7 I4 L6 g
       
    int x;
    2 _# g& l& l7 {1 P( C+ ?- N% |4 o. _6 U2 ^& q* U
       qsort((
    void: p. p4 K! p: K) x& G
    *)list, 5, sizeof(list[0]), sort_function); 8 A  {2 E2 A: Q; P; `7 N
       
    for (x =
    % G& r5 C+ C+ W" C% f0; x <
    $ o0 u  O9 n$ p5; x++)
    2 r; Y% a, t4 Y4 P   printf(
    "%i\n", list[x]); # D2 Z# I6 C# E, P& _$ [# P$ I2 |, M
       
    return- J) A" y& \* M! \  d; T
    0; : T; }, j) f. Q9 x" {! e
    } + v, h! `$ p" c: j5 X9 h

    * ~2 ~# X9 J3 u
    int sort_function( const4 d6 o4 E* m$ S* h  Z, b% u2 B
    void3 X# `$ R; @6 e. h. S  a: f5 j
    *a, const, f/ z: H/ ~+ J4 \
    void9 L8 y/ i/ W' ?5 V8 Z' o1 j* E9 F( E
    *b) ' ^( d/ p* Z& c1 M5 m6 s- t- e
    { 4 J6 Y3 P; A: a9 u
       
    return
    . q3 h' g; e; W- L7 r9 A5 D0 w5 K+ s*(int*)a-*(int*)b; * f$ U- e1 ~( g8 C' O$ b
    }

    9 W( w& [/ U0 ?- m; {7 P! J) q' H) t7 V+ o
    ) j! e( j7 C+ D* p

      n9 k) M& G2 U. T( Q/ g7 G  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    " a6 @2 k$ r3 ^, K; v8 ^2 v; g+ h  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>3 [! C. W& k0 V% v& F+ }! v

    " p& A0 K- J$ u1 ~& `7 B
    7 T+ g$ K6 O" X* q2 E% ^2 r1 uvoid MyFun(int x);
    : B2 }4 ~/ G; l, S- z  D) ^! t+ f. Utypedef
    void (*FunP)(int); ! l# Z* r* |+ g! \5 J9 D! p

    ! f0 E2 p% z1 B4 v6 l1 hFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;1 n; x2 r- Y  ?3 r

    ! {# h2 f  m; l' F+ G! z. M
    int main(int argc, char* argv[])
    ( a# ^! f. C0 c' s; Z6 @( x! i{
    , T" a( ~* k0 F   MyFun(
    10);                        //这里是调用MyFun(10);函数6 U& H2 @  R- @  q4 ~; C
    ! j6 `$ U6 r6 g# o
       fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    0 n1 |+ z- U6 ~9 X  M! j  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    ! O- z' g  D3 ?( o  |# ^
    ; g3 M; [9 P+ e1 R( J   fp2
    =&MyFun;                        5 a5 `! Q2 N! P! @
       fp2(
    30);    ; J! U, b2 g- @# ]

    1 h4 K% n- }/ `, _& a! V   fp3
    =MyFun;                        
    ; w7 [7 w3 ?, k$ y9 p9 F$ ?; Q   fp3(
    40);    6 x; ]0 R% o7 j# k1 r# Y7 y

    9 l/ ~2 s' ^; S5 _3 a( }4 P9 M   fp4
    =MyFun;  
    6 Q' R1 W3 _, [, I/ L/ Z   (
    *fp4)(50);   
    0 [+ ^/ z" k$ V  L' P$ B3 T5 Y0 c) \; l
       
    return
    + H& O1 T6 x' i7 w- O& a4 ~$ c0;
    # T, d9 Y/ }  c8 k}
    / s7 ^( c/ m- Y8 |9 I! o3 \3 E2 T  j6 [$ i) ~
    void MyFun(int x)                     //这里定义一个MyFun函数" z& K" R5 |0 C+ p0 a  v6 [
    {2 x/ {- P* T& f
       printf(
    "%d\n",x);1 o1 I6 U; s5 S" w" L( ]' t
    }

    . x6 G! G+ r  d! s( ^
      B- }% d$ z) N) V, i: P/ \, b9 w) @: m

    4 n" h# ?" G: k# r" J& m# j8 p1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。& W3 w) H- o' o' {+ y0 \
    2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。
    : E; l0 b4 y5 M3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    5 v$ l- u% p4 Y3 T( E4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-4-30 15:21

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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