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

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;
}


可以得到

变量地址内容
a12450641234
pint12450601245064

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

的结果是一致的。


  • 31
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值