函数指针&二级指针

函数指针

顾名思义函数指针就是指向函数的指针,这个指针是指向一个函数地址,我们在定义函数的时候也会像变量一样,有一个内存地址,但不同于变量,变量存储的是固定的值,而函数存储的是函数的内在地址。通过函数指针可实现Java多态的效果。让我们体验一下函数指针吧!

void funcPoint1(){
    printf("这里是函数1:%d\n",333);
}
void funcPoint2(int i){
    printf("这里是函数2:%d\n", i);
}

void main(){
    //函数指针的定义,返回值(*函数指针名称)(函数参数)=&函数名称

    //无参指针函数
    void(*funcP1)() = &funcPoint1;
    //有参数的指针函数
    void(*funcP2)(int) = &funcPoint2;


    //调用函数指针
    funcP1();
    funcP2(3);
    printf("函数1指针地址:%#x\n", funcP1);
    printf("函数2指针地址:%#x\n", funcP2);
    system("pause");

}

输出:

这里是函数1:333
这里是函数2:3
函数1指针地址:0x12a1050
函数2指针地址:0x12a1055
int add(int n1,int n2){
    return n1 + n2;
}
int minus(int n1,int n2){
    return n1 - n2;
}
//我们可以函数指针作为函数参数传入,实现java中的多态
void addOrMinus( int (*f)(int,int),int a,int b){
    int c = f(a,b);
    printf("计算出来的值为:%d\n",c);

}
void main(){
    addOrMinus(add,3,4);
    addOrMinus(minus,99,3);
    system("pause");
}

输出:

计算出来的值为:7
计算出来的值为:96

通过传函数地址,就可以调用该函数进行操作,在Android开发中经常会用到网络数据的回调,NetCallBack功能,那么C中就可以应用函数指针进行实现如:

#include //这里需要引入线程休眠头文件
/*
 *网络请求数据
 */
void netRequest(char* url,void(*callBack)(char*)){
    printf("请求地址:%s\n",url);
    Sleep(2000);
    callBack("服务端的数据");
}
/*
 *回调函数
 */
void callBack(char* netResult){
    printf("网络请求回调函数\n");
    printf("来自服务端的数据:%s\n",netResult);
    system("pause");
}
void main(){
    char* url = "www.baidu.com";
    netRequest(url,callBack);
}

输出:

请求地址:wwww.baidu.com
网络请求回调函数
来自服务端的数据:服务端的数据

二级指针

说白了就是指向指针的指针

void main(){
    int i = 100;
    //定义p指针变量(该p指针本身也是一个内存地址)存储的是i的内存地址
    int * p = &i;
    //定义pp指针变量存储的是p指针的地址
    int **pp = &p;
       //*p与的差别:p是一个地址,*p是p取地址的值.
        printf("指针地址:%d\n",*p);
    printf("指针地址:%#x\n",&p);
    printf("指向指针的地址:%#x\n",&pp);

    printf("修改之前的值为:%d\n",**pp);
    //多级指针就是要往上一级一级的找,然后通过*来操作内存空间
    **pp = 30;
    printf("修改之后的值为:%d\n",**pp);
    system("pause");
}

输出:

指针地址:0x30f788
指向指针的地址:0x30f77c
修改之前的值为:100
修改之后的值为:30

指针是操作内存的神器,二级指针,不管是几级指针只要记住里面存储的是上级指针的地址。

指针运算

void main(){
    int ids[] = { 56, 89, 56, 33, 15 };
    //数组变量名:ids就是数组的首地址
    printf("%#x\n",ids);
    printf("%#x\n", &ids);
    printf("%#x\n", &ids[0]);
    //以上三个都是同一个地址

    //指针变量
    int *p = ids;
    printf("%d\n",*p);//取第一个值
    //指针的加法
    p++;
    printf("%d\n", *p);//取第二个值

    p = p + 2;//取第三个的值33
    printf("%d\n", *p);
    system("pause");
}

函数指针的内存分配

那么指针为什么要有类型,它与地址有什么差别:

  • 地址只是开始的位置

你可能感兴趣的:(函数指针&二级指针)