c语言范式编程之swap

 

引言


C语言是一门古老的语言,没有C++语言的诸如模版、应用、面向对象的高级特性。对于数据的交换,只能使用指针来实现。在C语言中,一般使用如下的方法来实现两个整数的交换:

  1: void swap(int *ap, int *bp)

 

  2: {

 

  3: int tmp = *ap;

 

  4: int *ap = *bp;

 

  5: *bp = tmp;

 

  6: }


然后,使用如下方法来实现数据交换:

  1: int x = 10;

 

  2: int y = 15;

 

  3:

 

  4: swap(&x,&y);

至此,便完成了数据的交换。现假如有多个不同的类型的数据需要实现交换,在C++语言中使用模版简洁的实现了需要的功能。在C语言中,我们没有模版,可能只能为每个不同类型的数据写一个swap函数。但是当我们了解数据在内存中的表示时,我们很容易想到不同类型的数据交换的本质是相同的。

数据交换的本质简单介绍


一个简单的例子:

  • 1: #include <stdio.h>
  2: #include <stdlib.h>

 

  3:

 

  4: void swap(int *ap, int *bp)

 

  5: {

 

  6:     int tmp = *ap;

 

  7:     *ap = *bp;

 

  8:     *bp = tmp;

 

  9: }

 

 10:

 

 11: int main()

 

 12: {

 

 13:    float fa = 10.0;

 

 14:    float fb = 20.0;

 

 15:    printf("fa = %f,fb = %f\n",fa,fb);

 

 16:    swap(&fa,&fb);

 

 17:    printf("after swap,fa = %f, fb = %f",fa,fb);

 

 18:    return 0;

 

 19: }

由于sizeof(int)和sizeof(float)的结果是相同的,因此得到了正确地结果:

swap_result_1

这似乎是投机取巧的,但是当了解数据在内存的表示时,可以发现其实不同类型的数据底层的操作是一样的,都是位模式(所谓的bit pattern)的交换。

实现


void 指针可以指向任意类型的数据(也可以指向void 指针),亦即可用任意数据类型的指针对void指针赋值。值得注意的是,并不能对void指针解引用,因为编译器不知道void指针指向的数据类型,也就没办法为其生成相应的代码(不同类型的数据的大小可能不同,可执行的操作也可能不同)。

  1: #include <stdio.h>

 

  2: #include <stdlib.h>

 

  3: #include <string.h>

 

  4:

 

  5: void swap(void *vp1, void *vp2,int size)

 

  6: {

 

  7:     char buf[size];

 

  8:     memcpy(buf,vp1,size);

 

  9:     memcpy(vp1,vp2,size);

 

 10:      memcpy(vp2,buf,size);

 

 11: }

 

 12:

 

 13: int main()

 

 14: {

 

 15:    float fa = 10.0;

 

 16:    float fb = 20.0;

 

 17:    printf("fa = %f,fb = %f\n",fa,fb);

 

 18:    swap(&fa,&fb,sizeof(float));

 

 19:    printf("after swap,fa = %f, fb = %f",fa,fb);

 

 20:    return 0;

 

 21: }

结果:

swap_result_2

可以看到,实现了范类型数据的交换。这样写乍看很丑,当理解了内存的位模式时,可以发现其实这段代码是十分优雅的。如果用C++的模版来实现,C++会为不同类型的数据生成对应的代码,当我们有很多不同类型的数据需要swap时,代码膨胀会非常的明显。而调用这个函数只生成一份代码,所有不同数据类型的swap都是调用同一份代码。当然,调用这个函数必须十分小心,因为void指针式通用类型的指针,这意味着,当在这个函数传入不同类型的数据时,编译器并不会报错,这个错误只能在运行时才能发现。

转载请注明出处,查看原文:http://wavelee.info/2013/05/02/c-language-programming-paradigm-swap/

posted @ 2013-05-02 22:27  wavelee  阅读(1138)  评论(0编辑  收藏  举报