问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

C语言中 Viod类型指针与函数指针问题

发布网友 发布时间:2024-09-26 05:00

我来回答

3个回答

热心网友 时间:2024-10-06 02:19

先回答问题二:

函数指针成为void*之后,指向的函数类型的信息会丢失。

函数指针其实是函数的入口地址。

函数可以看成由3个东西决定:形参列表,返回值类型,以及入口地址。


前两者在函数指针成为void*之后会消失。


那么在考虑问题二,就好一点:


函数的参数在传递的时候是这样的:系统有一个叫做堆栈的数据结构,参数由调用方压入堆栈,由被调用方方弹出堆栈。返回值(!!!)也一样。


我实验了一下:

int get(int a,int b,int c)
{
    return a+b;
}
void caller()
{
    char (*p)(int,int) ;
    void *q;
    q=(void*)&get;
    p=(char(*)(int,int))q;
    printf("%s\n", (*p)( (int)'a' ,1) );
}

结果是异常退出……

但是,

int get(int c,int b,int a)
{
    return a+b;
}
void caller()
{
    int (*p)(int,int) ;
    void *q;
    q=(void*)&get;
    p=(int(*)(int,int))q;
    printf("%x\n", 'b' );
    printf("%x\n", (*p)( (int)'a' ,1) );
}
int main()
{
caller();
return 0;
}

不会产生任何错误,可是结果不正确:

62

22ff59

神奇的是,下面这个代码竟然结果正确!!!!!!!!!!!!!

int get(int a)
{
    return a+1;
}
void caller()
{
    int (*p)(int,int) ;
    void *q;
    q=(void*)&get;
    p=(int(*)(int,int))q;
    printf("%x\n", 'b' );
    printf("%x\n", (*p)( (int)'a' ,1) );
}
int main()
{
caller();
return 0;
}

结果:

62

62

-----------

原因是:堆栈里面不仅有传参操作的数据,还有其他重要数据,稍有不慎就可能破坏了他的结构。由于传参的参数是最后压栈的,所以多传一个少一个都还好,但是返回值可能就处于了一个危险地带。


无论怎样,结果不能总是对……


所以,编程时要注意这一点。

热心网友 时间:2024-10-06 02:19

答案可能因为编译器不同而不同,下面针对常见的编译器回答
问题一:参数不同时编译出错,返回类型不同时编译不出错,运行可能出错

问题二:函数内部不知道它指向的函数类型,报错是编译器报错

指向函数的Void指针,在强制类型转换成另一种参数不同的函数指针后,使用它会造成:参数不匹配的编译错误

热心网友 时间:2024-10-06 02:20

问题一:在使用时强制转换成函数参数不同的函数指针,会导致出错,返回类型指针不同也会出错,对吗?
编译器无法得知你传入的函数指针funp是什么类型,所以编译时不会出错,但是运行时如果无法转换会抛出错误停止运行。
问题二,上面例子中函数内部怎样得知指向的函数类型。

这个是靠约定的,并不能提前得知。所以万能指针是非类型安全的,要避免使用。这种设计也是不太好的。

热心网友 时间:2024-10-06 02:14

先回答问题二:

函数指针成为void*之后,指向的函数类型的信息会丢失。

函数指针其实是函数的入口地址。

函数可以看成由3个东西决定:形参列表,返回值类型,以及入口地址。


前两者在函数指针成为void*之后会消失。


那么在考虑问题二,就好一点:


函数的参数在传递的时候是这样的:系统有一个叫做堆栈的数据结构,参数由调用方压入堆栈,由被调用方方弹出堆栈。返回值(!!!)也一样。


我实验了一下:

int get(int a,int b,int c)
{
    return a+b;
}
void caller()
{
    char (*p)(int,int) ;
    void *q;
    q=(void*)&get;
    p=(char(*)(int,int))q;
    printf("%s\n", (*p)( (int)'a' ,1) );
}

结果是异常退出……

但是,

int get(int c,int b,int a)
{
    return a+b;
}
void caller()
{
    int (*p)(int,int) ;
    void *q;
    q=(void*)&get;
    p=(int(*)(int,int))q;
    printf("%x\n", 'b' );
    printf("%x\n", (*p)( (int)'a' ,1) );
}
int main()
{
caller();
return 0;
}

不会产生任何错误,可是结果不正确:

62

22ff59

神奇的是,下面这个代码竟然结果正确!!!!!!!!!!!!!

int get(int a)
{
    return a+1;
}
void caller()
{
    int (*p)(int,int) ;
    void *q;
    q=(void*)&get;
    p=(int(*)(int,int))q;
    printf("%x\n", 'b' );
    printf("%x\n", (*p)( (int)'a' ,1) );
}
int main()
{
caller();
return 0;
}

结果:

62

62

-----------

原因是:堆栈里面不仅有传参操作的数据,还有其他重要数据,稍有不慎就可能破坏了他的结构。由于传参的参数是最后压栈的,所以多传一个少一个都还好,但是返回值可能就处于了一个危险地带。


无论怎样,结果不能总是对……


所以,编程时要注意这一点。

热心网友 时间:2024-10-06 02:19

答案可能因为编译器不同而不同,下面针对常见的编译器回答
问题一:参数不同时编译出错,返回类型不同时编译不出错,运行可能出错

问题二:函数内部不知道它指向的函数类型,报错是编译器报错

指向函数的Void指针,在强制类型转换成另一种参数不同的函数指针后,使用它会造成:参数不匹配的编译错误

热心网友 时间:2024-10-06 02:22

问题一:在使用时强制转换成函数参数不同的函数指针,会导致出错,返回类型指针不同也会出错,对吗?
编译器无法得知你传入的函数指针funp是什么类型,所以编译时不会出错,但是运行时如果无法转换会抛出错误停止运行。
问题二,上面例子中函数内部怎样得知指向的函数类型。

这个是靠约定的,并不能提前得知。所以万能指针是非类型安全的,要避免使用。这种设计也是不太好的。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
开封跑滴滴需要什么手续 郑州的滴滴打车可以在开封好吗 集团管控有哪几种模式 集团管控五种模式 集团管控模式集团管控模式选择的主要影响因素 win10桌面图标间距变大了怎么调整 win10桌面图标间距变大了调整方法 南宁什么路有民生银行 南宁民生银行保安第一个月工资多少?? 如果电池在综合测试时,电压原本是3.7伏标准,但是一测试那个电压立马 保护板的线结对但是用检测板测试为什么检测灯不亮反插反而亮为什么? 不吃饭光喝水能减肥吗? 怎么删除 mzvkbd.dll文件? 求助应用程序或DLL C:\WINDOWS\system\COMRes.dll为无效的Windows映像... ...0x7b7a6273"内存。该内存不能为“written". 求助? 我中了个病毒!杀毒软件杀不了!求助高手帮忙! 奇怪的蓝屏问题,求助高手. 2022年全国333地级市人均GDP汇总 学舞蹈以后好找工作好就业吗 2023就业方向有哪些 黄晓峰近年来担任主创的电视剧作品有 国产电视剧有哪些 微信发信息怎么没有声音 金庸作品电视剧有哪些 我奶奶头晕腿软还很困,现在70岁。是怎么回事啊?我很害怕,还不敢多问... ...低血糖、气管炎等。老人时常会头晕,出虚汗,四肢无力 怎么办... 智能电视开机后自动播放频道怎么设置? 投屏自动播放下一集的设置方法有哪些? tcl电视怎样设置自动循环播放? 《哥哥的狂爱》txt全集下载 在新南站买的温州到深圳的汽车票,是到深圳哪个区哪个车站的啊? 新温州火车站第二步:买票 马上就要参加C语言等级考试了,在笔试环节大家有什么总结的重点共享下吗... wondows PE病毒是指什么? 奔驰e260多少公里该做什么保养 练气最忌什么水果蔬菜和水果 造梦西游3怎么打流沙河? 6500xt相当于n卡的什么? 6500xt相当于n卡的什么? amd6500xt相当于n卡哪一款显卡? amd6500xt相当于n卡哪一款显卡? 百炼成神在哪看 武汉哪里可以打美白针 武汉打美白针价格一般是多少钱 ...ERP系统,但成本太大,应该用智装天下的,还是装修云管家的? ...机械专业大二学生,以后想搞人工智能。那在跨专业考研时应该怎么选择... 矫正牙齿的坏处 在绵阳开一个台球厅面积160个平方一年房租25000就4张大桌4张小桌 桌子... rx6500xt相当于什么水平的显卡呢? 有线电视能上宽带吗?拜托各位了 3Q 用宽带充QB有什么好处和坏处?拜托各位了 3Q ...怎样…女声唱的。请问这首是什么歌?拜托各位了 3Q ...网费可以办几个月吗?不是一年的。行吗?那个办过?拜托各位了 3Q...