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

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

#include

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

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)();

的结果是一致的。

Copyright © 2088 02年世界杯中国队_1930年乌拉圭世界杯 - n360l.com All Rights Reserved.
友情链接