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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    : a0 q4 {8 a4 Y% m0 {' k' m7 r+ L- o7 V( w

    . z4 O  l+ w; U2 U在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    2 {6 P4 V! s0 t  g  快速排序的原型:$ O0 s$ r* d: A$ `+ }- g
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); 6 u; d+ o! i6 B) a) X- ?
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?$ p) O9 y( v, F# N
    #include <stdio.h>
    ( p. f, u% j7 C4 C0 f#include
    <stdlib.h>7 s3 m. s0 k4 A5 Y# s' \5 s
    int sort_function( const. v0 _+ \4 G  B' b6 ?3 O9 [  v
    void
    ! T, i/ H% {" K. m- a*a, const" R# C7 L2 i4 q8 O. l0 f$ M
    void
    . \5 G& |+ K/ }5 B- w" r8 F*b); 3 I5 J+ V% E" s. z0 I3 @* p! F
    int list[5] = { 54, 21, 11, 67, 22 };
    $ l5 ^- u+ B3 _, J; K4 i" H* r; x6 `2 o+ v0 M- V/ i5 y& f; s
    int main(void)
    ; G' t2 n  Y# @9 F+ |) p{ 2 y1 d( g/ h6 s% A: g+ b
       
    int x; 4 u$ N% }* E: D
    , i8 D2 d# {) H5 |8 @+ X( I- t
       qsort((
    void0 e8 {$ P3 t$ [& T& c" D7 e
    *)list, 5, sizeof(list[0]), sort_function); 6 j9 ]5 P7 O9 Z: K
       
    for (x =8 n& @& E5 K6 s- t0 Q! K0 o
    0; x <
    * C+ {" [( G8 w/ c" [6 b5; x++) ; l: S2 k7 z& {
       printf(
    "%i\n", list[x]); 1 g! q( n- t6 r" ~$ o) E
       
    return8 O$ |# g, G( ~9 x0 B; C
    0; + O  O4 }' x3 ?
    } 5 g1 N6 l9 {4 Y: u

    3 a' s  P1 A  U# P& q" u$ e7 v# |
    int sort_function( const/ J% U/ C; K5 u, _
    void: F/ ~8 v; f# D8 R$ b( T! \
    *a, const/ Z- e2 X9 l" [  F7 q
    void+ n4 ]& e8 D. a" b: `* @
    *b) 1 q( i2 L$ `1 u- f5 q+ j
    {
    5 {8 i; K2 |5 N  i8 I   
    return& K+ ?6 |1 w/ v0 r% |: J
    *(int*)a-*(int*)b;
      |" l! m  _2 v% ~8 P+ F. |6 y}

    3 u4 {4 P0 W( H! a& m( U9 R( S
    ( N' O- A2 Z7 |5 n& \$ m  b( [. d( ~/ U
    - P, N, G- W5 L/ }: P4 }
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    / D- M# U: n* z5 K: [5 U5 N  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    " I/ w$ L& U- B4 B: X+ a( v$ Z
    5 _. j! Q, B, _9 v  @) G% |6 c" Q7 w7 Z5 {% ?: B7 V: w0 j
    void MyFun(int x);9 c: V) e7 Z! d- b7 ?0 s" \
    typedef
    void (*FunP)(int);
    + m9 v$ a+ u, S$ I6 C9 c
    ( Z: w8 v7 f1 p2 S  v9 SFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;+ ?# H' @' z% J; g5 ?

    ( O, J$ h) z) [. t3 K
    int main(int argc, char* argv[])- b- H# A0 [0 f0 ^
    {
    ' j/ t2 F0 ]/ L   MyFun(
    10);                        //这里是调用MyFun(10);函数. `- V$ t2 `9 Z" }& A% g$ q! o

    ; ^6 U3 x; w8 ]4 p9 ^8 k   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    / r- a7 W! Y4 c1 `" n  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        ) x2 C3 d0 c4 ^' m+ c5 B" B
    ' d: R& {# S% {. n
       fp2
    =&MyFun;                        
    8 H2 X; n% c( o* ~) \5 `   fp2(
    30);    6 @) e1 ^" x3 T! M

    ; n. X4 Q, K4 d: s% R: }; \, _6 c   fp3
    =MyFun;                        
    ' t' a* Z% I1 a. [, n8 H8 ]   fp3(
    40);   
    4 g0 Q# K& b$ V& X  ]) T) A: `: q; I8 M1 u
       fp4
    =MyFun;  " g9 ^9 ?6 j  P$ h' w
       (
    *fp4)(50);   
    & T6 o) o+ q8 Z$ t
    3 @0 e/ l! ~2 T% W   
    return
    . |1 m) a3 [% d; e% J! h' l3 L- m* A* a% w0;' d: S5 }+ l& ?. {3 q+ u/ i# W  ^7 M
    }5 V( o* p" b  d1 L; t* h

    # ]: w# P/ H4 h/ t; A. t3 ^
    void MyFun(int x)                     //这里定义一个MyFun函数$ e$ f% P) {# [; E9 `5 {3 ]
    {; N8 ]7 _* l6 Q9 j8 o
       printf(
    "%d\n",x);
    / Y) Y' E4 T9 x) g% s}
    8 q' M" i+ y' F/ w$ _

    0 ]6 X: X( I9 H- }% p* D
    * y( l" v2 o& Z& P& d# M1 k3 K# T! j  @2 ]" a
    1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    4 t+ Q; u4 }3 L- ~% R2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。3 a. D4 N* x8 }# r1 ]1 S
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    5 ?% @1 _, k' J# N) P4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-3-19 06:18

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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