先说一下强制转换,可以跳过。例子:
#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指针赋值。例如:int *pint;void *pvoid;...
用void* 定义一个void类型的指针,它不指向任何类型的数据,意思是,void*指针“指向空类型”或“不指向确定的类型”,而不要理解为void*指针能指向“任何的类型”数据。简而言之:void*只提供一个地址,没有指向。
许多初学者对C/C++诧言中的void及void指针类型丌甚理解,因此在使用上出现了一些错诨。本文将对void关键字的深刻含义迚行解说,并详述void及void指针类型的使用方法不技巧。
void InitTIMER0(void);//inital timer0 /******************************************************************/ /* 主函数 */ /******************************************************************/ void main...
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; ...
许多初学者对C/C++语言中的void及void指针类型不甚理解,因此在使用上出现了一些错误。本文将对void关键字的深刻含义进行解说,并详述void及void指针类型的使用方法与技巧。
一般来说,程序的起始地址是从“代码区”的0地址开始存放的(注:如果插入一个内存分布图,则更能说明问题,此处省略),但实际上现代操作系统并非如此,却保留了从0开始的一块内存。至于这块内存到底有有多大,与具体...
深入理解计算机系统: csapp.h csapp.c //csapp.h /* $begin csapp.h */ #include #include #include #include #include #include #include #include #include #include #include #include #include #...
它鼓励编程者在面对复杂的代码和逻辑时,保持冷静和专注,以清晰的思维去理解和解决问题。 而void,作为C语言中的一个关键字,代表着无类型或空类型。它代表着一种无限的可能性和空灵的境界。在甘晴void中,它赋予...
void PID_Operation(void) { uInt32 Temp[3] = {0}; //中间临时变量 uInt32 PostSum = 0; //正数和 uInt32 NegSum = 0; //负数和 if(PID.iSetVal > PID.iCurVal) //设定值大于实际值否? { if(PID.iSetVal - ...
。。。
。。。
Tp01.struct的使用,及字节对齐;struct和class的差别与联系;struct中指针的危险性。 Tp02.extern C修饰的作用及头文件宏保护。... TP22.void*和void** TP23. char a[ ] 和 char *a 是一样的 TP24.指针数组等价性
甘晴void,学习领域包括计算机网络、数据库系统以及计算机系统(包括操作系统)。这些领域都是计算机科学的核心,对于理解和掌握现代计算机技术至关重要。
=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关键字的相关资料,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说结构体……通过...
利用所学的三种程序基本结构以及数组、指针、结构体、用户自定义函数、文件进行一个中型程序的设计,进一步理解和掌握C语言的语法以及三种基本程序结构的综合应用。 2.通过程序中涉及到的排序、查找、求和等操作...