免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2374 | 回复: 9
打印 上一主题 下一主题

问个apue让我纠结的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-05 16:04 |只看该作者 |倒序浏览
本帖最后由 mickgrady 于 2011-03-06 10:42 编辑

typedef函数指针大家都知道吧。
一般是这么定义的 typedef int (*Pt)(int a , int b);     
然后这么赋值
Pt pt =max;    (*pt)(a,b);

我见apue中文99页
这么typedef  
typedef int Myfunc(const char*, const struct stat*, int)  //注意Myfunc前没带*
然后它定义了一个变量
Myfunc myfunc;
调用了 myftw(arv[1], myfunc);
而myftw原型是  int myftw(char 8pahtname, Myfunc *func);   //这里有 *符号。

我觉得调用的时候因该是这样啊 myftw(arv[1], &myfunc);

通过编译运行,发现我改后的 和它之前的用法都可用。 也就是说加不加&符号都对。 这是为什么啊 ,十分疑惑, 求明白人给个解答啊。

论坛徽章:
0
2 [报告]
发表于 2011-03-05 18:21 |只看该作者
函数名本身就是地址/指针

论坛徽章:
0
3 [报告]
发表于 2011-03-05 21:18 |只看该作者
2楼我知道函数名是指针  可是它前后不符啊。
问题是typedef int Myfunc(const char*, const struct stat*, int)  
这样声明的Myfunc 是函数指针类型?
如果是的话为什么更常见的是这样声明
typedef int (*Myfunc)(const char*, const struct stat*, int)  
难道这两种其实是一模一样的, 编译器替我们做了处理? 那哪种是标准的啊 ????

论坛徽章:
0
4 [报告]
发表于 2011-03-06 02:41 |只看该作者
typedef int Myfunc(const char*, const struct stat*, int)  
声明的是一个函数

myftw(arv[1], myfunc);
这里的myfunc是该函数的地址,而不是指向该函数地址的指针

typedef int (*Pt)(int a , int b);     
声明了一个指向函数的指针

Pt pt =max
该指针指向了max地址


感觉有点像 指针和数组名的关系

论坛徽章:
0
5 [报告]
发表于 2011-03-06 11:33 |只看该作者
区别很大

typedef int Myfunc(const char*, const struct stat*, int) ;
定义一个类型Myfunc, 它是个函数类型,有三个参数,返回int

typedef int (*Pt)(int a , int b) 类似,但是它的类型是个函数指针类型,重点是指针类型,而不是函数类型

如果Myfunc是int,那么myfunc就和int myfunc等价,是个定义
但是Myfunc myfunc;就不一样了,等价于
int myfunc(const char*, const struct stat*, int);
它并不是定义,而是个函数_声明_
如果能这么理解,myfunc, &myfunc,那就是typedef没有关系了

Myfunc fun = XX; 就是错的, 好比 int fun(); fun = c;显然就是错的
但是 Pt fun = XX; 就可以, 就像 int (*fun)(); fun = c;就可以

论坛徽章:
0
6 [报告]
发表于 2011-03-06 12:39 |只看该作者
回复 5# flw2


    MyFun mf=XX显然是错的吗?
你自己上机试一试就知道这也是对的  。
这里非常恶心,不是想像中那个样子。
MyFun mf=&XX对,
NyFun mf=XX也对。

论坛徽章:
0
7 [报告]
发表于 2011-03-06 13:02 |只看该作者
回复  flw2


    MyFun mf=XX显然是错的吗?
你自己上机试一试就知道这也是对的  。
这里非常恶心, ...
mickgrady 发表于 2011-03-06 12:39



xcm@u32:/u32/t$ cat test.c
#include <stdio.h>
#include <sys/stat.h>
int main()
{
        typedef int Myfunc(const char*, const struct stat*, int);
        Myfunc myfun = NULL;
}

xcm@u32:/u32/t$ g++ test.c
test.c: In function ‘int main()’:
test.c:6: warning: declaration of ‘int myfun(const char*, const stat*, int)’ has ‘extern’ and is initialized
test.c:6: error: function ‘int myfun(const char*, const stat*, int)’ is initialized like a variable
xcm@u32:/u32/t$ gcc test.c
test.c: In function ‘main’:
test.c:6: error: function ‘myfun’ is initialized like a variable
test.c:6: error: nested function ‘myfun’ declared but never defined
xcm@u32:/u32/t$

论坛徽章:
0
8 [报告]
发表于 2011-03-06 13:15 |只看该作者
本帖最后由 liukunmeister 于 2011-03-06 13:18 编辑

为了简化问题,我想给楼主灌输一个模型。我先总结一下楼主面临的问题,楼主认为在int myftw(char 8pahtname, Myfunc *func) 中这个Myfunc *func应该是由一个Myfunc类型的地址传入的,可是书上的调用却是myftw(arv[1], myfunc);直接传入了一个Myfunc类型的变量而不是Myfunc类型的地址。

我的模型是这样的,函数的指针赋值是下面这个样子

int func(void);
int (*p)(void)=func;

就这么简单,需要注意的是第二行int (*p)(void)是一个指针,它和int *p是一样意思,只是这里长的很像函数是告诉你它是一个指向函数的指针。

接下来我们来看楼主遇到的问题

Myfunc myfunc;
myftw(arv[1], myfunc);

首先第一行Myfunc myfunc

因为Myfunc来自于typedef int Myfunc(const char*, const struct stat*, int)
所以其实Myfunc myfunc的意思就是 int myfunc(const char*, const struct stat*, int)
myfunc就变成了一个和Myfunc类型一样的指向函数的指针

然后第二行myftw(arv[1], myfunc);
到了关键的问题了,到底是myfunc传入还是&myfunc传入

myftw的定义是int myftw(char 8pahtname, Myfunc *func);

那么Myfunc *func 的意思其实就是 int (*func)(const char*, const struct stat*, int)

请楼主看看我的模型,再看看 int (*func)(const char*, const struct stat*, int)后面应该跟什么,是不是应该跟myfunc呢?


我不知道传入&myfunc是否正确,如果也正确的话可能是因为编译器做处理了吧,因为曾经c89的时候关于到底是p()还是(*p)()做过一场争论,最后编译器都支持了。

我认为楼主之所以会困惑主要是因为Myfunc *func这个东西和c语言中平常的指针申明不太一样,要按照指针函数申明的方式来理解。

论坛徽章:
0
9 [报告]
发表于 2011-03-07 09:37 |只看该作者
回复 8# liukunmeister


    确实是编译器做了处理  数组名有两种解释,既是数组类型的命名 又标示数组的地址。函数名也是如此。
我发邮件给apue2的作者 他这样回复我的
In C, an array name and a function name are evaluated as addresses, so
an "&" is not needed, and merely redundant.

For example,

  int a[10];

tells us that a is an array of ten integers.  If a[0] is an integer,
that means "a" is a pointer to an integer.  When we declare

  int *ap;

we can assign it as either

  ap = a;

or

  ap = &a;

They are equivalent.

The same goes for functions in C.  If we declare a function as

  int foo()
  {
  }

and a pointer to a function

  int (*pfunc)();

We can assign pfunc as either

  pfunc = foo;

or

  pfunc = &foo;

Both are equivalent.

Hope this helps.

论坛徽章:
0
10 [报告]
发表于 2011-03-07 09:55 |只看该作者
5楼说的是,理解了点关于typedef。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP