函数指针
首先要理解以下三个问题:
(1)C 语言中函数名直接对应于函数生成的指令代码在内存中的地
址,因此函数名可以直接赋给指向函数的指针;
(2)调用函数实际上等同于"调转指令+参数传递处理+回归位置入栈",
本质上最核心的操作是将函数生成的目标代码的首地址赋给 CPU 的 PC 寄存
器;
(3)因为函数调用的本质是跳转到某一个地址单元的 code 去执行,所
以可以"调用"
一个根本就不存在的函数实体,晕?请往下看:
请拿出你可以获得的任何一本大学《微型计算机原理》教材,书中讲到,
186 CPU 启动后跳转至绝对地址 0xFFFF0(对应 C 语言指针是
0xF000FFF0,0xF000 为段地址,0xFFF0 为段内偏移)执行,请看下面的
代码:
typedef void (*lpFunction) ( ); /*
定义一个无参数、无返回类型的 */
/*
函数指针类型 */
lpFunction lpReset = (lpFunction)0xF000FFF0; /* 定义一个函数指
针,指向*/
/* CPU
启动后所执行第一条指令的位置 */
lpReset(); /*
调用函数 */
在以上的程序中,我们根本没有看到任何一个函数实体,但是我们却执
行了这样的函数调用:lpReset(),它实际上起到了"软重启"的作用,跳转到
CPU 启动后第一条要执行的指令的位置。
记住:函数无它,唯指令集合耳;你可以调用一个没有函数体的函数,
本质上只是换一个地址开始执行指令!
数组 vs.动态申请
在嵌入式系统中动态内存申请存在比一般系统编程时更严格的要求,这
是因为嵌入式系统的内存空间往往是十分有限的,不经意的内存泄露会很快
导致系统的崩溃。
所以
一定要保证你的 malloc 和 free 成对出现
,如果你写出这样的一段程序:
char * function(void)
{
char *p;