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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    1 G: o: j  d. U4 w0 b1 k' b. f
    9 w- ?0 `" r6 k9 Q' Q3 M. y; Q# m- ]- e% v4 ~. c' i- g
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    ' L: l6 O. T+ b, {$ O& f  快速排序的原型:
    9 Z7 E: C( [9 p7 x9 U1 t6 \) c  void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    9 O9 Q- Y! S" R- t5 j  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    4 F! X' M: n3 T/ J1 {  z #include <stdio.h> 1 ^5 s9 t( J2 ]/ q# f( ~; ]
    #include
    <stdlib.h>
    . ~1 f* h- [; _4 k9 p; wint sort_function( const0 }  Y4 q; [5 C% s4 Z5 s8 H: }
    void: n1 B5 T/ C% D6 {9 L
    *a, const/ k# l5 K; @, |( \# F5 p7 ~
    void
    + o$ A* |  b2 I*b); / _8 @4 N8 Z  G5 x" l" g( i0 D
    int list[5] = { 54, 21, 11, 67, 22 }; 0 A' {# _0 n# u8 B! `/ O
    # J" s& [$ V1 U" \% F& i
    int main(void) ' ?4 C; g' C/ U. T, A- F
    { % f! e4 L, F5 H
       
    int x; 0 Z; O0 P4 q, t3 E  N8 Q0 s3 x. v

    5 J- `# F! k# F   qsort((
    void
    # `' |, j7 [% e4 c% g9 e7 A*)list, 5, sizeof(list[0]), sort_function);
    ( B. h$ o4 G3 F0 z% B: @( d- D   
    for (x =1 p$ _: C/ m6 M) i; t8 [, m& j
    0; x <
    2 }1 J( [. |/ f& A! v3 _, `5; x++)
    ) D& g! C5 i- g* [) ~6 O5 d5 E   printf(
    "%i\n", list[x]); $ G$ e: q' X! q* V  X
       
    return1 i- s5 b1 T& H/ B. y6 i9 E& Y" W) \
    0; : w4 d& ?) W; d( x
    } % n3 q, N! c! ?1 h7 ?' Q2 {0 X
    5 K0 ^1 g( h2 S7 _: H
    int sort_function( const
    ( z' _- v+ ~. ?5 M* rvoid
    , P% m+ n: g$ N2 ~0 p*a, const
    , c$ L+ I8 M8 I2 C  }2 g) Lvoid* l; o# B9 U( ?' y: K' q/ A( z
    *b)
    0 v3 u  J! I5 ?0 N/ i( z  r{
    6 t; t. w+ Z7 p2 {' @   
    return
    1 W# M. F& X' R" T*(int*)a-*(int*)b; + \6 D- z- m3 m/ e" }
    }
    + Y( V* w, ~4 V& Z# E5 S3 g# l

    5 V# _$ v9 v. q# @8 x( d; M( H! x: d0 f  \
    2 d2 {/ ]3 g' E  q1 u% r3 O0 E5 ]3 _
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。* n( o0 ]" P& s$ j+ Y5 h3 ^; z) h! u
      下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    $ @4 Z6 G( _6 m; q: C) R2 R" S6 `
    / C! O- R/ E" o( q. e
    void MyFun(int x);$ K) j+ {! ]1 o9 `5 o
    typedef
    void (*FunP)(int); : t6 y4 A$ m6 {

    ( B3 w. _6 p  _# b! RFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    5 J7 v! ~/ E5 H) t
    % A7 w1 {# V8 [( S! d
    int main(int argc, char* argv[])
    & ^2 |7 k* q5 x+ k' s0 w{9 k: G) s1 }- ^; ~
       MyFun(
    10);                        //这里是调用MyFun(10);函数
    4 I- h8 K. a+ s; b1 f7 B8 T, v
    : k6 |7 U) i& T4 z1 ~" T  t- [   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量; ~6 D  ]# J5 i. M% X
      (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    + A! p& d1 d- c$ p, ~" S
    : e+ _$ d! k1 H: f$ o3 j* U3 w! P   fp2
    =&MyFun;                        - h# I* _! x6 e! W' o
       fp2(
    30);   
    9 l0 ]; B! q) a  L2 u$ T5 d- z3 m
       fp3
    =MyFun;                        
    2 P, @0 d2 ~1 u   fp3(
    40);    / r+ E! X* u* A% X1 w. I& v, z
    + |+ M# c: V) i0 L. |
       fp4
    =MyFun;  " A4 e. [/ z% p  f& [2 D& v
       (
    *fp4)(50);   ! Q9 e; N; u* }" R

    $ F* P# k; d, `! U& E! E* g. Z   
    return
    ; d! H& f" |# J' P3 i  I% v0;
    ' ^1 [! ?4 \9 {$ Q- B; M. [}! Y# v6 E) e4 y2 @5 @/ v
      ]7 x% R: E  U6 q) I
    void MyFun(int x)                     //这里定义一个MyFun函数
    ( h" F: O) Q. X5 i6 e6 c5 g{; j. y* f8 s' n8 W. i
       printf(
    "%d\n",x);
    ' M& o' W5 Q- h3 _}
    6 A! T+ T2 y. v" Q$ u
    : O7 Z) E1 q3 z, A4 c8 u( }9 K
    ; e/ P3 h/ ^% u+ m3 f9 F4 B
    7 ^2 s5 u9 G2 Z4 D! [
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。. O' V& T$ G/ V1 t
    2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。/ ]0 t- n9 Q( T
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    % A7 ?2 b/ n& B/ X% Z) R% [4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2025-8-14 04:07

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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