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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    ' d/ K/ d2 J' E/ ^2 ]. b) W( [, |6 ~0 G
    7 L) ~2 f, P6 ^+ c% j
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。  o, T! i- G8 Q0 `% q
      快速排序的原型:$ S1 p+ {* ^( ^& X
      void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *)); ( ]2 c  C; \$ P$ C1 I) Q1 \
      可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    : b0 V4 L; E- v  @3 |7 J( ~8 w# G #include <stdio.h>
    3 b* {; i* [! u( H#include
    <stdlib.h>
    9 l& d' N% x; E/ U) Fint sort_function( const5 Z7 v3 a# B9 I0 K/ [2 T* Z8 M! y
    void0 F! M2 A4 S) a! M
    *a, const
    * Z6 x3 |5 T$ T3 D3 ]. Wvoid* b, N5 @3 }- c% L  E& Z1 b
    *b); 4 b. M- ~0 d5 y: ~# z6 M
    int list[5] = { 54, 21, 11, 67, 22 };
    " O: Y3 S8 s- q3 p" ~) G8 O: S/ |0 Z0 s! i$ e2 N
    int main(void) , [, M4 p. {/ q/ y) R* K* V) T
    { - m# a* C% ~% U& ?" b& t% M
       
    int x; 2 y- c& r, ]$ |# g' B" a1 s2 a

    ; L, x, u, D; U+ {. [   qsort((
    void% e$ S& k/ y5 g% T
    *)list, 5, sizeof(list[0]), sort_function);
    , P  x, P5 e" j2 g9 G3 Y3 I% M   
    for (x =
    ( e( ?( b3 l6 [2 s8 O0; x <
    % }& i! K; z5 l5; x++) 8 ?: t/ g& w8 P7 i* w
       printf(
    "%i\n", list[x]);
    0 r4 U/ v1 \+ O1 p) F0 |   
    return2 X( S* N. G- V  x. z
    0; , z/ a; D) X& U0 k8 F  x
    } ' w2 S7 w8 \6 R& J- X8 Z) D
    & h; l3 z2 k- ^
    int sort_function( const( j3 o. ]9 R# T& P3 O8 M
    void' |$ z8 ?3 x; ^6 Q
    *a, const
    : h( U, w& c7 r2 R+ n) a) Hvoid
    ; [/ K, _! n. Y- ~*b) # A( K1 O/ y: f% Q# _5 @/ Q" R
    { + s, H. r3 S4 r% M* z7 h1 r% @1 i
       
    return* r. L2 h3 }) l+ H
    *(int*)a-*(int*)b;
    & M/ C$ l9 Z' n6 I}
    $ e: B7 I0 S4 ?0 Q* b, J
      m0 ^+ b& f) \! s/ b+ o! n

      @7 p: p- X4 ~% L/ i% H5 f9 V8 `2 M2 U0 s. p
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    9 }. n& E/ Z4 k4 i* y8 h  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>
    ( h7 z: B% C+ h0 i7 _  U* a
    4 H/ v9 x1 h3 K. a
    7 r% T# `% l2 D& d# o- S/ ivoid MyFun(int x);
    ' _% {0 n, X" \; ?: I# {  htypedef
    void (*FunP)(int);
    ) N4 R6 t! ^& q' X  E5 a
    * S, U$ O' k6 ?2 r+ KFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;) L7 m% B/ X* i& K, J, F
    9 h' z7 H" s2 m0 ]- h1 F
    int main(int argc, char* argv[])9 y* Z% `6 a$ [! Y# e' s$ n
    {
    1 h$ M3 o+ J# x8 U* f   MyFun(
    10);                        //这里是调用MyFun(10);函数! R0 @  F6 t6 b/ U2 {

    7 V6 Q* l# u7 W" a5 l5 S2 u   fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    7 D+ [7 A6 T; ?1 G  c  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        ! T0 Q6 j4 K3 l, C' w/ d2 ~

    ! ^2 [4 B$ X& K# m   fp2
    =&MyFun;                        9 g9 x  R+ ~' F/ ?6 R3 _
       fp2(
    30);   
    ' i2 `- w0 p, p) m- j$ s" u% d' e. H- W( i* k4 e  z. g6 r
       fp3
    =MyFun;                        
    ! o5 Q) E0 @4 u) q5 I  P   fp3(
    40);   
    ! M3 |* f' C2 V2 a& Z! V* F3 q) e6 [) r: p  d; X' d9 R( Y2 }' y3 i
       fp4
    =MyFun;  
    8 F4 N* U3 _5 ~   (
    *fp4)(50);   
    & \7 d0 o4 R, j% [# A  e
    * ^! e2 Y+ c* R3 j9 i   
    return
    " c: ^( U8 ^6 f% C9 J' k* ^# G! [0;# P: H8 ^6 p* w, m7 g
    }
    9 u6 ^/ }. s( F( E: K7 X2 y- @& b8 _4 F9 h' x/ N( ~! l: }
    void MyFun(int x)                     //这里定义一个MyFun函数
    & G  @5 Q  }; g, Q, ]# ?{
    * W/ K: B9 z& h8 a" I   printf(
    "%d\n",x);9 F$ ^+ }# [% R* J
    }

    7 S$ a2 L* j+ \( R8 t. j6 R/ U7 g# G2 m
    2 S: j2 Q% m8 @) b5 K7 D
    " e; d& o% y% S# v3 A( x
    1 A: L  Y. i7 f5 t8 }1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。" u6 p0 ~9 c8 j4 o
    2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。0 T/ X, ^7 [+ c  k
    3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
    : m3 I) u6 a$ h/ h( I0 B4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2026-3-16 09:42

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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