c语言swap指令_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

2: #include

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)的结果是相同的,因此得到了正确地结果:

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

实现

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

1: #include

2: #include

3: #include

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: }

结果:

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


版权声明:本文为weixin_35473217原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。