如何理解 (*(void (*)())0)();

来源:互联网 发布:苹果6s怎么开4g网络 编辑:程序博客网 时间:2024/06/04 18:21

我想很多人看到这个语句的时候也都是懵圈的状态,这是我在书上看到的一个很有趣的语句,一般不会用到这个例子,不过好好地理解它,能加深对C语言的认识,最起码对我是有帮助的,而且后来还用上这里面的一些小技巧。

(怎么排版和我编辑时的排版不一样...囧rz...算了)

1、铺垫

在分析上面的语句前,我们先从简单的入手。先来区别和理解下面这两个定义。

float  *g();   和 float  (*h) ();

直接上答案:由于( )结合的优先级别高于*,所以g先和后面的( )结合,构成一个函数,该函数的返回值是一个指向float 数的指针。同理,h是一个函数指针,它所指向的函数的返回值是一个浮点数。

当我们知道如何声明一个给定类型的变量,那么不难得出该类型的类型转换:只需要把声明中的变量名和声明末尾的分号去掉,然后将剩下的部分用一个括号整个“封装”起来。最简单的例子比方说我们以前学过的强制转换   (int) value这类的,但是们现在稍微复杂一些。如下:

 float  (*h) ();   表示h是一个指向返回值为浮点类型的函数的指针,所以有

(float  (*) () )   表示一个“指向返回值为浮点类型的函数的指针”的类型转换  (这一步需要理解一下)


2、理解

有了上面的铺垫之后,我们就开始理解(*(void (*)())0)();这个语句。

1) (void (*)())  里面的这个和铺垫的一样,是一个类型转换,表示一个“指向返回值为void类型的函数的指针”的类型转换。

2)   (void (*)())  0  这是表示将常数0转换为“指向返回值为void的函数指针”类型。

3)    有了1) 和 2)的理解之后,我们就明白,0是一个函数指针,它指向的函数的返回值类型为void,这样就比较好办了,那我们就按照使用指针变量的方法去理解它。我们使用一个指针变量的时候,前面会带一个*号,同理,对于这样一个函数指针,我们在调用它的时候。也类似地这么调用,就是(*(void (*)())0)();这就分析完了。


3、补充

这个例子主要运用在计算机地址方面,比方说arm芯片一上电的时候,是从0地址处开始执行程序。而要对各个状态字进行配置或者存入某个内存块的时候,处理的方法也都是把一个常数(也就是这个地址)转换成一个指针类型,然后对这个指针进行操作就能对该地址进行操作,这方面在嵌入式的配置方面见得比较多。

我之所以说这个例子对我有帮助是这样的。我大哥之前写了一个功能挺复杂的驱动程序,其中有一条语句是这样的:

pos == IOFPGA_DO_DATA_ADDR(iofpga_if_get_dod_addr(), pfifo) ;

那我就进去看一下它的定义咯,如下:

#define IOFPGA_DO_DATA_ADDR(base, reg)((unsigned int)&(((struct st_iofpga_do_data *)((int)base))->reg))

右边的表达式我一看就知道在干嘛了(因为在此之前我看过标题的例子),我们看一下右边的表达式对这base和reg这两个形参做了什么事情,很明显嘛:

1)首先把base强制转换为int类型,注意,它是一个常数。

2)结合上面的例子分析,(struct st_iofpga_do_data *)((int)base) 和上面的例子用法一样,就是把一个常数转换成一个指针,这      里是转换成自定义的结构体指针。

3)((struct st_iofpga_do_data *)((int)base))->reg)  把这个常数转换成结构体指针之后,在这个结构体中找到传入的reg成员。

4)  &(((struct st_iofpga_do_data *)((int)base))->reg))  找到该结构体里面的这个成员之后,用&取其地址

5) (unsigned int)&(((struct st_iofpga_do_data *)((int)base))->reg)  &取到这个成员的地址之后,强制转换为(unsigned int)类型

6)分析完毕....

然后结合我大哥对结构体的定义和传入的实参,不难理解这个函数的功能就是找到结构体特定成员的偏移地址。可能是新手的心态吧,当时一下子就看出来还是挺高兴的,以前看标题例子只是为了好玩,没想到实际中还用上了,不过还是得多多积累。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 b2汽车驾驶证年审过期几天怎么办 上海驾照到期人在外地怎么办 交警开的罚单交不了怎么办 珠海交警微信交罚单扣分怎么办 驾驶证违法罚款单子没有了怎么办 转账密码输错3次怎么办 汽车违章扣6分怎么办 汽车扣了72分年检怎么办 汽车扣了50分怎么办 汽车扣了15分怎么办 汽车扣了27分怎么办 汽车扣了40分怎么办 行驶证掉了怎么办 异地 高速上没带驾驶证行驶证怎么办 身份证驾驶证行驶证都丢了怎么办 驾驶证年审过期一个月怎么办 柴油车辆年检尾气不合格怎么办 驾驶证过期了5天怎么办 过了审车时间怎么办 骑车没带行驶证怎么办 轿车行驶证丢了怎么办 车子没年检被扣怎么办 上海车辆年检过期了怎么办 行驶证过期十天怎么办 行驶证盖章满了怎么办 驾照c证扣12分怎么办 两年小车忘年审怎么办 4年车检过期了怎么办 车检过期了1周怎么办 超过检车几天了怎么办 驾驶证扣两个6分怎么办 行驶证检验有效期过期怎么办 驾驶证被扣26分怎么办 c1驾驶证扣26分怎么办 驾驶证被扣6分后怎么办 c1驾照年审过期一天怎么办 审驾照时间过了怎么办 b2驾驶证扣了分怎么办 a2驾照逾期未审怎么办 中学生只想打游戏不肯学习怎么办 汽车4年未年检怎么办