免费注册 查看新帖 |

Chinaunix

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

[C] 一个关于APUE的例子的相关问题:函数变量指针相关? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-18 09:09 |只看该作者 |倒序浏览
我在阅读apue的时候,遇到了一个问题,
这个例子是遍历目录的例子,源代码在
http://book.chinaunix.net/specia ... /ch04lev1sec21.html
为了方便阅读,我也贴上面了,如果格式不习惯,或者更多的信息参见前面的网址。
问题是,
1,myfunc是用typedef定义的函数类型的变量,那么,这个变量是否代表一个函数?
2,如果1成立,怎样引用myfunc所代表的函数?
3,在例子里面,把 myfunc作为其他函数的参数了,那么,myfunc本身的参数是从哪里传进来的?
总结如上问题,关键就是,如何获取myyfunc的参数信息?
  1. #include "apue.h"
  2. #include <dirent.h>
  3. #include <limits.h>

  4. /* function type that is called for each filename */
  5. typedef int Myfunc(const char *, const struct stat *, int);

  6. static Myfunc     myfunc;
  7. static int        myftw(char *, Myfunc *);
  8. static int        dopath(Myfunc *);

  9. static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;

  10. int
  11. main(int argc, char *argv[])
  12. {
  13.     int     ret;

  14.     if (argc != 2)
  15.         err_quit("usage: ftw <starting-pathname>");

  16.     ret = myftw(argv[1], myfunc);        /* does it all */

  17.     ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
  18.     if (ntot == 0)
  19.         ntot = 1;       /* avoid divide by 0; print 0 for all counts */
  20.     printf("regular files  = %7ld, %5.2f %%\n", nreg,
  21.       nreg*100.0/ntot);
  22.     printf("directories    = %7ld, %5.2f %%\n", ndir,
  23.       ndir*100.0/ntot);
  24.     printf("block special  = %7ld, %5.2f %%\n", nblk,
  25.       nblk*100.0/ntot);
  26.     printf("char special   = %7ld, %5.2f %%\n", nchr,
  27.       nchr*100.0/ntot);
  28.     printf("FIFOs          = %7ld, %5.2f %%\n", nfifo,
  29.       nfifo*100.0/ntot);
  30.     printf("symbolic links = %7ld, %5.2f %%\n", nslink,
  31.       nslink*100.0/ntot);
  32.     printf("sockets        = %7ld, %5.2f %%\n", nsock,
  33.       nsock*100.0/ntot);

  34.     exit(ret);
  35. }

  36. /*
  37. * Descend through the hierarchy, starting at "pathname".
  38. * The caller's func() is called for every file.
  39. */
  40. #define FTW_F   1       /* file other than directory */
  41. #define FTW_D   2       /* directory */
  42. #define FTW_DNR 3       /* directory that can't be read */
  43. #define FTW_NS  4       /* file that we can't stat */

  44. static char *fullpath;      /* contains full pathname for every file */

  45. static int                  /* we return whatever func() returns */
  46. myftw(char *pathname, Myfunc *func)
  47. {

  48.     int len;
  49.     fullpath = path_alloc(&len);    /* malloc's for PATH_MAX+1 bytes */
  50.                                         /* (Figure 2.15) */
  51.     strncpy(fullpath, pathname, len);       /* protect against */
  52.     fullpath[len-1] = 0;                    /* buffer overrun */

  53.     return(dopath(func));
  54. }
  55. /*
  56. * Descend through the hierarchy, starting at "fullpath".
  57. * If "fullpath" is anything other than a directory, we lstat() it,
  58. * call func(), and return. For a directory, we call ourself
  59. * recursively for each name in the directory.
  60. */
  61. static int                  /* we return whatever func() returns */
  62. dopath(Myfunc* func)
  63. {
  64.     struct stat     statbuf;
  65.     struct dirent   *dirp;
  66.     DIR             *dp;
  67.     int             ret;
  68.     char            *ptr;

  69.     if (lstat(fullpath, &statbuf) < 0) /* stat error */
  70.         return(func(fullpath, &statbuf, FTW_NS));
  71.     if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */
  72.         return(func(fullpath, &statbuf, FTW_F));

  73.      /*
  74.       * It's a directory. First call func() for the directory,
  75.       * then process each filename in the directory.
  76.       */
  77.     if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
  78.         return(ret);

  79.     ptr = fullpath + strlen(fullpath);      /* point to end of fullpath */
  80.     *ptr++ = '/';
  81.     *ptr = 0;

  82.      if ((dp = opendir(fullpath)) == NULL)     /* can't read directory */
  83.          return(func(fullpath, &statbuf, FTW_DNR));

  84.      while ((dirp = readdir(dp)) != NULL) {
  85.          if (strcmp(dirp->d_name, ".") == 0 ||
  86.              strcmp(dirp->d_name, "..") == 0)
  87.                  continue;        /* ignore dot and dot-dot */

  88.          strcpy(ptr, dirp->d_name);   /* append name after slash */

  89.          if ((ret = dopath(func)) != 0)          /* recursive */
  90.               break; /* time to leave */
  91.      }
  92.      ptr[-1] = 0;    /* erase everything from slash onwards */

  93.      if (closedir(dp) < 0)
  94.          err_ret("can't close directory %s", fullpath);

  95.      return(ret);
  96. }

  97. static int
  98. myfunc(const char *pathname, const struct stat *statptr, int type)
  99. {
  100.     switch (type) {
  101.     case FTW_F:
  102.         switch (statptr->st_mode & S_IFMT) {
  103.         case S_IFREG:    nreg++;    break;
  104.         case S_IFBLK:    nblk++;    break;
  105.         case S_IFCHR:    nchr++;    break;
  106.         case S_IFIFO:    nfifo++;   break;
  107.         case S_IFLNK:    nslink++;  break;
  108.         case S_IFSOCK:   nsock++;   break;
  109.         case S_IFDIR:
  110.             err_dump("for S_IFDIR for %s", pathname);
  111.                     /* directories should have type = FTW_D */
  112.         }
  113.         break;

  114.     case FTW_D:
  115.         ndir++;
  116.         break;

  117.     case FTW_DNR:
  118.         err_ret("can't read directory %s", pathname);
  119.         break;

  120.     case FTW_NS:
  121.         err_ret("stat error for %s", pathname);
  122.         break;

  123.     default:
  124.         err_dump("unknown type %d for pathname %s", type, pathname);
  125.     }

  126.     return(0);
  127. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-05-18 09:22 |只看该作者
回复 1# vaqeteart
typedef定义的是变量?
哥 你得好好学学了

论坛徽章:
0
3 [报告]
发表于 2010-05-27 16:11 |只看该作者
1,myfunc是用typedef定义的函数类型的变量,那么,这个变量是否代表一个函数?
myfunc是函数指针。
2,如果1成立,怎样引用myfunc所代表的函数?
myfunc(参数),和普通函数一样。
3,在例子里面,把 myfunc作为其他函数的参数了,那么,myfunc本身的参数是从哪里传进来的?
接收myfunc做为参数的函数调用并赋予其参数,见84行对func的调用,func也是Myfunc类型的函数指针

论坛徽章:
0
4 [报告]
发表于 2010-08-26 11:14 |只看该作者
回复 2# tajial
看清楚些,我说的是“typedef定义的函数类型的变量”,
不过还是谢谢你

论坛徽章:
0
5 [报告]
发表于 2010-08-26 11:38 |只看该作者
都被他说了。我还说什么啊。2分得了。哈哈

论坛徽章:
3
巳蛇
日期:2013-10-03 10:41:48申猴
日期:2014-07-29 16:12:04天蝎座
日期:2014-08-21 09:24:52
6 [报告]
发表于 2010-08-26 11:40 |只看该作者
求Own讲解typedef.

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
7 [报告]
发表于 2010-08-26 12:40 |只看该作者
这就是个缩写而已,当被缩写的函数作为另一个函数的参数时,那个函数的声明或者定义就会“好看”些。

看见识“不好看”的版本,参见信号那一章。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP