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

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

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

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

    连续签到: 1 天

    [LV.2]偶尔看看I

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

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

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

    ×
    C中最重要 最难的就是 指针咯!
    $ D0 q# @3 c5 R0 Z' F& H& _- a+ r* Z1 ~; f1 h- |
    ! e  p( C: u4 d; D
    在学习C++的回调函数机制时有一个关于函数名和函数指针的疑惑,如是就自己研究了下二者的关系。
    ! g# {! y( \0 K1 S  快速排序的原型:
    ) P2 {/ b, }8 G1 g  void qsort(void *base, size_t nelem, size_t width, int (_USERENTRY *fcmp)(const void *, const void *));
    , }# D& F( w8 ?. i# N' w  可见qsort接受一个类型为_USERENTRY的函数指针fcmp,但是下面代码中qsort函数接受一个函数名,却不是一个函数指针。而函数名和函数指针的关系如何呢?
    + j0 g" ~+ H4 [8 X: x( ^7 c1 ?, | #include <stdio.h>
    6 e, t1 F! E5 c. ]#include
    <stdlib.h>
    % F% C: d* b( V1 u- Kint sort_function( const
    % |) c& r# i  p3 G( M4 }+ Evoid) Z1 l8 F* Z2 a) y4 F& u
    *a, const8 j: w- O' h2 k) P. u) }  Y
    void: {$ S* m# o9 C* B% E
    *b); + y. p2 Q# `3 \7 o; @
    int list[5] = { 54, 21, 11, 67, 22 }; ( Q3 f  G7 e5 b1 T: ]

    3 t" C; ], r  \1 T. N
    int main(void) % i  l) F$ p$ j9 P2 z" P
    {
    " }' x3 a9 V# c: n/ T   
    int x; + B5 ^4 Y7 M% p6 u; [9 m
    * G; ]5 L& X4 }% M. b; m
       qsort((
    void  g) h; |# X- G" v' T# l, V# A
    *)list, 5, sizeof(list[0]), sort_function);   N; s8 N7 W# c5 r. ]. W6 e0 m
       
    for (x =- q6 n  ^: o' A# h9 x* l6 Y
    0; x <
    $ x6 x: H0 z4 |9 p) g5; x++)
    9 }# @- x6 {. `, V   printf(
    "%i\n", list[x]);
    0 s( q: Z- s5 D/ @3 u& F. o2 C   
    return& S6 s5 a- _* M: q  L+ F" O
    0;
    4 K4 p: M7 I( Y" x; G}
    3 O6 y; ]' U$ T" S3 j5 s, N
    5 p( n7 P. v: g+ V  K2 `8 \; }
    int sort_function( const
    ( l0 r6 O; V# e9 N% K! J0 N1 Bvoid& X: h5 w: z4 H  q+ U
    *a, const
    ! x) r% i: i; @$ |6 g6 Kvoid% U5 `. z: v% c6 H! ~& e# E) j
    *b)
    6 {/ B6 @: X6 o5 }{ 6 o; E! D4 k  ]5 r
       
    return; c+ N/ _/ j2 ]7 {
    *(int*)a-*(int*)b;
    / D. d! M* K, |6 F. ?- V}
    5 e5 B4 n1 c3 B3 u# X
    - S4 \- i8 U% J4 A) `  M
    1 y. T* E! T+ z& E8 [
    + Z1 o5 _! Z: X
      函数指针实际上就是该函数代码段开始的地址。其实,编译器对于函数名、函数指针都是转换为一个地址,这个地址就是该函数代码起始地址。
    % z0 T6 b- I4 {  下面的代码说明了函数名和函数指针的关系:#include<stdio.h>6 T! w" Q% f' B6 L6 t% [; ^

    - E# j$ F/ {: H( w5 N, J! T+ ]0 F
    " k+ c" P6 E5 G2 ]void MyFun(int x);0 m7 v( _& K$ T+ K: e
    typedef
    void (*FunP)(int); ; N# Y/ @  J) j' h( P0 v3 c1 l. ?

    3 E8 u7 g# Z3 @% r5 y" ]8 bFunP fp1
    = NULL, fp2 = NULL, fp3 = NULL, fp4 = NULL ;
    ' z! @; I" f, z( ~3 y3 d* O" y( x1 P' S, k, Y+ {( @
    int main(int argc, char* argv[])( q+ c8 A- E" c6 h, A/ c2 o$ F
    {3 P" R+ k; _1 p6 t% x
       MyFun(
    10);                        //这里是调用MyFun(10);函数$ f5 B/ m) \2 T( K' P7 s
    $ s" y9 j; Q* f
       fp1
    =&MyFun;                       //将MyFun函数的地址赋给FunP变量
    ; y5 |9 B3 V1 p6 n/ k2 ]- q  (*fp1)(20);                        //通过函数指针变量FunP来调用MyFun函数的。                        $ f: _7 B  M! a
      C) Z  E1 o+ @$ l) ]4 E" W% ?
       fp2
    =&MyFun;                        
    5 s4 R5 k, O2 S2 v2 I4 B   fp2(
    30);   
    3 `8 g& p& L, x' a$ ~# B" X
    1 E6 Y5 u: _. }& V. x: L2 A% v   fp3
    =MyFun;                        , ^+ E4 l) D& U' s
       fp3(
    40);    ! s1 Y: K$ U: v
    3 b0 L+ s$ W1 G% l8 f
       fp4
    =MyFun;  
    4 g$ r( l0 M7 B; n# l5 ]   (
    *fp4)(50);   , \2 }: T8 t: a* L; a" @1 X4 D
    - G$ S+ z1 s" G( b
       
    return5 A! _+ ^' i  _; K# B$ R, O
    0;: m/ h; E3 k. B: v
    }' `& n1 f6 S" y" ]. G9 [

    ' W! P& v, `( x( i
    void MyFun(int x)                     //这里定义一个MyFun函数0 ]0 s: _. a( z5 M" S/ K
    {
    5 A/ q% d: q, t, @+ @$ D   printf(
    "%d\n",x);
    1 ^; ]. E) [- H6 M, J, X8 ^6 ^}

    $ M0 l: D1 T3 ^0 V! ~( M
      O% M- _, a! T- J; U9 K/ x0 P2 S+ j5 E6 j; A

    - _: H& X7 E* I/ w+ U+ o) Y1. 可见,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
    " @. r# {1 q( o0 O( \2. 但函数名调用如果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10);这种形式地调用        (这样方便多了并与数学中的函数形式一样)。
    & R  W' ^  o/ V$ g0 F3. 为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。, S" K, F  Q. f
    4. 赋值时,即可FunP=&MyFun形式,也可FunP=MyFun
    "真诚赞赏,手留余香"
    还没有人打赏,支持一下
    楼主热帖
    帖文化:【文明发帖 和谐互动】 社区精神:【创新、交流、互助、共享】
    您需要登录后才可以回帖 登录 | 立即加入

    本版积分规则

    招聘斑竹

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

    GMT+8, 2025-6-6 15:51

    Powered by Discuz! X3.5 Licensed

    © 2001-2025 Discuz! Team.

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