`

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

阅读更多
先说一下强制转换,可以跳过。例子:
#include <stdio.h>
#include <stdint.h>
int main()
{
    uint16_t a = 0xA5A1;
    uint8_t   b;
    b = (uint8_t)a;    // 16位强制转换为8位
    printf("b=0x%X",b); 
}

a是16位,b是8位,将a进行一次强制转换的结果给b。
我这里的输出结果是
b=0xA1
---------------------------------------正文----------------------------------------

include <stdio.h>

void funa(void)
{
	printf("funa is called\n");
}

int main()
{
	void (*p)();	// 定义一个函数指针
	p=funa;		    // p中存放funa函数地址 
	(*p)();		    // 运行funa 
	printf("0x%X",&funa); // 打印funa函数的地址 
	return 0;	
}


我这里执行之后得到的结果是
funa is called
0x401530


第一行表示funa函数已经执行
第二行表示funa函数的地址为0x401530(在不同机器不同时间结果可能都不同)

以这里的结果为例,此时将上述代码的第11、12行改为
p=0x401530;
(*p)();

运行结果是相同的。

但是将11、12行合并为:
(*0x401530)();
编译器会报错。

也就是说,我们需要将 "0x401530"强制转换为函数地址
参照最开始的强制转换,这里的格式应该大体是这样的:
(*(_______)0x401530)();

接下来只需要考虑下划线里该填什么了
参照之前的
void (*p)();     // 定义一个函数指针
我们可以知道,下划线里应该写
void (*)()

那么结果就出来了,这里要想将11、12行合并为一句,只需要这么写:
(* (void (*)())0x401530)();

我这里修改之后的最终程序为:
#include<stdio.h>

void funa(void)
{
	printf("funa is called\n");
}

int main()
{
	(*(void(*)())0x401530)();	// 运行位于0x401530地址处的funa函数 
	printf("0x%X",&funa); 		// 打印funa函数的地址 
	return 0;	
} 

输出和之前是完全相同的。

--------------------------------------归题--------------------------------------
如果我们需要运行位于0地址处的函数(或者是从0地址处开始运行)
只需把上面的0x401530改成0即可
也就是
(*(void(*)())0)();
---------------------------------------拓展----------------------------------------
如果真的理解之后,可以配合typedef使用。
之前的例子可以这样写
#include<stdio.h>
typedef void (*funcptr)();    // 为函数指针类型定义别名funcptr

void funa(void)
{
	printf("funa is called\n");
}

int main()
{
	(*(funcptr)0x401530)();	// 运行位于0x401530地址处的funa函数 
	printf("0x%X",&funa); 	// 打印funa函数的地址 
	return 0;	
} 


参考资料: <C的陷阱与缺陷> 2.1章 Andrew Koenig著
分享到:
评论

相关推荐

    深入理解void以及void指针的含义

    void的含义void即“无类型”,void *则为“无类型指针”,可以指向任何数据类型。 void指针使用规范①void指针可以指向任意类型的数据,亦即可用任意数据类型的指针对void指针赋值。例如:int *pint;void *pvoid;...

    对void指针的理解.pdf

    用void* 定义一个void类型的指针,它不指向任何类型的数据,意思是,void*指针“指向空类型”或“不指向确定的类型”,而不要理解为void*指针能指向“任何的类型”数据。简而言之:void*只提供一个地址,没有指向。

    void指针小结

    许多初学者对C/C++诧言中的void及void指针类型丌甚理解,因此在使用上出现了一些错诨。本文将对void关键字的深刻含义迚行解说,并详述void及void指针类型的使用方法不技巧。

    DS1302时钟芯片电子时钟显示C程序

    void InitTIMER0(void);//inital timer0 /******************************************************************/ /* 主函数 */ /******************************************************************/ void main...

    C#浏览器编程,学习使用

    4 浏览器网络编程(共两周) 4.1 浏览器工作原理(老师讲解1学时,学生理解1学时) 浏览器工作原理如图4-1所示。 图4-1 浏览器工作原理 ... private void Form1_Load(object sender, EventArgs e) ...

    火灾报警器

    //请先了解ADC0832模数转换的串行协议,再来读本函数,主要是对应时序图来理解,本函数是模拟0832的串行协议进行的 unsigned char ad0832read(bit SGL,bit ODD) { unsigned char i=0,value=0,value1=0; SCL=0; ...

    void 指针详解(用法、注意事项等等 )

    许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。

    深入理解void类型

    一般来说,程序的起始地址是从“代码区”的0地址开始存放的(注:如果插入一个内存分布图,则更能说明问题,此处省略),但实际上现代操作系统并非如此,却保留了从0开始的一块内存。至于这块内存到底有有多大,与具体...

    csapp_深入理解计算机系统_相关文件_csapp.h_csapp.c

    深入理解计算机系统: csapp.h csapp.c //csapp.h /* $begin csapp.h */ #include #include #include #include #include #include #include #include #include #include #include #include #include #...

    甘晴void的一些相关资源

    它鼓励编程者在面对复杂的代码和逻辑时,保持冷静和专注,以清晰的思维去理解和解决问题。 而void,作为C语言中的一个关键字,代表着无类型或空类型。它代表着一种无限的可能性和空灵的境界。在甘晴void中,它赋予...

    PID算法的运用

    void PID_Operation(void) { uInt32 Temp[3] = {0}; //中间临时变量 uInt32 PostSum = 0; //正数和 uInt32 NegSum = 0; //负数和 if(PID.iSetVal &gt; PID.iCurVal) //设定值大于实际值否? { if(PID.iSetVal - ...

    void指针的深刻理解.pdf

    。。。

    void指针的深刻理解.docx

    。。。

    深入理解嵌入式开发之系统开发篇全覆盖

    Tp01.struct的使用,及字节对齐;struct和class的差别与联系;struct中指针的危险性。 Tp02.extern C修饰的作用及头文件宏保护。... TP22.void*和void** TP23. char a[ ] 和 char *a 是一样的 TP24.指针数组等价性

    甘晴void.zip0001

    甘晴void,学习领域包括计算机网络、数据库系统以及计算机系统(包括操作系统)。这些领域都是计算机科学的核心,对于理解和掌握现代计算机技术至关重要。

    达内 coreJava 习题答案

    =0)||(year%400==0)) System.out.println(year+" is bissextile"); else System.out.println(year+" is not bissextile "); } } 2,给定一个百分制的分数,输出相应的等级。 90分以上 A级 80~89 B级 70~...

    详解javascript void(0)

    主要介绍了javascript void关键字的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下

    用C编写班级成绩管理系统

    在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说结构体……通过...

    用C语言开发小型数据库管理系统.txt

    利用所学的三种程序基本结构以及数组、指针、结构体、用户自定义函数、文件进行一个中型程序的设计,进一步理解和掌握C语言的语法以及三种基本程序结构的综合应用。 2.通过程序中涉及到的排序、查找、求和等操作...

Global site tag (gtag.js) - Google Analytics