C 学习记录-指针函数和函数指针, 烧脑的指针

指针函数和函数指针, 相信很多同学跟我一样,刚开始总会把他俩弄反, 理解不了他俩的用法
 

开始我们先从定义开始说下

1, 指针函数 指带指针的函数, 本质上他也是一个函数, 只是他的返回值是某一类型的指针,不是像基本数据类型定义的函数,返回的是基本数据类型值.
    类型:
    类型标识符 *函数名(参数列表)
    int *func( int x, int y); ----> (int *) func(int x, int y);

    从例子可以分开看, 首先他是一个函数, 只是这个函数的返回值是一个指针(地址), 函数返回值必须用同类型的指针变量来接收;
代码解析:
int * getDate(int week, int day){
    int calendar[5][7] = {
        {1,2,3,4,5,6,7},
        {8,9,10,11,12,13,14},
        {15,16,17,18,19,20,21},
        {22,23,24,25,26,27,28},
        {29,30,31,-1}
    };
    return &calendar[week-1][day-1];
}

int main(int argc, char *argv[]){
    int week,day;
    printf("请输入周数(1-5), 天数(1-7)\n");
    scanf("%d ,%d", &week, &day);

    if(week <1 || week >5 || day <1 || day > 7) return 0;

    printf("%d\n", *getDate(week, day));

}


2, 函数指针  指向函数的指针变量, 即本质是一个指针变量, 他接收函数名, 并可以用此变量名操作赋值的函数, 在C里,可以作为回调函数使用, 函数原型:
    类型标识符 *变量名 (参数);

    int (*f) (int x);  //声明函数指针

    f = func; //将func函数的首地址赋值给指针f, 一个函数名称就表示了它的地址, 所以在写时可以忽略&取地址符

     ==> *(int *) &f = f =(int)func;  &f求指针变量f本身的地址;
    
    指向函数的指针包含函数的地址的入口地址, 这个特殊的指针指向一个返回整型值的函数;其实仔细观察函数指针和指针函数 只是在命名的时候多了一个括号,
    就是这个括号改变了他们的意义, 如果没有括号, 变成了返回有类型的指针函数了;
    
调用实例:
    int (*fptr) ();
    int func(){  printf("xxxxx"); return 0;}
    
    fptr = &func;
    fptr = func;

    int x = (*fptr)();    或 int x = fptr();

 

    指针函数 =====> 返回值是某一类型指针的函数,本质是函数;

    函数指针 =====> 能接收函数名的指针变量, 本质是指针变量;

typedef有两种用法:
一、一般形式,定义已有类型的别名
  typedef   类型    定义名;
二、创建一个新的类型
     typedef   返回值类型   新类型名(参数列表);

1)typedef int NUM[10];//声明整型数组类型

    NUM n;//定义n为整型数组变量,其中n[0]--n[9]可用

2)typedef char* STRING;//声明STRING为字符指针类型

    STRING p,s[10];//p为字符指针变量,s为指针数组

3)typedef int (*POINTER)();//声明POINTER为指向函数的指针类型,该函数返回整型值,没有参数

    POINTER P1,P2;//p1,p2为POINTER类型的指针变量

 

用函数指针 完成c的回调功能

使用typedef  定义一个函数指针类型

    形式 typedef 返回类型(*新类型)(参数列表);

    例:
    a.h
     typedef char (*PFUNC)( int x);
     void set_listen(PFUNC func);
    
    a.c
    PFUNC pfunc;        
    void set_listen(PFUNC func){
        pfunc = func;
    }

    void do(){
        (*pfunc)(11);
    }

    b.c    
    char aFun( int x){
        char cc='a';
        return cc;
    }

    void listener(){
        set_listen(aFun);

    }

   

 对函数来说,传递的任何参数仅仅是原来参数的一个拷贝,所以想要在一个函数内改变另一个函数内的变量值, 就必须把变量地址传入, 对变量地址操作, 地址内的值变了, 另一个函数内的变量对应的值必然变了;

每个变量都有一个地址, 指针变量是存放一块内存地址,就是声明的这块地址可以存放内存地址值,  整型变量存放的是整型数值, 这个地址存放的是整型值,其他类型类推

以上内容为个人学习感悟总结, 如有不对地方,请留言,谢谢

   

谢谢 http://nevel.cnblogs.com/p/6370264.html的整理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值