设计一个程序,当计算机启动的时候,硬件将调用首地址为0位置的子例程。 经过思考,获得
(*(void(*) ())0) ();先暂不看下列内容,思考一下,这个语句,到底实现了什么功能?
C语言中,有以下的特点(规则)。
任何一个变量在使用前均需要声明。 int i = 0; //声明一个有符号整形变量 i ,并赋初始值为0 u8 buf[64]; //声明一个无符号8bit的数组 buf,长度为64,这种经常使用在单片机开发中 任何一个函数,在使用的时候,均需要对其进行声明。 void fun1(void); //声明一个函数fun1,没有输入的参数,没有返回的参数 u8 fun2(u8 para1); //声明一个函数fun2,输入参数为u8 para1,返回参数类型为u8C语言也可以用指针来指向一个变量或者一个函数。
指向变量的指针 //ptr为指向整形变量的指针 int i = 0; int *ptr = &i; //注意,在上述表达中,偶尔会有误认为 *ptr = &i ,但实际上,上述语句等同于下述语句 int i = 0; int *ptr; ptr = &i; 指向函数的指针 void (*fun1_ptr)(void); //fun1_ptr是指向一个函数的指针,这个函数没有返回值 int (*fun2_ptr)(void); //fun2_ptr是指向一个函数的指针,这个指针返回值为整形变量 //此处为什么要将*fun2_ptr,用括号括起来?思考“声明一个函数,其返回值为一个整型变量的指针。” 返回值为整形的指针 int *fun1(void); /* 由于()优先级高于*,所以 int (*fun2_ptr)(void);指的是fun2_ptr这个指针指向的函数,返回值为一个int变量; int *fun1(void);指的是fun1这个函数,返回值为一个指向int的指针。 注意区分两者的不同。 */有了上述的准备工作,我们做的是“设计一个程序,当计算机启动的时候,硬件将调用首地址为0位置的子例程。”
暂时可以做到的是,运行某个地址的函数。
int (*fun_ptr)(void); (*0)();但这种做法是不行的,因为*需要一个指针来做操作数,并且这个指针为函数指针。
换句话说,我们只要将 0 强制转换成函数指针就可以了?
那么如何转换呢? 借用上述准备知识中的,函数指针强制类型转换,将常数0转换为“指向返回值为void的函数的指针类型”
(void (*)())0然后将这一串东西,替换原本的0,即
int (*fun_ptr)(void); (*(void (*)())0)();如果用这种做法,能否正常运行?
int (*fun_ptr)(void); fun_ptr = 0; (*fun_ptr)();个人看法:在C语言中,指针是不能随便赋值后访问的,我们不可以这样做。但未经实验验证过,期待各位的想法。