求教C语言中关于函数指针的若干问题

飘过的小牛 2012-08-06 11:53:24
#include<iostream>
using namespace std;

int mm(int x, int y){
return x >= y ? x : y;
}

int main()
{
int a, b;
int (*p)(int, int) = mm; //疑问1
//int (*p)(int, int) = &mm; //这两个区别?
cout<<"mm = "<<mm<<endl;
cout<<"p = "<<p<<endl;

cout<<"*mm = "<<*mm<<endl;
cout<<"&mm = "<<&mm<<endl;

cout<<"*p = "<<*p<<endl;
cout<<"&p ="<<&p<<endl;

cout<<mm(3, 12)<<endl;
cout<<(*mm)(2, 223)<<endl;
cout<<(*p)(223, 15)<<endl;
cout<<p(433, 35)<<endl;
return 0;
}

这段程序能够正常运行。问题有以下几个:
1.为什么p=mm和p=&mm都是正确的?
2.mm是函数的入口地址,p也指向函数的入口地址。这两个地址肯定相同。但是*mm,&mm,*p为什么和函数的入口地址都相同,只有&p和上述几个不同。
3.四种方式调用函数为什么都是正确的?这是怎么规定的。
4.函数名和指针的关系
5.数组名和指针的关系

我觉得如果各位如果能把这点理解清楚,函数指针应该就算功夫到家了。我在私底下问了几个同学,都说不清楚。网上的资料也比较匮乏或者含糊其辞,这点困扰自己很久了,希望各位出手相助,帮我一把。谢谢!
...全文
331 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
ies_sweet 2012-08-08
  • 打赏
  • 举报
回复
1,语言标准规定,函数名就是地址,解除引用的操作对于函数名可以忽略,既然是规定,记住就可以了
2,p是一个指针变量,变量就需要一个地址空间来存放,所以对p取地址是有意义的
3,语言规定就是如此,估计有历史原因,不必深究了
4,函数名在编译后就作为函数代码运行的入口地址了,指针的实质也是个地址,但是指针首先是个变量,函数名不是变量,所以说,指针是变量的特性是区别于函数名的关键
5,数组名和指针的关系。数组名也是个地址,但是这个地址不能进行变址运算,而且sizeof()对于两者的运算也是不同的。深究起来,我建议楼主看下 c和指针 c专家编程。我怕说不清楚误导了楼主。
fzamygsd 2012-08-08
  • 打赏
  • 举报
回复
好好学英语,读

标准文档
MSDN
权威的c/cpp网站,
飘过的小牛 2012-08-08
  • 打赏
  • 举报
回复
谢谢楼上的回答,最近我也在看一些网友提供的资料,等问题搞清楚就会结贴。谢谢大家!
fzamygsd 2012-08-07
  • 打赏
  • 举报
回复
人的高级思维还是要多多容忍那些似乎不太合逻辑的。。。。。。
fzamygsd 2012-08-07
  • 打赏
  • 举报
回复
假设pf是函数指针,那么*pf就是函数。。。。。将(*pf)()当做函数调用还是说的通的

函数名可以作为指向函数的指针,那么pf和函数名等效。。。将pf()当做函数调用也说的通。

C/C++容许这两种方式可能正如楼上所说的“激烈的讨论”。。

数组名是数组名,只不过它经常变成指针的样子来诱惑你。。。。。。。
eatsweetpotato 2012-08-07
  • 打赏
  • 举报
回复
1.因为C中,对函数名取址 与 使用函数名本身 是等价的

2. “只有&p和上述几个不同”
因为&p 是指针本身的地址

3.四种方式调用函数为什么都是正确的?这是怎么规定的。
记得,《C语言参考手册》上说“mm(3, 12)”与“(*mm)(2, 223)”这两种形式曾经引起过激烈的讨论,后来就共存了。
插一句话,看了《C语言参考手册》后发现,C的历史遗留内容真不少;同时也见识了些非常BT的用法。


4.函数名和指针的关系
5.数组名和指针的关系
这两个可以等高手来回答,我怕说错。或者LZ也可以看看《C和指针》和《C专家编程》中关于指针的内容。不过个人认为《C专家编程》中指针内容讲的非常好。
Nickning_88 2012-08-07
  • 打赏
  • 举报
回复
好贴留名
回头好好活研究
wanglu343280746 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
typedef int (*fun)(void);

*fun(); **fun() 一致 ************fun()都是等价的


If the type of an expression or subexpression is ``array of T,'' for some type T, then the value of the expression is a poin……
[/Quote]
哥 能不能换个头像 见你好多次了
iamnobody 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

typedef int (*fun)(void);

*fun(); **fun() 一致 ************fun()都是等价的


If the type of an expression or subexpression is ``array of T,'' for some type T, then the value of the expression is a poi……
[/Quote]

妹子,,,你举的例子....................................问题好大呀.
AnYidan 2012-08-07
  • 打赏
  • 举报
回复
typedef int (*fun)(void);

*fun(); **fun() 一致 ************fun()都是等价的


If the type of an expression or subexpression is ``array of T,'' for some type T, then the value of the expression is a pointer to the first object in the array, and the type of the expression is altered to ``pointer to T.'' This conversion does not take place if the expression is in the operand of the unary & operator, or of ++, --, sizeof, or as the left operand of an assignment operator or the . operator. Similarly, an expression of type ``function returning T,'' except when used as the operand of the & operator, is converted to ``pointer to function returning T.''

虽没有指明本质,但指出了用法
飞天御剑流 2012-08-07
  • 打赏
  • 举报
回复
1.为什么p=mm和p=&mm都是正确的?
-------------------------------
可参考:

C/C++左值性精髓(三)左值转换----从函数到指针的转换

2.mm是函数的入口地址,p也指向函数的入口地址。这两个地址肯定相同。但是*mm,&mm,*p为什么和函数的入口地址都相同,只有&p和上述几个不同。
----------------------------------------------------------------
把mm称为函数的入口地址是错误的,mm仅在表达式中隐式转换为函数的首地址,但入口地址不是本质,不能说mm是入口地址,mm的本质是函数名,是mm函数实体的代表,就这么简单。



3.四种方式调用函数为什么都是正确的?这是怎么规定的。
4.函数名和指针的关系
5.数组名和指针的关系
------------------------------------------------
同样可参考上述链接和以下系列文章:

第一章 数组与指针概念剖析
飘过的小牛 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

1.为什么p=mm和p=&mm都是正确的?
-------------------------------
可参考:

C/C++左值性精髓(三)左值转换----从函数到指针的转换

2.mm是函数的入口地址,p也指向函数的入口地址。这两个地址肯定相同。但是*mm,&mm,*p为什么和函数的入口地址都相同,只有&p和上述几个不同。
-------------……
[/Quote]
能说一下您这些观点是在哪里学习到的吗?感觉你很清楚,希望可以给出具体的书。您的博客我正在看,写的质量很高。
飘过的小牛 2012-08-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

1.因为C中,对函数名取址 与 使用函数名本身 是等价的

2. “只有&p和上述几个不同”
因为&p 是指针本身的地址

3.四种方式调用函数为什么都是正确的?这是怎么规定的。
记得,《C语言参考手册》上说“mm(3, 12)”与“(*mm)(2, 223)”这两种形式曾经引起过激烈的讨论,后来就共存了。
插一句话,看了《C语言参考手册》后发现,C……
[/Quote]
这本书上有?好,我去网上搜索一下。希望弄明白。谢谢你了

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧