((void(code *)(void))0x0000)();
例如:
int(*p)();
定义了一个指向函数的指针变量p,它可以存放一类整型函数的入口地址,程序中把哪一个函数的入口地址赋给它,它就指向哪一个函数。
在这里定义的时候直接就把地址0x0000赋值给了p,所以执行这条语句的时候就直接指向了初始化入口(自己的理解)
void(*)() 这是一个函数指针
那么(*(void(*)())就是调用它,
后面跟的地址为指向函数指针的指针地址。
这样的话执行上面程序就会自动跑到PC(0x0000)的地址开始执行程序,也就实现了软件复位功能与看门狗复位差不多。
也能实现任意地址跳转功能。(注意复位地址自己查看各单片机的main函数入口地址或复位的起始地址)
概念补充:
定义一个返回值是空函数指针的定义形式如下:
void (*p) ( )
当把函数指针赋值后,就能通过函数指针调用函数,调用形式如下,
(*p) ( );
或等价的简化形式:
p ( );
假设rst就是函数指针(),则如下调用形式就可以令单片机复位再起。
(*rst ) ( );
如同把char型变量a赋值给int型变量b,(int) 表示强制类型转换:
b = (int) a
(C语言的哲学是定义形式和使用一致):
( (void (*)() ) rst
,简单的调用形式如下:
#define K ( (void (*)( ) ) rst
(*K) ( )
或:
( * ( void (*)( ) )rst ) ( );
这样的语句就完成复位再启功能了。,所以上述语句就能完成复位功能了。保险起见有些程序员常
常喜欢再加个括号:
#define K ( ( (void (*)( ) ) rst )
(*K) ( )
或
( *( ( void (*)( ) )rst ) ) ( );
由于没有输入参数,上述复位代码更严谨的写法是:
#define K ( ( (void (*)(void ) ) rst )
(*K) ( )
或
( *( ( void (*)(void ) )rst ) ) ( );