C语言 函数指针调用时加星号与不加星号的分析

来源:互联网 发布:招投标系统源码 编辑:程序博客网 时间:2024/05/02 01:22

0. 通过函数指针调用函数时,函数指针变量前到底加不加星号。首先以例子说明。

#include <stdio.h>typedef void (*TPFun)(void);void syr(void){ printf("hello world!\n");}int main(int argc, char *argv[]){  TPFun pFun; int *Addr; printf("%d\n",syr); pFun = (void(*)(void))(4198760);//这里须保证地址与上面打印出的地址一致 printf("The 1st call...\n"); syr();  printf("The 2nd call...\n");  (*syr)(); printf("The 3rd call...\n");  (**syr)(); printf("The 4th call...\n");  (pFun)(); printf("The 5th call...\n"); (*pFun)(); printf("The 6th call...\n"); (**pFun)(); printf("The 7th call...\n"); ((void(*)(void))(4198760))(); printf("The 8th call...\n"); (*((void(*)(void))(4198760)))(); printf("The 9th call...\n"); (*(*((void(*)(void))(4198760))))(); printf("\n\n\n"); getchar(); return 0;}}

 

可以看到不论加不加星号,加几个星号,都可以正常调用函数,甚至只要知道函数地址,也可以用立即数调用。到底是为什么呢?

1. 首先来弄明白C语言的指针问题。

#include <stdio.h>int main(int argc, char *argv[]){ unsigned int a=1234; unsigned int *pint = &a;  printf("*pint=%d\n",*pint); printf("pint=%d\n",pint); printf("&pint=%d\n",&pint); getchar(); return 0;}


可以得到

变量地址内容a12450641234pint12450601245064

 变量a的地址为1245064,指针变量pint的内容是a的地址,即为1245064。可以由此看出对应关系。

2. 分析:每加一个星号,代表取值,那为什么加几个星号都可以呢?

推算,函数名就是地址,而函数名对应的地址里存放的内容仍然是函数的地址,所以无论取几次星号,结果都一样。但是考虑到函数入口应该是函数主题的内容,实际情况是什么样的?本人对DSP的编程环境比较熟悉,这里以CCS进行了分析,对与c语言相关的汇编代码进行分析。定义了函数void f(void);并定义了void (*Pf)(void);函数指针,下图是定义的函数f的汇编代码。可以看到定义的函数入口地址为0x009597,而函数名称对应的标号对应的地址也为0x009597(核心解释)。所以,对于0x009597地址取值结果还是0x009597,再次取值仍然是0x009597。函数指针Pf的地址为0x000406,Pf的内容是0x009597,即Pf=0x009597,f的地址也为0x009597。所以

f();

(*f)();

Pf();

(*Pf)();

(**Pf)();

的结果是一致的。


0 0
原创粉丝点击