转自:http://www.cnblogs.com/liuxiaoming/archive/2012/08/15/2640170.html
问题:当计算机启动时,硬件将调用首地址为0的子例程,为了模拟开机启动时的情形,如何设计出一个C语句,以显示调用该子例程。
换个问法:有一段程序存储在起始地址为 0的一段内存上,如果我们想要调用这段程序,请问该如何去做?
《C陷阱与缺陷》给出答案:(*(void(*)())0)();
相关知识:函数指针
函数指针是指向函数的指针变量,即本质是一个指针变量。
在C语言中规定,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。我们把这种指向函数的指针变量称为“函数指针变量”,简称:函数指针
指向函数的指针包含了函数的地址,可以通过它来调用函数。声明格式如下:
类型说明符 (*函数名)(参数)
其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。指针的声明必须和它指向函数的声明保持一致。
//函数指针示例:
void func(int x, int y); //声明一个函数 void(*f) (int, int); //声明一个函数指针 f=func; //将func函数的首地址赋给指针f
(*func)(1, 2) //调用形式,等价于func()
问题分析:
1、想要调用这段程序(子例程),设为func函数,由上述相关知识,我们可以使用最基本的指针函数void(*f) ()来调用子例程,调用方法:(*func)();
2、子例程存储在起始地址为 0的一段内存上,故可理解为0是这个子例程的入口地址,func函数入口地址为0。即func指向地址为0的函数;
3、由2知,func为指向地址0的函数,所以func是一个函数指针,设func是一个指向返回值为void类型的函数的指针,故可设func的函数指针声明为void (*pFunc)();
4、由函数声明void (*pFunc)()类比于变量声明,同样,通过强制转换,我们可以得到地址为0的入口函数地址(void (*)())0;
5、将4代入1中,即有(*(void (*)())0)().
其他:
指针函数:
一个函数不仅可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。
返回指针的函数,一般定义格式为:类型标识符 *函数名(参数表)
示例:int *f(x,y);
函数指针是一个指向函数的指针,而指针函数只是说明他是一个返回值为指针的函数。
void* 指针:
C++提供了一种特殊的指针类型void*,它可以保存任何对象类型的地址(C++ PRIMER)。
参考:http://lionwq.spaces.eepw.com.cn/articles/article/item/18258