技术开发 频道

C语言入门:接口、委托、泛型、单元测试

  测试我们通用排序程序

  我们先测试一个double类型数组,首先我们要定义 一个compar_double的函数来比较两个double类型谁大谁小,是否相等,这相当于.NET里的IComparable的成员方法。

int compar_double(void *a, void *b){  
  
double diff = *(double*)a - *(double*)b;  
  
if(fabs(diff) < 0.00005)  
      return
0;    
else if(diff > 0.0)    
    return
1;  
else        
    return
-1;
}

 

  我们都知道double类型是不能直接比较的,由于精度的问题,要想比较两个double对象是否相等,要把它们的差取绝对值后看是否小于某个特别小的浮点数,如果小于的话,我们就假设它们在这个要求的精度上是相等的。注意fabs要include 。测试代码也很好写,声明一个double数组arr并初始化,调用sort函数,第一个参数传递刚刚定义的compar_double函数,最后一个参数传递sizeof(double)。

void test_sort_double(){  
   printf(
"sort_double\n");  
  
double arr[] = {3.2,2.4,1.3,5.1,4.7};
   sort(compar_double, arr,
5, sizeof(double));    
int i = 0;  
  
for (i = 0; i < 5; i++){    
     printf(
"arr%d=%.2f\n",i, arr[i]);  
  }
}

 

  执行结果符合预期,如下

sort_double
arr0
=1.30
arr1
=2.40
arr2
=3.20
arr3
=4.70
arr4
=5.10

 

  对指针数组的排序

  刚才对一个double的数组进行了排序,在排序的过程中要对数组的元素进行实际的位置交换,交换的话就要涉及内存的拷贝,拷贝一个double对象就要拷贝sizeof(double)个字节,咱这个算法又是一个复杂度很高的函数,O(n*n)吧应该是,所以这样算起来效率更低了,如果对一个很大的结构对象进行拷贝,那影响更大了,所以我们如果对一个大对象数组进行排序的话,可以把一个一个的大对象的指针搞成一个指针数组,对指针数组进行排序,那拷贝就只是一个指针的大小,指针应该很小,32位机器就是始终4个字节。

  比如我们要对一个字符串数组进行排序吧,注意是字符串数组,不是字符数组,每个字符串是一个字符数组,多个字符串构成一个字符串数组,但我们最终的数组的元素只是一个个指向字符串(字符数组)的指针。我们在设计compar_string的时候,就应该知道void *a是一个指向指针的指针,我们先把a转换成一个指向指针的指针(char**)a,然后再对其进行*取值,这样就得到了具体的字符串的指针,也就是一个char*了,然后对char*比较,库函数里有现成的,就是strcmp,我们直接调用它来完成对字符串比较。strcmp需要include <string.h>。

int compar_string(void *a, void *b){  
   return strcmp(
*(char**)a, *(char**)b);
}

 

  相应的测试程序和上面的差不多,只不过要arr的类型是一个指针数组,声明字符串数组很简单,因为字符串本身就是字符数组,字符数组名字本身就是一个指针常量,所以初始化arr就写的比较直观了,不用大括号套着大括号了,如下。

void test_sort_string(){  
  printf(
"sort_string\n");    
  char
*arr[] = {        
  
"lilei",      
  
"hanmeimei",      
  
"jim",        
  
"poly",      
  
"miss gao"    
};  
   sort(compar_string, arr,
5, sizeof(char *));  
  char
**arr_p = arr;  
  
int i = 0;    
  
for (i = 0; i < 5; i++){  
      printf(
"arr%d=%s\n",i, *arr_p++);  
   }
}

 

  值得注意的一点是arr虽然是指针数组,是一个数组名,数组名又代表一个指针,但却是一个指针常量,不能对其进行自增操作,所以我们得声明 一个指向指针的指针char **arr_p来指向arr,然后才能遍历指针数组并打印它的值。测试结果如下

sort_string
arr0
=hanmeimei
arr1
=jim
arr2
=lilei
arr3
=miss gao
arr4
=poly

 

  小节

  用C语言实现泛型(模板)除了用指针外还可以使用宏,但宏理解起来更麻烦,调试也麻烦,还不如耗点儿性能用指针强制转换呢。我是一个C的新手,可能在帖子里有一些幼稚的错误,欢迎大家多多指点,我是写了半天程序了,才知道类库里有一个qsort函数和我想要实现的函数几乎一样,参数的类型个数都一样,真巧了,热。

0
相关文章