找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
楼主: f556
收起左侧

不用中间数交换两个变量的方法

  [复制链接]
ID:753146 发表于 2020-5-16 10:48 | 显示全部楼层
楼主有点武断了,用加法交换虽然会溢出但结果依然正确。在指出问题之前最少要动手试一试。
回复

使用道具 举报

ID:753146 发表于 2020-5-16 10:50 | 显示全部楼层
溢出不影响结果,楼主方向错了。
回复

使用道具 举报

ID:47286 发表于 2020-5-20 17:09 | 显示全部楼层
请教两个问题 如下应该是最傻愣的方法吧 第一这样也不限制长度 不管是char还是int 因为过程变量的长度是相同的 第二不需要运算 只是赋值 会比你的方法速度快 是么

uchar a=123;
uchar b=234;

void swap()
{
uchar c;
c=a;
a=b;
b=c;
}
回复

使用道具 举报

ID:467862 发表于 2020-5-25 15:53 | 显示全部楼层
好厉害,电赛初学者刚好
回复

使用道具 举报

ID:762498 发表于 2020-5-27 14:58 | 显示全部楼层
好东西值得去想和学习
回复

使用道具 举报

ID:764107 发表于 2020-5-30 17:26 | 显示全部楼层
楼主的这个帖子很有意义,用到了异或的性质:
只要有: a^b=c
那么对于()^()=()可以随便填入a、b、c 都成立,交换数来説也就很简单了
MOV A,#33H
MOV 30H,#66H
XRL A,30H
XRL 30H,A
XRL A,30H
在一些寄存器不够的地方用刚刚好,学习了
回复

使用道具 举报

ID:807712 发表于 2020-8-29 16:16 | 显示全部楼层
有那么点意思,值得发扬光大!
回复

使用道具 举报

ID:483991 发表于 2020-8-29 16:31 | 显示全部楼层
顶起!值得推广!
回复

使用道具 举报

ID:337139 发表于 2020-9-23 16:47 | 显示全部楼层
你这种方法可行,只是单片机就需要花更多是时间去处理,效率有点低。
回复

使用道具 举报

ID:838081 发表于 2020-11-6 14:28 | 显示全部楼层
你的思路不错
回复

使用道具 举报

ID:8222 发表于 2020-11-28 07:54 | 显示全部楼层
wanghz12 发表于 2020-3-22 13:53
int x,y;
x=x+y;
y=x-y;

x=x+y可能会溢出。
回复

使用道具 举报

ID:879809 发表于 2021-1-23 18:06 | 显示全部楼层
温xyz 发表于 2020-11-28 07:54
x=x+y可能会溢出。

溢出不影响结果的正确性。
回复

使用道具 举报

ID:878235 发表于 2021-1-28 13:56 | 显示全部楼层
Daniel008 发表于 2020-1-20 16:30
相等就不用交换了

所谓的相等,是认为分析,
在程序运行时 A  B  有时相等,有时不相等
例如  A 是用户指定的数据
        B  是函数得出的返回值

那么:我们控制不了的两个数据,他们有可能相等(作者认为相等的会出错),有时候不相等
回复

使用道具 举报

ID:886836 发表于 2021-3-24 17:23 | 显示全部楼层
不同的思维方式,看了很受益
回复

使用道具 举报

ID:855987 发表于 2021-3-27 15:56 | 显示全部楼层
好方法呀!
回复

使用道具 举报

ID:693254 发表于 2021-5-12 14:53 | 显示全部楼层
方法不错~~不过大型的程序会在意这个小算法吗?
回复

使用道具 举报

ID:511754 发表于 2021-5-25 09:28 | 显示全部楼层
讨论热烈拓展思路
回复

使用道具 举报

ID:123289 发表于 2021-6-23 15:42 | 显示全部楼层
1、程序运行时间长;
2、占用存储器多;
3、不实用。
将这段程序编译后,看看所用的代码就知道有多蠢了。
比起:A--->C,B---->A,C----->B 的方案差远了。
回复

使用道具 举报

ID:519089 发表于 2021-7-14 19:16 | 显示全部楼层
时间换空间
回复

使用道具 举报

ID:519089 发表于 2021-7-14 19:17 | 显示全部楼层
PUSH A
MOV A,B
POP B
最简单
回复

使用道具 举报

ID:510342 发表于 2021-7-23 11:28 | 显示全部楼层
rotga 发表于 2019-12-16 08:51
这种交换方法有一个前提,就是aa和bb不能相等,如果相等,则会得出错误的结果。所以在做异或运算前,需要进 ...

1.相等了 就可以不用交换了;
2.可以加个判断,只有不相等的时候才会有下面的交换
回复

使用道具 举报

ID:130230 发表于 2021-8-2 17:05 | 显示全部楼层
rotga 发表于 2019-12-31 10:08
不是明显错了,而是模拟在复杂环境里面,很有可能产生待比较的两个数的指针指向同一地址,而结果你也看到了 ...

你用其它方法指向同一个地址也是会有问题的,这个和楼主的算法无关。
回复

使用道具 举报

ID:584195 发表于 2021-8-3 22:26 | 显示全部楼层
这是什么原理?可以解释一下吗?
回复

使用道具 举报

ID:584195 发表于 2021-8-3 22:29 | 显示全部楼层
rotga 发表于 2019-12-16 08:51
这种交换方法有一个前提,就是aa和bb不能相等,如果相等,则会得出错误的结果。所以在做异或运算前,需要进 ...

你是最牛的人,给你点赞先!
回复

使用道具 举报

ID:958719 发表于 2021-8-3 22:48 | 显示全部楼层
初学者的天堂
回复

使用道具 举报

ID:88256 发表于 2021-8-4 00:57 | 显示全部楼层

我也想这样说的,这个占用的是预留的空间,过后归还,不会额外占用空间
回复

使用道具 举报

ID:513213 发表于 2021-8-7 23:56 | 显示全部楼层
rotga 发表于 2019-12-22 22:54
#include
void swap(int *a,int *b)
{

这句错了swap(&test[0],&test[0]);
应为  swap(&test[0],&test[1]);
回复

使用道具 举报

ID:624769 发表于 2021-9-24 23:20 | 显示全部楼层
specialClass 发表于 2020-5-30 17:26
楼主的这个帖子很有意义,用到了异或的性质:
只要有: a^b=c
那么对于()^()=()可以随便填入a、b、 ...

兄弟,你都用汇编写了……
你直接一个  XCH A,30H 不就换过来了么? 还那么几个 XRL 干嘛啊?
回复

使用道具 举报

ID:624769 发表于 2021-9-24 23:27 | 显示全部楼层
表面上看,不占用中间变量,实际上至少占用了累加器A,根据不同的编译方式还可能占用寄存器B,一样动用了累加器A,你先移动到累加器A,再互相移位远比反复运算要好得多。
回复

使用道具 举报

ID:468878 发表于 2021-11-3 11:37 | 显示全部楼层

你这种算法很好。运行效率与可读性应该是比较强的。
不过我觉得还是设个中间数的最简单明了,不用去规避一些未知的坑。
回复

使用道具 举报

ID:22218 发表于 2022-3-19 05:10 | 显示全部楼层
异或效率该比加减高吧?这个出来40年了吧?我好奇还有折磨多人发帖
回复

使用道具 举报

ID:115923 发表于 2022-3-19 09:28 | 显示全部楼层
#include <stdio.h>

int main(void)
{
   unsigned int a=65530;
   unsigned int b=65535;
   
printf("交换前a,b的值分别为:\n");
    printf("a=%d\n",a);
    printf("b=%d\n",b);
   
a=a+b;   //a=a*b;
   
b=a-b;   //b=a/b;
   
a=a-b;   //a=a/b;
   
printf("交换前a,b的值分别为:\n");
    printf("a=%d\n",a);
    printf("b=%d\n",b);
       
        return 0;
}


已经测试了, 没有问题, 不会溢出问题
回复

使用道具 举报

ID:1017814 发表于 2022-4-16 14:43 | 显示全部楼层
就用一下一个中间变量又能咋滴?

 想起了一个笑话,3个专家和一个农民在说下雨时雨滴的问题,这个故事 就不在这里说了。

原来这个笑话是说我们程序猿的。。。。。。。
回复

使用道具 举报

ID:397054 发表于 2022-6-11 20:02 | 显示全部楼层
zyluglugl 发表于 2021-8-3 22:26
这是什么原理?可以解释一下吗?

有两条:
1是,异或运算既满足交换律也满足结合律;
2是,与自己异或结果是0且0与一个值异或结果就是那个值。
回复

使用道具 举报

ID:397054 发表于 2022-6-11 20:17 | 显示全部楼层
dzbj 发表于 2020-5-20 17:09
请教两个问题 如下应该是最傻愣的方法吧 第一这样也不限制长度 不管是char还是int 因为过程变量的长度是相 ...

异或运算是CPU最拿手的运算之一,与赋值也不相上下,都可以是单周期单字节指令,速度上差不了多少只是程序的可读性差点。赋值的方法要开辟第三个变量并也是要对其操作的,时间上不见得有多少优越性。
回复

使用道具 举报

ID:397054 发表于 2022-6-11 20:40 | 显示全部楼层
guyunfeng 发表于 2020-5-16 10:50
溢出不影响结果,楼主方向错了。

溢出的确不影响结果,但楼主的方向哪里错了?他这个方法的结果不对吗?这两种方法都有可读性问题,但相比之下很显然楼主的更专业,可读性、严格性要好得多,常用C语言尤其是汇编语言的都对溢出、反码补码很在乎,这是习惯。我还是第一次看到这么做,看到加减法时也立即想到了有溢出问题,假如是别人写的程序要我来检查的话,我肯定要多花时间精力甚至询问编程者来肯定它的正确性,而楼主的方法严格明了,不必跟任何人商量,可读性、专业性楼主的要好得多,何来“方向错误”?
回复

使用道具 举报

ID:397054 发表于 2022-6-11 20:49 | 显示全部楼层

你这是汇编语言,你这么做恰恰是舍近求远,微处理器、单片机都有交换指令,一条指令即可,早年的Z80是XCHG,86处理器也是,51的汇编写法好像是XCH,当目标和原都是寄存器时,交换指令是典型的单周期单字节指令。
回复

使用道具 举报

ID:397054 发表于 2022-6-11 21:05 | 显示全部楼层
1823711995 发表于 2020-4-30 16:52
把加法换为减法不就可以了?减法不会溢出,也比异或效率高

换为减法也可以,但也有问题,小减大会得到补码,这个你想过没有?但是,也不影响结果,也行得通,可读性那就比加法还差。。。。“减法比异或效率高”——这个是错的,【异或】运算是CPU最拿手的指令,无出其右,你大概不太熟悉数字电路,加法电路就是异或电路,如果是单纯的异或那就连进位都不需要,完整的加法电路就是带进位的异或电路。
回复

使用道具 举报

ID:397054 发表于 2022-6-11 21:19 | 显示全部楼层
这个方法不会比更流行的赋值方法慢,异或运算是CPU上处理起来最快的指令,不会比赋值慢,更不会比加减法慢,它们都可以是单字节单周期指令,楼主的方法比加减法要好得多,相比之下严格、明了得多,老手都会用楼主的方法而不会去用加减法的虽然它也正确,加减法明显的很笨拙、不专业。
回复

使用道具 举报

ID:397054 发表于 2022-6-11 21:56 | 显示全部楼层
yzwzfyz 发表于 2021-6-23 15:42
1、程序运行时间长;
2、占用存储器多;
3、不实用。

不会的,如果是汇编语言,这个算法只快不会慢,它少用了一个变量怎么会“占用存储器多”呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表