C语言--指针的进阶测试

1.指针数组

    int* pArr[10];    //pArr是数组名,该数组存放了10个int*的元素

2.数组指针

    int (*pA)[10];    //pA是一个指针,指向一个存放10个int元素的数组

3.函数指针

    int (*pFun)(int,int);    //这是一个函数指针,指向一个返回类型为int,两个参数为int的函数

4.有趣的代码

        1)(*(void(*)())0)();

        以上代码,看起来非常有意思,突破点就是0和void,若是熟悉函数指针类型的话,就会发现,void(*)()若是在*后面加上p,变成void(*p)(),很明显p就是一个函数指针,因此,void(*)()是一个函数指针类型,返回值void,参数为空,(void(*)())0又怎么解释呢?不知道大家记不记得强制类型转换的写法,如(int)10.1;当然这种由实型转换为整形会丢失精度,只保留10,我们此处不做考虑,回到正题,若是将10.1和0同等看待,(int)和(void(*)())同等看待,就会发现这是一个强制类型转换,0变成了一个函数指针,只是这个指针是0地址处的。若是能看到这里,那么后面的代码就简单了,首先对0地址处的函数指针进行解引用,得到什么?函数指针指向函数,解引用得到函数。再思考一个问题,函数是怎么调用的如:

                                                        int add(int x,int y)

我们要想使用它,很简单,就是add(5,6); 函数名加参数即可,若是无参函数呢?

                                                       void print()

直接写print(),前面说到(*(void(*)()0))就是一个函数了,那么它怎么调用呢?即在其后面加上(),

(*(void(*)()0))()调用,这句代码整体看下来就是一个无参函数调用,在0地址处的一个返回值为void无参函数的调用。

        2)void(*singal(int,void(*)(int)))(int);

        这句代码又该怎么看呢?在看这句代码前,我们首先要了解*的优先级和结合性,如int *p(int)和int (*p)(int)怎么看,第一个是一个函数声明,该函数返回值是int* 函数名为p 返回值为int,第二个是一个函数指针,指向一个返回值为int,参数为int的函数,因此singal(int,void(*)(int))优先一起看,那么还剩下什么?void(*                               )(int);这是函数指针啊,

                                                         void(*)(int)  singal(int , void(*)(int));

这么看的话是不是有点明白了,当然上述写法是错误的,若是记得typedef的用法的话,可以用typedef  void(*vfun_int)(int); 那么以上代码即为:

                                                         vfun_int singal(int,vfun_int);

这有点类似于(不是)数学里的换元,可以清晰知道其结构,看到这就会明白了,这是一个函数声明,singal是一个函数名,int,vfun_int是参数, vfun_int是返回类型。

        3)void(*pArr[10])(int,void(*)(int));

        首先看pArr,看它与*还是[]结合,很明显是pArr[10],这是一个数组,元素为void(*)(int,void(*)(int))类型,这是一个函数指针,那么pArr就是一个函数指针数组,有10个元素,元素类型为函数指针,其参数为int和返回值为void参数为int的函数指针,返回值为void。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值