从实例出发了解C语言闭包之三:Clang block

1725阅读 0评论2011-12-15 桔色花朵
分类:

    目前介绍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.

上一篇:python格式化字符串和转义字符
下一篇:linux设备模型之uart驱动架构分析