C语言指针进阶,数组指针,指针数组,函数指针

数组指针:

数组指针的意思:指向数组的指针。

这里的数组指针的解释:1,指向num这个数组。2,该数组中有5个元素。3,该数组中元素的类型是int。

注意:&arr是数组的地址,它的类型是int (*)[5],而arr是该数组的首地址,类型是int *,所以这里如果用int (*p)[5]=arr;是错误的。

           但你会发现&arr和arr打印出来的值是一样的。但如果数组地址加1则直接跳过该数组,而数组的首地址加1则是跳到下一个元素。

#include <stdio.h>
int main()
{
    int i=0,j=0;
    int arr[5]={1,2,3,4,5};
    int (*p)[5]=&arr;
    for(i=0;i<5;i++)
    {
        printf("%d ",(*p)[i]);       
    }
    for(j=0;j<5;j++)
    {
        printf("%d",*(*p+j));
    }
    return 0;
}

 

指针数组:

指针数组的意思:数组中的每个元素是指针。

这里的指针数组的解释:1,该指针数组有5个元素。2,该数组中元素的类型是char*。

所以这时可以把arr1,arr2两数组的首地址(char*类型)存入该数组中。

一:

#include <stdio.h>
int main()
{
    char arr1[5]="my ";
    char arr2[5]="name";
    char *q[5];
    q[0]=arr1;
    q[1]=arr2;
    printf("%s",q[0]);
    printf("%s",q[1]);
    return 0;
}

 

二:

这里的指针的解释:1,一个长度为2的数组。2,该数组元素的类型是数组指针,即p[0]中存放了数组str的地址,p[2]中存放了数组str1的地址。

#include <stdio.h>
int main()
{
    char str[10] = "hello ";
    char str1[10] = "world";
    char(*p[2])[10];
    p[0] = &str;
    p[1] = &str1;
    printf("%s", p[0]);
    printf("%s", p[1]);
    return 0;
}

 

函数指针:

函数指针:指向函数地址的指针。(获得函数地址即可调用函数)

这里的函数指针的解释:1,p中存放Add函数的地址。2,函数参数的类型是(int,int)。3,函数的返回值是int。

#include <stdio.h>
int Add(int x,int y)
{
    return x+y;
}
int main()
{
    int (*p)(int,int)=Add;
    printf("%d\n",Add(1,2));
    printf("%d\n",(*p)(1,2));
    return 0;
}

函数指针的数组:

解释:一个指针数组,里面放的都是函数指针

看似好像没什么用,其实很是有用的。假设你有多个函数,分别解决不同的问题,函数指针数组可以对应的调出所需要的函数解决问题,如果有新的函数也可以直接加入该数组。

#include <stdio.h>
int Add(int x,int y)
{
    return x+y;
}
int Sub(int x,int y)
{
    return x-y;
}
int Mul(int x,int y)
{
    return x*y;
}
int Div(int x,int y)
{
    return x/y;
}
int main()
{
    int (*p[5])(int,int)={0,Add,Sub,Mul,Div};
    printf("%d ",(*p[1])(2,3));
    printf("%d ",(*p[2])(2,3));
    printf("%d ",(*p[3])(2,3));
    printf("%d ",(*p[4])(2,3));
    return 0;
}

函数指针数组的指针:

#include <stdio.h>
int Add(int x,inty)
{
    return x+y;
}
int main()
{
    int (*p)(int,int);                    //函数指针
    int (*p[5])(int,int);                 //函数指针数组
    int (*(*pp)[5])(int,int);             //指向函数指针数组的指针
    return 0;
}

测试:

其实并不难,只是烦,套娃。可以试着分析下下面两个指针

第一个:(*(void(*)())0)();
        1, void(*)()        //一个函数指针
        2, (void(*)()0)     //强制类型转化,0变成函数的地址
        3, (*)()            //函数指针的解引用
        4, (*(void(*)())0)()//调用地址为0的函数 


第二个:void(*test(int,void(*)(int)))(int);
        1,test(int,void(*)(int))        //函数名为test的函数,参数类型是 (int,函数指针)
        2,void(*        )(int)          //是不是像一个函数指针
        3,所以表达的是一个名为test的函数,他的参数类型是(int,函数指针),它的返回类型是函数指针。

注意:  这里的*就不是解引用了,本来test就是一个函数解引用不了
        void(*)() test(int,void(*)(int)) 不要以为是这样,这是错误的。   
            

总结:

回调函数,使用一些复杂的函数时都会用到指针。对指针的理解还是很重要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jchenn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值