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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    , x% u& l: \+ s( Z
    * X- y7 I2 F% }% v! n0 [
    , K! w" R9 J; `在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    / H/ w9 T( q9 t5 D5 j  快速排序的原型:
    , v% N* [% s, b5 L  void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); ) u, E6 T8 L! S4 b6 _  N' W
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    6 Y# Y0 |$ ~+ _- D! Y, b" V #include <stdio.h>
    : l$ N3 c- V: o#include
    <stdlib.h>! @5 C# I& m5 q2 H8 z% G# q( @! @- Y
    int sort_function( const4 x" ]0 R! j, G* W. e& R
    void
    * `* c9 Y* N' x& O! n7 F5 I( E# Z*a, const- M- K: I* z. l7 u* ^8 @, W' x' h
    void4 O, @2 O- X) J/ V6 M- v3 K/ m8 `
    *b);   Z1 Q! G" K- G5 J) z
    int list[5] = { 54, 21, 11, 67, 22 }; " x  A) |3 x; C$ F' X

    % V) Q! B8 M8 E8 [6 H
    int main(void) ! j$ [) }* Q4 x9 V: p& ?+ c9 M' a
    { ) M/ t, I7 [0 m' S( p9 p8 v9 w2 |( t
       
    int x;
    $ R+ I/ a/ a; [4 P8 s
    # s& ?3 D% i7 B% f8 X   qsort((
    void& r- v" ]# }: L- Q4 h' J& S& ~% Y4 \
    *)list, 5, sizeof(list[0]), sort_function);
    " U! G3 A. m; ]: a! e   
    for (x =
    & m. V; V6 r( N) V3 y4 E! Z0; x <
    + \# L3 z) D1 O6 p0 C% ~8 `# C$ Q7 u5; x++)
    $ @; d/ z, u6 W( Z4 s6 w   printf(
    "%i\n", list[x]);
    1 c& Z9 C$ R: d8 S   
    return- H# H) t7 a1 l9 C; K
    0; 8 o7 [+ f  A4 Z$ q% p6 s
    }
    - m8 h: o8 p& {0 S3 ^. g6 B: u( e4 x; A4 _
    int sort_function( const% @7 \' L1 ?' ^- z
    void
    * @2 h  u- }: _; z) V. i*a, const
    * ]; H& e- }' q3 h4 ~! k. nvoid: _( `( i5 l/ w* N0 g- u) d
    *b)
    ! [: `4 R- i7 L9 o{
    $ Q3 G; m( N3 n( Q   
    return
    : E; r0 n' w$ B( n7 q1 _. c$ y*(int*)a-*(int*)b; 7 ]) q; w. h! k; T$ p# ~( J
    }

    ( g2 G* v5 ^6 v. F; E4 x6 u
    . n$ J$ T6 h- [
    . k9 f* [! L/ E
    . P. _/ K8 K& F5 n0 B7 V3 [8 b  函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
      F; L* a7 G4 S$ X6 }, N  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>% y! |( k, Q2 k9 [
    - a. K  I# e# s8 k

    0 b7 r6 E0 ]. A. `$ Ovoid MyFun(int x);+ {: d5 ~7 ]9 L/ m8 w
    typedef
    void (*FunP)(int); & A8 {& W/ `1 X, P: N5 N# W

    " [1 f5 f6 u5 i: GFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;3 H; d" E) _6 b, o4 k+ R  o, L4 H$ j
    8 C; b3 ?8 D3 ]& b
    int main(int argc, char* argv[])
    7 S) W! V- f# e7 U7 v) p{
    9 {3 `4 I% u* a  \# E# {   MyFun(
    10);                        //这里是调用MyFun(10);函数% \' |0 c+ X5 \# _6 [9 E. v$ o6 E0 Y

    7 B7 T7 m4 B( |1 K% |. z. n1 s   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    / ]& J5 H. T& D, L. `' |& L2 ~, `  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        
    % `" g: a8 b% U' Q% V4 @+ Y2 z& x% F. y5 ~) h$ W
       fp2
    =&MyFun;                        4 S. o  V' X  ], ^
       fp2(
    30);    8 G3 c1 m( i& c0 Z% O8 E

    , q+ D! }( d) \: V9 C   fp3
    =MyFun;                        
    4 U3 [, A6 O! d; k   fp3(
    40);    7 X3 n: k) i" x

    - f) C; q/ k: u6 j0 {; c  a  Y   fp4
    =MyFun;  ( Q$ }8 a  d! |& i) L9 P5 m. g
       (
    *fp4)(50);   ; E/ f+ _, }; G6 I, d1 ]2 W

    # i/ L. _3 i  `8 c5 ?   
    return, ^  Q$ s( X, w( |  r
    0;
    ; c6 ?/ V3 V! t, x$ `( ~7 n}
    8 I  {6 O. U& g2 e, q8 H
      W1 e7 r: C8 |" W
    void MyFun(int x)                     //这里定义一个MyFun函数- i. x$ C& C& G# |5 g
    {4 k( S8 a9 {! [3 ]' d2 @
       printf(
    "%d\n",x);
    + v; ^1 A( \7 x7 n}

    / j2 \( v- a6 e+ N' `  s; v" i( f  V# S# z
    + d0 l, _$ a7 b3 K4 Z, P
    % s3 K3 c3 y( x# w
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    % w% N! v# S6 i( m0 ~7 L0 w9 Q. T. A2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。
    # T/ ?6 X/ |! E# T. G3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。; c0 M/ _; ^+ B9 H
    4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-5-31 07:56

    Powered by Discuz! X3.5 Licensed

    © 2001-2026 Discuz! Team.

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