Chinaunix首页 | 论坛 | 博客
  • 博客访问: 60278
  • 博文数量: 15
  • 博客积分: 353
  • 博客等级: 一等列兵
  • 技术积分: 175
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-12 16:15
文章分类
文章存档

2011年(15)

我的朋友

分类: C/C++

2011-12-12 23:32:24

    目前介绍Clang的中文资料还不多。它是苹果公司推出的一个开源的C/C++/Objective C编译器前端。苹果公司的意图是用Clang+LLVM来替换掉传统的GCC编译工具链。

    Clang对闭包的支持要比Gcc强大。它引入了新的Block的语法,和传统的C语言函数指针并不兼容。Block的语法基本上就是把原来函数指针用*的地方都采用^来替代。比如目录遍历的接口,用Clang Block来定义如下:
  1. typedef void (^pDirentVisitor)(struct dirent * dp);

  2. extern void each(pDirentVisitor visitor, char *dir_name);
实现代码也和上篇中类似:
  1. void each(pDirentVisitor visitor, char *dir_name){
  2.     struct dirent * dp;
  3.     DIR * dirp = opendir(dir_name);
  4.     if(dirp==NULL) return;
  5.     while ((dp = readdir(dirp)) != NULL){
  6.         visitor(dp);
  7.     }
  8.     closedir(dirp);
  9. }
唯一不同点就是Block的调用语法。函数指针的调用方式为(*visitor)(dp),而Block直接visitor(dp)就可以了。
实现ls很简单:
  1. void ls(char *dir_name){
  2.     each(^(struct dirent * dp){
  3.         printf("%s\n",dp->d_name);
  4.     }, dir_name);
  5. }
可以看到Clang的语法更接近函数式编程,比Gcc的nested function更简洁。

用Block实现文件名和文件大小查找也很方便,如下:
  1. void find(char *dir_name, char *find_str, int min_byte){
  2.     each(^(struct dirent * dp){
  3.         if(strncmp(dp->d_name, find_str, strlen(find_str))==0){
  4.             struct stat    statbuf;
  5.             char buf[1024]={0};
  6.             strcat(buf,dir_name);
  7.             strcat(buf,dp->d_name);
  8.             if (stat(buf, &statbuf) !=-1){
  9.                 if(statbuf.st_size>=min_byte) printf("%s, %d\n",dp->d_name, (int)statbuf.st_size);
  10.             }
  11.         }
  12.     }, dir_name);
  13. }

本文的所有可运行代码在github上:
代码编译可以用下面的命令:
clang ls.c dir_each.c -I.

阅读(2172) | 评论(3) | 转发(2) |
给主人留下些什么吧!~~

yuan_xin_yu2011-12-20 20:50:56

桔色花朵: 这是什么实例呢、?.....
以实际的需求出发来讨论闭包的作用。clang的代码需要有对应的编译器,我在最新的苹果Lion下测试通过。

桔色花朵2011-12-15 23:35:27

这是什么实例呢、?

校长的马夹2011-12-15 02:48:35

强大!