有关函数指针的小题目

分析一下下面一小段代码的输出。

#include <stdio.h>
#include <stdlib.h>

void main(int j)
{
        printf("%d\n", j);
        ((void(*)(int))((int)&main + ((int)&exit - (int)&main) * (j / 1000)))(j + 1);
}

主要是printf后的一段程序不太易读,我们不妨将它拆开来看,首先void(*)(int)是一个函数指针的强制类型转换,可以用#define代替。而&main是main函数的入口地址,&exit是exit的入口地址,前面加上(int)将其强制转换成int类型,故而这一句的前面部分是一个函数调用,而后面的(j + 1)则是一个传入的函数实参。改写后的程序如下所示。

#include <stdio.h>
#include <stdlib.h>
#define FUNC void(*)(int)

void main(int j)
{
	int m = (int)&main;
	int e = (int)&exit;
	printf("%d\n", j);
	((FUNC)(m + (e - m) * (j / 1000)))(j + 1);
}
改写说明:&main可以在int m = (int)&main;的声明后用m代替,&exit可以在int e = (int)&exit;的声明后用e代替,这两个一个是入口地址,一个是出口地址。而(FUNC)是将
(m + (e - m) * (j / 1000))
部分强制转换为函数指针指向的函数类型,后面的j + 1为参数。若这一部分取值为&main,则又返回main执行,且参数为j + 1;若取值为&exit,则退出。


注意到一般的main函数中可接受3个参数,为int argc, char *argv[], char *env[]这3个参数。而直接编译运行此段程序时没有任何其它命令输入,对应的argc即为j在此处值为1,则此处最开始j/1000为0,上面的(m + (e - m) * (j / 1000))的值即为m,则为&main,故而又返回main执行,且参数为j + 1,即2。如此依次递增,到j为1000时,该部分的值为e,即为&exit,则退出程序。整段程序的输出即为递增地依次输出1到1000,然后退出。

注意若非直接编译运行,而选择在命令行中运行,假设该程序生成test.exe,在cmd中输入[test.exe所在路径]\test.exe [任意参数] [任意参数],则j的初始值为3,再加多一个[任意参数]则j初始为4,这跟main函数的接受参数相关。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值