| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 837 人关注过本帖, 2 人收藏
标题:关于辨析函数类型与函数指针类型,小白求解!!!!!!
只看楼主 加入收藏
朱大哥
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:72
专家分:123
注 册:2015-1-16
收藏
得分:0 
你的操作符  *  &  =   这些都是变量操作符
编译器这么解释的  你问我为什么 搞球球呢
2015-01-26 15:28
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
回复 11楼 朱大哥
态度啊  朱三同学

DO IT YOURSELF !
2015-01-26 15:49
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
以下是引用郑江苇在2015-1-26 15:18:25的发言:

hello:004012F0
&hello:004012F0
*hello:004012F0
hello_ptr=hello;
hello_ptr:004012F0
&hello_ptr:0022FF44
*hello_ptr:004012F0
请按任意键继续. . .



我觉得都可以理解,没啥太反常的东东,其中:&hello_ptr:0022FF44 是变量的地址,其余均是函数的地址

DO IT YOURSELF !
2015-01-26 15:50
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
贴一段楼主的代码的反汇编代码  自己看一下,看不懂没关系,多看几次,,,,,,

程序代码:
00401010 >/$ 55             PUSH EBP
00401011  |. 8BEC           MOV EBP,ESP
00401013  |. 51             PUSH ECX
00401014  |. 56             PUSH ESI
00401015  |. 8B35 A0204000  MOV ESI,DWORD PTR DS:[<&MSVCR100.printf>>;  MSVCR100.printf
0040101B  |. 68 00104000    PUSH w10.hello                           ; /<%p> = w10.hello
00401020  |. 68 F4204000    PUSH OFFSET w10.??_C@_09CICCEGPN@hello?3>; |format = "hello:%p
"
00401025  |. FFD6           CALL ESI                                 ; \printf
00401027  |. 68 00104000    PUSH w10.hello
0040102C  |. 68 00214000    PUSH OFFSET w10.??_C@_0L@MOAGNKPD@?$CGhe>;  ASCII "&hello:%p
"
00401031  |. FFD6           CALL ESI
00401033  |. 68 00104000    PUSH w10.hello
00401038  |. 68 0C214000    PUSH OFFSET w10.??_C@_0L@MEBMEIDE@?$CKhe>;  ASCII "*hello:%p
"
0040103D  |. FFD6           CALL ESI
0040103F  |. 68 18214000    PUSH OFFSET w10.??_C@_0BC@INLNNMJF@hello>;  ASCII "hello_ptr=hello;
"
00401044  |. C745 FC 001040>MOV DWORD PTR SS:[EBP-4],w10.hello
0040104B  |. FFD6           CALL ESI
0040104D  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
00401050  |. 50             PUSH EAX
00401051  |. 68 2C214000    PUSH OFFSET w10.??_C@_0O@FIHDDMNF@hello_>;  ASCII "hello_ptr:%p
"
00401056  |. FFD6           CALL ESI
00401058  |. 8D4D FC        LEA ECX,DWORD PTR SS:[EBP-4]
0040105B  |. 51             PUSH ECX
0040105C  |. 68 3C214000    PUSH OFFSET w10.??_C@_0P@PECEKMJJ@?$CGhe>;  ASCII "&hello_ptr:%p
"
00401061  |. FFD6           CALL ESI
00401063  |. 8B55 FC        MOV EDX,DWORD PTR SS:[EBP-4]
00401066  |. 52             PUSH EDX
00401067  |. 68 4C214000    PUSH OFFSET w10.??_C@_0P@LBNBAFHN@?$CKhe>;  ASCII "*hello_ptr:%p
"
0040106C  |. FFD6           CALL ESI
0040106E  |. 83C4 34        ADD ESP,34
00401071  |. 33C0           XOR EAX,EAX
00401073  |. 5E             POP ESI
00401074  |. 8BE5           MOV ESP,EBP
00401076  |. 5D             POP EBP
00401077  \. C3             RETN



DO IT YOURSELF !
2015-01-26 15:57
郑江苇
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2015-1-25
收藏
得分:0 
回复 10楼 朱大哥
printf("*hello_ptr:%p\n",*hello_ptr);  那这一句呢      函数指针 hello_ptr    加*  结果时函数地址   是不是说 要调用函数  要用 (*hello_ptr)(参数) 然后这里没有参数  所以编译器 就直接又规定成 hello 的首地址值  这么理解吗??
2015-01-26 16:00
郑江苇
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2015-1-25
收藏
得分:0 
回复 14楼 wp231957
恩恩  谢谢哈   
不过汇编真心看不懂额  
第一个hello  返回 函数首地址   属于正常操作
第二个 和 第三个  因为hello是函数名   是一个标号   所以对它 * & 操作 没意义  视编译器而言 给出了地址值

第一个hello_ptr 跟hello一样   
第二个 因为 hello_ptr 是变量  所以 取了它的地址
第三个 还是 没有意义的操作  因为  调用函数  要(*函数指针)(参数)   所以这里 视编译器 给出地址值  
是这么理解吗??
2015-01-26 16:20
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
收藏
得分:10 
反复实验可知道:理论上编译器碰到函数名()时一般会执行call 函数,然后返回函数返回值,对于没有返回值的在printf里不能通过编译,如果函数名不加(),作为语句可以通过编译,但不执行函数,在printf里输出函数首地址,前面加&、*、加n个*,都输出函数地址,加其他运算符则出错,估计是c的规则使然,不能按指针变量或多级指针变量来理解。

能编个毛线衣吗?
2015-01-26 16:36
郑江苇
Rank: 1
等 级:新手上路
帖 子:10
专家分:0
注 册:2015-1-25
收藏
得分:0 
回复 17楼 wmf2014
恩恩  试过了   跟你说的一样啊 啊    谢谢了
2015-01-26 18:46
朱大哥
Rank: 3Rank: 3
等 级:论坛游侠
威 望:2
帖 子:72
专家分:123
注 册:2015-1-16
收藏
得分:0 
操作符的作用对象  这个你要理解清楚
函数名是个标量 不是变量标识符
函数的定义部分是告诉编译器 这里放的是代码 标量的值是这块代码的首地址
你给出的操作符对应的 对象是变量  
作用在标量上,编译器可以认为这是个错误 也可以解释成其他的,只不过C编译器告诉你 啥都不用解释 给你首地址就可以了   


[ 本帖最后由 朱大哥 于 2015-1-26 20:09 编辑 ]
2015-01-26 20:06
快速回复:关于辨析函数类型与函数指针类型,小白求解!!!!!!
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027333 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved