一个交换程序的通用版本

Author:bakari   Date:2012.9.3

      交换程序是每个开始学习编程的人必学习的一个初级算法。算法思想很简单,就是为两个交换的双方在定义一个第三者即可。但越学到后面,你也许会发现这个程序也是蕴藏着很多知识点,并且一些知识点只要用这个作为例子就能非常好的理解,比如说在学习指针和函数时,一定会碰到的传值还是传指的问题。学到C++又会有传引用的问题。这些问题我个人觉得只要用学习这个例子一般都可以理解清楚。

      前不久有学长在跟我讲这方面的知识时又进一步补充了这个交换程序,他要求是只用一个函数就可以实现交换任意类型的数据,即对于任意类型的数据交换都是通用的。也许大部分人和我一样首先想到的是用模板函数。当然用模板函数可以实现,但讨论这个就没有什么意思了。后来经过学长的提示,豁然开朗,用(void *)不就可以了吗?见下面:

 1 /* uElemSize 两者中最大的字节数
 2  * 开辟(char *)的字节空间来作为辅助交换
 3  * 用string函数memcpy()进行内存复制
 4  */
 5 void Swap(void *p1,void *p2,unsigned int uElemSize)
 6 {
 7    assert(NULL != p1 && NULL != p2 && uElemSize > 0);
 8    if(NULL == p1 || NULL == p2 || uElemSize <= 0)
 9         return;
10 
11    char * pBuffer = (char*)malloc(uElemSize);
12 
13    memcpy(pBuffer,p1,uElemSize);
14    memcpy(p1,p2,uElemSize);
15    memcpy(p2,pBuffer,uElemSize);
16 
17    free(pBuffer);
18 }

  assert()断言是防御性编程经常用的技巧,对于小程序没必要这么用,但平时多用也是为了能够养成一个好的编程习惯。对于防御性编程,可以参考我的另一篇文章:https://cloud.tencent.com/developer/article/1017817

程序就是如此神奇,只要我们静下心来,用心去思考,其实很多知识点我们都知道,只是没有深入去理解,所以常常出现一些似曾相识的模糊的状态,那叫一个痛苦啊,所以,学知识就要学会有取舍,然后由浅入深,做出成绩。下面是用结构体为例做的测试:

 1 /*****************************************************
 2  *      Author: bakari
 3  *      Swap程序的通用版本
 4  *****************************************************/
 5 #include<stdio.h>
 6 #include<stdlib.h>
 7 #include<malloc.h>
 8 #include<string.h>
 9 #include<assert.h>
10 
11 void Swap(void *p1,void *p2,unsigned int uElemSize);   //用(void *)来指代任何类型
12 
13 int main()
14 {
15     struct student{
16            char ID;
17            char name[20];
18            int score;
19            }stu1={'a',"huang",89},stu2={'b',"lixiang",98};
20     printf("交换之前:\n");
21     printf("%c %s %d\n",stu1.ID,stu1.name,stu1.score);
22     printf("%c %s %d\n",stu2.ID,stu2.name,stu2.score);
23 
24     printf("\n交换之后:\n");
25     Swap(&stu1,&stu2,sizeof(stu1));
26     printf("%c %s %d\n",stu1.ID,stu1.name,stu1.score);
27     printf("%c %s %d\n",stu2.ID,stu2.name,stu2.score);
28     system("pause");
29     return 0;
30 }
31 /* uElemSize 两者中最大的字节数
32  * 开辟(char *)的字节空间来作为辅助交换
33  * 用string函数memcpy()进行内存复制
34  */
35 void Swap(void *p1,void *p2,unsigned int uElemSize)
36 {
37    assert(NULL != p1 && NULL != p2 && uElemSize > 0);
38    if(NULL == p1 || NULL == p2 || uElemSize <= 0)
39         return;
40 
41    char * pBuffer = (char*)malloc(uElemSize);
42 
43    memcpy(pBuffer,p1,uElemSize);
44    memcpy(p1,p2,uElemSize);
45    memcpy(p2,pBuffer,uElemSize);
46 
47    free(pBuffer);
48 }

既然结构体可以,其他数据类型就都没问题了。截图显示如下:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端技术探索

从头到尾解析Hash 表算法

问题描述 百度面试题: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。 假设目前有一千万个记...

1604
来自专栏面朝大海春暖花开

c++入门笔记

C++函数的返回值类型可以是除数组和函数以外的任何类型。 函数可以返回一个引用,将函数说明为返回一个引用的主要目的是为了将函数用在赋值运算符的左边。函数原型的表...

1284
来自专栏Spark学习技巧

深入理解 hashcode 和 hash 算法

作为一个有抱负的 Java 程序员,在经过长期的CRUD 和 HTML 填空之后必须有所思考,因为好奇心是驱动人类进步的动力之一,我们好奇,比如我们常用的 Ha...

1603
来自专栏一名合格java开发的自我修养

MapReduce中一次reduce方法的调用中key的值不断变化分析及源码解析

摘要:mapreduce中执行reduce(KEYIN key, Iterable<VALUEIN> values, Context context),调用一...

1763
来自专栏绿巨人专栏

学习Scala: 初学者应该了解的知识

2904
来自专栏轮子工厂

卧槽,为什么你的程序执行到一半就退出了,原来是因为加了这个

快到月底了,相信有很多人都和呆博一样,不是“快揭不开锅了”,而是已经快要把锅都吃了〒▽〒。没关系我们可以一起吃掉这篇精神食粮啊,营养又健康,如果觉得味道还不错,...

2972
来自专栏WD学习记录

Python数据结构与算法笔记(4)

当数据项存储在诸如列表的集合中时,我们说它们具有线性或顺序关系。每个数据项都存储在相对与其他数据项的位置。在Python列表中,这些相对位置是单个项的索引值。由...

1251
来自专栏程序员互动联盟

【专业技术】STL hash_map使用(一)

今天在使用STL中的hash_map模板遇到使用PTCHAR作为Key时无法对字符串进行正确比较的问题。 hash_map类在头文件hash_map中,和所有其...

3288
来自专栏落影的专栏

程序员进阶之算法练习(二十)

前言 这四个题属于中等,有的需要一定的代码量,有的需要奇妙的思考。 正文 1. Sonya and Queries 题目链接 ** 题目大意:** 给出一...

3394
来自专栏Bingo的深度学习杂货店

Python实现十大经典排序算法

话不多数,先上两张图: ? ? 名词解释: n:数据规模 k:“桶”的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内...

4.7K10

扫码关注云+社区

领取腾讯云代金券