你会写几种swap函数?

条款25:考虑写一个不抛出异常的swap函数 我们可以调用std下的swap函数,这是一个模板函数:既可以: int a = 1; int b = 2; std::swap(a,b); cout 也可以(前提这个类型支持复制构造函数和赋值构造函数): class Test { public: Test(int i):val(i){} int getVal(){return val;} private: int 阅读详情

     swap函数估计是一个各种各样程序都会频繁用到的子程序,可是你知道它究竟有多少种不同的写法吗?下面我就列举我知道的几种swap函数来跟大家分享一下。

(1)经典型---嫁衣法

无论是写程序还是干其他事情,一旦涉及到交换,就总是会遇到第三方。这个第三方可能是公正的监督者,也可能是一个徒为他人做嫁衣的可怜虫。在经典法的交换程序中,我们就需要有一个可怜虫来为我们提供暂时的服务。程序如下:


void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}

我们看到,我必须用一个temp变量作为过渡,让他先拥有然后又再赋值给其他人。可见他也不是徒做嫁衣,而是先索取后奉献的主人公精神。哈哈,扯远了。


(2)经典型改进版---范型法
上面的那个swap函数只能交换int类型变量,如果我想交换double类型,short类型,char类型......呢?上面的程序就必须重新写,可是又不是完全推倒重来,只需要修改相应的类型变量就可以了,如果是用C++来编程,我们还可以用到NB的模板,可是C语言就没有这种特点了。唯一可以用的便是void*指针。void*指针可以视为一种通用指针,任何指针都可以转换为void*指针而不会丢失值。同理,只要我们把原先的指针变量换成void*类型不就行了。可是,你很快发现,这样不行。为什么呢?因为我们没有通用的嫁衣。C语言中的变量不可以为void类型,也就是说没有void temp; 这种古怪的东西。那怎么办呢?我们可以从底层去想两个数交换的本质。不就是相应的内存值交换嘛。我们可以联想到memcpy函数,我们可以模仿着来,写一个函数,通过传入void*指针和变量类型的字节大小,来将这两个变量相应的字节内容发生对换。程序如下:

void swap(void *a,void *b,size_t size)

{

unsigned char *p1=(unsigned char *)a;          //强制类型转换

unsigned char *p2=(unsigned char *)b;
unsigned char temp;                                      //字节型的嫁衣
while(size--)
{
temp=*p1;
*p1=*p2;
*p2=temp;
p1++;
p2++;
}
}

使用的时候可以这样调用:swap( &a,&b,sizeof(int) );

这种字节的分别交换可以通用各种类型的交换,当然,彼此之间应该是同种类型,否则会因为类型大小,字节序等一些问题发生错误。


(3)取巧型---赋值法
这个方法其实一个很取巧的方法,大家先看一下程序,看能不能看出巧在哪里:
void swap(int *a,int *b)
{
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
这种方法有一个好处,那就是不用消耗额外的变量空间,只需要两个变量做一些运算即可。让我们慢慢看:

首先:

我用A代表a+b

 A=a+b,           这时候A的值为两者之和

接着,b=A-b, 也就是b=A-b=a+b-b=a,这时候b得到了a的值
最后,a=A-b, 因为经过上面的运算,b=a,所以a=A-b=a+b-a=b,这时候a得到了b的值。
所以,交换成功了。

(4)诡异型---逻辑运算法
如果没有仔细拿纸算一算的话,这段程序估计会晕倒很多人,让我们来看一下吧:
void swap(int *a,int *b)

{

//  *a^=*b^=*a^=*b;  这种做法达不到效果,不知道为什么

*a=*a^*b;
*b=*b^*a;
*a=*a^*b;

}
怎么样,够诡异的吧。如果我们把它拆开来看的话,其实也没那么可怕:
首先我们必须明确运算顺序,是从右至左:
*a=*a^*b;
*b=*b^*a;
*a=*a^*b;

在解释这段代码的时候,我们先普及一下逻辑运算的基础知识,^ 符号是异或符号,也就是如果两个逻辑变量各不相同,其表达式值为1,反之为0 。则有:

A^A=0

A^1=~A
A^0=A

A^B^C=A^(B^C)=B^(A^C)

首先,A=a^b;

接着,b=b^A=b^a^b=a^0=a,这时候b获得了a的值。

最后,a=A^b=a^b^a=b^0=b,这时候a获得了b的值。


其实这个方法跟(3)的道理差不多,都是取巧,钻了赋值的空子。

我就想到这么多swap函数了,你呢?
Qt常用的模板函数说明 1.函数qSwap()用来交换两个变量的值,例如: QString second( "Einstein" ); QString name( "Albert" ); qSwap( second, name ); 函数qCount()用于统计容器中一个值出现的次数。例如 QValueList<int> l; l.push_back( 1 ); //放入1到l 链表中 l.push_back( 1 ); l.push_back( 1 ); 阅读详情

相关推荐

C++ Swap函数有几种写法?

在说C++模板的方法前,我们先想想C语言里面是怎么做交换的。 举个例子,要将两个int数值交换,是不是想到下面的代码: 如果要求不用临时变量,可考虑异或的方式。 整型数比较容易理解,如果是字符串呢?字符串交换不能直接使用上面类似的方法赋值,想想原因是啥? 当然如果还可以用指针的指针。 上面的方法都是按特定的类型做的处理,有没更通用的写法? 我们来看看C++ 怎么处理交换: 是不是和int...

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1315

swap c语言 数组,交换C ++数组的2个字符(Swap 2 char of a C++ array)

交换C ++数组的2个字符(Swap 2 char of a C++ array)我有内存访问问题。 当i = 0 ,Visual Studio会引用一个异常并引用一行,如下面的代码所示。无法访问0x00AD8B3B和0x00AD8B3B等于scr+np-i如何修复for循环体以解决此问题?int o_strrev(char* scr){int np = strlen(scr) - 1;char ...

weixin_39582569的博客 403

自托管AI邮件助手imap-mcp:安全连接Claude与个人邮箱的完整指南

在AI助手日益普及的今天,如何安全地让AI访问个人邮箱数据成为关键挑战。传统方法如直接暴露IMAP/SMTP凭证存在严重安全隐患,而第三方SaaS服务则涉及隐私泄露风险。Model Context Protocol (MCP) 作为一种新兴的标准化协议,为AI工具安全接入提供了解决方案。其核心价值在于实现数据源与AI助手间的安全、标准化交互,特别适用于处理敏感信息的场景。imap-mcp正是基于MCP协议构建的自托管邮件网关,它通过多层安全机制(包括主密钥加密和OAuth令牌哈希化)保护用户凭证,让用户能在

weixin_28295799的博客 655

swap()交换函数的用法

#include void swap1(int a ,int b)//这样交换实际上是把a和b两个形参的进行了交换,而主函数中的a b实参是没有变化的 {   int tmp;  tmp=a;  a=b;  b=tmp; } void swap2(int *a ,int *b)//这样交换实际上是把a和b两个形参的地址进行了交换,而主函数中的a b实参是没有变化的 {  int

u010575913的专栏 9819

手把手教你用DCT/DCG实现Multi-bit FF物理优化(含SPG流程避坑指南)

本文详细解析了Multi-bit FF(MBFF)在芯片物理实现中的优化方法,重点介绍了DCT/DCG与SPG流程的实战应用。通过物理感知综合、寄存器组识别和增量优化三阶段流程,实现PPA(Power-Performance-Area)的协同提升。文章还提供了Innovus与ICC工具的协同优化策略及典型问题排查指南,帮助工程师高效完成MBFF物理优化。

ik67890123的博客 241

嵌入式设备系统日志记录及调试技巧_嵌入式日志系统(1),如何成为杰出的程序员

这里面我使用的芯片为哈弗体系,全局常量存储编译器默认分配在flash,需要注意如果使用片内flash时,注意存储调试等级的flash块不要与代码区重合,要不然修改调试等级擦除flash块同时PC指针指向当前块的代码区,会导致仪器死机;这个也是之前用的比较多的,以上代码是模仿linux 内核的写法,可以比较好的做到日志信息分层,编译时相加对应的编译开关即可。但有个弊端就是,切换debug等级时,需要重新编译且需更新固件,而嵌入式设备出现异常后更新固件往往复位后,故障有时很难复现,调试起来比较浪费时间。

2401_84240431的博客 1293

使用函数实现两个数的交换

#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> void Swap(int* x, int* y) { int tmp =0; tmp= *x; *x = *y; *y = tmp; } int main() { int num1 = 10, num2 = 20; pri...

weixin_43267837的博客 668

基于KiCad的STM32最小系统设计实战案例(含PCB布线)

手把手带你用KiCad完成STM32最小系统设计,涵盖原理图绘制、封装匹配、规则约束设置及关键信号PCB布线技巧;全程基于开源EDA工具KiCad,强调实操细节与常见坑点规避。

weixin_42452483的博客 356

Qt学习(二)算法(qAbs()、qMax()、qRound()、qSwap())及正则表达式

算法及正则表达式 一、Qt5常用算法 1.double c=qAbs(a):数qAbs()返回double型数值a的绝对值; 2.double max=qMax(b,c):函数qMax()返回两个数值中的最大值; 3.int bn=qRound(b):返回一个与浮点数最接近的整数值(四舍五入); 4.int cn=qSwap(bn,cn):交换两数的值; 代码 #include &lt;QDebu...

li162001的博客 1万+

告别复杂配置:利用原生DDNS实现IPv6直连群晖的极简指南

本文详细介绍了如何利用原生DDNS实现IPv6直连群晖NAS的极简方法,告别复杂配置。从检查IPv6网络环境、路由器防火墙设置到群晖DDNS配置,一步步指导用户完成设置,并分享移动网络下的使用体验和安全防护建议,帮助用户轻松实现远程访问。

weixin_30918633的博客 413

深入掌握英飞凌TriCore中断向量表

摘要:本文探讨了英飞凌Tc277芯片中断机制的原理与实现,重点解析了中断向量表基地址的链接文件定义方式、BIV寄存器的初始化过程以及每个中断条目的32字节空间分配规则。通过分析中断向量号(1-255)的计算方法,阐明了中断条目跳转地址(如STM0中断向量号37对应0x800F04A0)的生成逻辑。文章还揭示了.map文件中14字节跳转指令的组成原理,以及最终通过a14寄存器跳转到实际中断函数(如stm0Sr0ISR)的执行流程,为嵌入式开发人员理解中断处理机制提供了清晰的技术路径。

IT技术猿猴的博客 1712

SWAP函数的几种写法

你会写几种swap函数?        swap函数估计是一个各种各样程序都会频繁用到的子程序,可是你知道它究竟有多少种不同的写法吗?下面我就列举我知道的几种swap函数来跟大家分享一下。 (1)经典型---嫁衣法 无论是写程序还是干其他事情,一旦涉及到交换,就总是会遇到第三方。这个第三方可能是公正的监督者,也可能是一个徒为他人做嫁衣的可怜虫。在经典法的交换程序中,我们就需要有一个可怜虫来

菜鸟的修炼 1万+

【BUG已解决】RuntimeError: CUDA error: no kernel image is available for execution on the device 解决方案

方案适用场景推荐指数精确匹配官方版本绝大多数场景(大众消费卡+主流数据中心卡)⭐⭐⭐⭐⭐安装历史旧版本Pascal/Maxwell等老显卡⭐⭐⭐⭐安装Nightly版本刚发布的最新架构显卡⭐⭐⭐⭐源码编译官方各版本均不支持的特殊硬件⭐⭐Docker官方镜像追求省心、避免版本排查⭐⭐⭐⭐⭐的核心是PyTorch 预编译包不包含你显卡对应的计算能力架构先确认显卡真实计算能力),而不是盲目重装驱动对比 PyTorch 支持的架构列表),定位是否真的不匹配精确匹配官方版本。

博客 1万+

c语言中swap函数_C ++中的swap()函数

c语言中swap函数 介绍 (Introduction) In this tutorial, we are going to learn the swap() function in C++ programming language. Swapping is a simple operation in C++ which basically is the exchange of data or v...

从零开始的教程世界 4万+

SAP-ABAP:BAPI_INSPOPER_RECORDRESULTS 记录检验操作结果更新检验批状态详细解析

SAP-ABAP:BAPI_INSPOPER_RECORDRESULTS 记录检验操作结果更新检验批状态详细解析

baidu_35680696的博客 967

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Swap()函数的详细解析

C\C++语言编程:Swap()函数的详细解析 在c\c++编程上,我们常会用到Swap()函数,实现其两个数据之间的调换。但由于Swap()函数的运用存在诸多限制,很容易造成数据对调失败。下面让我们进入Swap()函数的详细解析,避免我们日常在编程上出现小错误。 错误原因一 代码展示: void Swap(int *p1,int *p2) { int *temp; *temp=*p1; *p1=*p2; *p2=*temp; } 代码分析: 对*temp赋值就是向一个未知的存储单元赋值,而这个

qq_44831918的博客 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

c语言中的Swap函数

在学习C语言时,我们学到指针这里的时候,使用到Swap()函数,下面是关于Swap函数的一些见解。 首先我们通常会用下面的代码来实现Swap函数整型变量的交换: void Swap(int *p1,int *p2) { int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp; } 下面这三种都是不能实现的常见的几种错误: void Swap_err1(int a,int b) { int tmp = a; a = b; b = tmp; } void Swap_e

weixin_51311212的博客 2万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【C++】带你发掘swap函数的秘密

这篇文章主要介绍作者对C++中swap函数的一些新的认识。

m0_48475532的博客 2万+

C++容器的swap()函数的三点说明

写在前面: 1、使用范围for遍历容器的每个元素,需要使用auto& it引用元素的同一块内存空间,不要使用auto it因为范围for的原型就是容器迭代器遍历元素,将迭代器所致的元素值然后拷贝给it,所以it又是栈上的一块内存空间了。建议使用引用类型,若不需要修改则写成const auto &it,需要修改写出auto &it。 2、关于array的swap的两个数组的...

algsup 1万+

Python 中怎么写 swap()交换函数

******Python 不需要交换函数swap(),如果要交换a,b的话,只需要使用如下语句: a,b = b,a 即可(因为:Python以引用方式管理对象,你可以交换引用,但通常不能交换内存中的对象值。当然你也不需要这样做。) 在python中应该这样做: a = 1 b = 2 def swap(t1, t2):     return t2, t1

hyqsong的专栏 3万+

swap函数底层剖析

对于自定义类型(如类或结构体),为其实现高效的swap函数非常重要。​在类中提供成员swap函数​:直接交换内部资源。​在类的同一命名空间内提供非成员swap函数​:让std::swap能通过 ​ADL(参数依赖查找)​找到你这个高效的版本。#include <algorithm> // 标准库 std::swapprivate:int* data_;public:// ... 构造函数、析构函数、拷贝构造函数、拷贝赋值运算符等// 成员 swap 函数// 交换指针// 交换大小。

weixin_55617272的博客 891

实现Swap函数,将两个数交换

一个人至少拥有一个梦想,有一个理由去坚强。心若没有栖息的地方,到哪里都是在流浪——三毛 自信心深受打击的我,只能来写写笔记了。 刚刚对指针做了基础的学习,那么指针的作用在哪里呢,我们就用Swap函数作一下分析。 void Swap(int a, int b)//交换不成功 { int tmp = a; a = b; b = tmp; } int main() { int a = 10; int b = 20; printf("交换前:%d,%d\n",a,b) Swap(a,b) printf("交换后:%

Serendipity_00的博客 1万+

写一个高效的swap函数

一、前提 缺省版本的swap

zhliu1991的专栏 563

C++ swap(交换)函数 指针/引用/C++自带

ea fe

weixin_43281875的博客 2万+

c++语言swap函数,C++中swap函数

本文是我用到swap函数时,对其产生好奇,所以结合网上有关博文写下的。个人水平有限,若有错误的地方,欢迎留言指出。谢谢!一、通用的函数交换模板templatevoid swap(T &a,T &b){T c(a);a=b;b=c;}T为类型,可根据实际需要使用相应的类型二、针对int类型的优化使用异或,整数异或本身为结果0;一个数异或0结果为本身;void swap(int &am...

weixin_39645343的博客 5603

Swap()-- C++ 几种交换函数

Swap()-- C++ 几种交换函数一、简单交换二、传指针交换(C/C++)三、定义宏(C/C++)四、传引用交换(仅C++)五、使用std::swap()函数交换总结: C++几种交换函数写法 一、简单交换 此方法为按值传参。 将a b分别拷贝一份副本传递给Swap(),并未对真实的a b进行操作。 所以这是一种不成功的交换函数。 #include <iostream> us...

爱吃芒果的薯条 的博客 1701
上一篇: C语言堆栈入门——堆和栈的区别( 转自http://www.top-e.org/)
下一篇: Windows编程革命简史(转自http://coolshell.cn/)
GhostComputing
博客等级 码龄16年 6粉丝 12原创
评论 27
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值