久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 21038|回復: 80
收起左側

不用中間數交換兩個變量的方法

  [復制鏈接]
ID:282850 發表于 2019-11-26 10:49 | 顯示全部樓層 |閱讀模式
本帖最后由 f556 于 2019-11-26 10:50 編輯

再次翻看多年前的日志,看到自己記錄的算法,聯想到前些天論壇有人問了一個簡單的問題:“怎么交換兩組數?”
當時有人回答用中間變量,這是一種常用的方法。這個思路好比以下例子:一杯果汁A、一碗牛奶B,現在要互換一下容器,即把A換到碗里,B換到杯里。只有借助第3個容器C。操作是A--->C,B---->A,C----->B,這樣才能完成交換。
有人回答用加減法,思路不錯:
a=3;b=5;
a=a+b;         
b=a-b;
a=a-b;
但當時我提出有溢出問題,如235+122怎么辦,設定a、b均為unsigned char;如果均為unsigned int同樣有問題,不能用程序來限定a、b值的范圍,特別是ADC的值。

我日志記錄的不用中間數交換兩個變量的方法,均利用C語言的異或運算。
異或邏輯:對應的位相比較,同=0,異=1,實際上可以理解就“按位求異”,即“異為真,同為假”
舉例:
xxxx 1001  ^   0000 1111 = xxxx 0110(后4位翻轉)
xxx1 xxxx  ^      1 0000 =xxx0 xxxx   
xxx0 xxxx  ^      1 0000 =xxx1 xxxx  

程序如下:
unsigned int aa=3456,bb=7890;
void main( void )
{
  aa=aa^bb;
  bb=bb^aa;
  aa=aa^bb;
}
運行結果見圖片。

還未運行

還未運行

運行完

運行完

評分

參與人數 4黑幣 +66 收起 理由
6789364 + 6 絕世好帖!
lenvov + 5 很給力!
八月初 + 5 厲害,佩服你的思路
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:645890 發表于 2019-11-28 08:36 | 顯示全部樓層
夭壽,答案確實如此為何腦子還是轉不太過來。
回復

使用道具 舉報

ID:190832 發表于 2019-11-30 12:33 | 顯示全部樓層
這個太厲害了,精彩
回復

使用道具 舉報

ID:654169 發表于 2019-12-2 12:35 | 顯示全部樓層
好厲害,電賽初學者剛好
回復

使用道具 舉報

ID:656472 發表于 2019-12-5 09:22 | 顯示全部樓層
沒看懂。。!
回復

使用道具 舉報

ID:540262 發表于 2019-12-10 09:49 來自手機 | 顯示全部樓層
神仙算法
回復

使用道具 舉報

ID:282850 發表于 2019-12-10 17:07 | 顯示全部樓層
解釋一下,試算:
a=2   ----b 10
b=3   ----b 11             以下用二進制
a=a^b=10^11=01     這個數相當于一個中間值,不是原a,也不是原b
b=b^a=11^01=10  ---->2     使用了中間值01 (a)
a=a^b=01^10=11  ----->3     使用了中間值01 ,也使用了交換好的b

異或象加法一樣,不分先后順序
改程序如下圖,也可
sss.jpg
回復

使用道具 舉報

ID:663421 發表于 2019-12-13 17:59 | 顯示全部樓層
牛逼,學習了
回復

使用道具 舉報

ID:653902 發表于 2019-12-16 08:51 | 顯示全部樓層
這種交換方法有一個前提,就是aa和bb不能相等,如果相等,則會得出錯誤的結果。所以在做異或運算前,需要進行判斷。
回復

使用道具 舉報

ID:282850 發表于 2019-12-17 14:13 | 顯示全部樓層
rotga 發表于 2019-12-16 08:51
這種交換方法有一個前提,就是aa和bb不能相等,如果相等,則會得出錯誤的結果。所以在做異或運算前,需要進 ...

真的嗎?純屬你的主觀意斷!
回復

使用道具 舉報

ID:282850 發表于 2019-12-17 14:18 | 顯示全部樓層
否定樓上的想當然,兩個相同數的交換。見運行圖片
人算:
a=1;  b=1;
a=a^b=0;
b=a^b=0^1=1;
a=a^b=0^1=1;
錯在哪里!
ssss.jpg
回復

使用道具 舉報

ID:351097 發表于 2019-12-20 15:56 | 顯示全部樓層
你這種方法雖然可行,涉及到異或處理,編譯出的匯編代碼會比中間變量法多一些,這樣的話,單片機就需要花更多是時間去處理,可以說效率低。而且這樣寫,代碼的可讀性非常差。
回復

使用道具 舉報

ID:669731 發表于 2019-12-21 12:37 | 顯示全部樓層
多學一種思路,至少以后看的懂 謝謝樓主的講解 樓主說的兩種我看過,這個沒看過
回復

使用道具 舉報

ID:653902 發表于 2019-12-22 22:26 | 顯示全部樓層
如果只是在main中這樣做,結果沒有問題,但是在實際編程中,以調用函數的方式,那么只能用指針傳遞實參,如果兩個數值相等的話,這樣就會出錯。你可以試一試。
回復

使用道具 舉報

ID:653902 發表于 2019-12-22 22:54 | 顯示全部樓層
#include <stdio.h>
void swap(int *a,int *b)
{
        *a^=*b;
        *b^=*a;
        *a^=*b;

}
void main(void)
{
        int test[2] = {21,23};
        swap(&test[0],&test[0]);
        printf("test[0]=%d test[1]=%d",test[0],test[1]);
}
運行結果:test[0]=0 test[1]=23
回復

使用道具 舉報

ID:673561 發表于 2019-12-25 15:29 | 顯示全部樓層
學到了,很有幫助,這個平臺很不錯
回復

使用道具 舉報

ID:282850 發表于 2019-12-27 16:31 | 顯示全部樓層
rotga 發表于 2019-12-22 22:54
#include
void swap(int *a,int *b)
{

你程序有一句明顯錯誤。
回復

使用道具 舉報

ID:664974 發表于 2019-12-27 22:18 來自手機 | 顯示全部樓層
太麻煩了
回復

使用道具 舉報

ID:282850 發表于 2019-12-28 12:36 | 顯示全部樓層
rotga 發表于 2019-12-22 22:54
#include
void swap(int *a,int *b)
{

有一個語句明顯錯了,請改正。
另外,我個人非常厭惡printf,這個純無用的垃圾語句。從你用printf可以看出受了唐大師的毒害,還是重新找本書或者混一下網站、論壇。
回復

使用道具 舉報

ID:653902 發表于 2019-12-31 10:08 | 顯示全部樓層
不是明顯錯了,而是模擬在復雜環境里面,很有可能產生待比較的兩個數的指針指向同一地址,而結果你也看到了,是否和你之前想象的結果一致?你的心態很浮躁,我的水平是不高,但三人行必有我師焉。是否你認為給你指出潛在的錯誤邏輯只能是水平比你高的人才有資格?這個帖子我無意和你扯這些口舌之爭。如果技術上還有需討論的地方,歡迎發表觀點。關于用異或交換數字,是個思路,但第一,對于直接交換,如果操作對象是同一個數,會有錯誤結果。第二,運行效率低,代碼可讀性差。這個早已是定論。

評分

參與人數 1黑幣 +5 收起 理由
zpmpok001 + 5

查看全部評分

回復

使用道具 舉報

ID:676429 發表于 2019-12-31 10:33 | 顯示全部樓層
好厲害,初學者剛好
回復

使用道具 舉報

ID:328200 發表于 2020-1-11 12:11 | 顯示全部樓層
#include <stdio.h>
void swap(int *a,int *b)
{
        *a^=*b;
        *b^=*a;
        *a^=*b;

}
void main(void)
{
        int test[2] = {21,21};
        swap(&test[0],&test[1]);
        printf("test[0]=%d test[1]=%d",test[0],test[1]);
}
運行結果:
test[0]=21 test[1]=21Press any key to continue
回復

使用道具 舉報

ID:392682 發表于 2020-1-17 11:05 | 顯示全部樓層
感謝,漲知識了
回復

使用道具 舉報

ID:348676 發表于 2020-1-20 16:11 | 顯示全部樓層
學習了,很有幫助
回復

使用道具 舉報

ID:348676 發表于 2020-1-20 16:30 | 顯示全部樓層
rotga 發表于 2019-12-16 08:51
這種交換方法有一個前提,就是aa和bb不能相等,如果相等,則會得出錯誤的結果。所以在做異或運算前,需要進 ...

相等就不用交換了
回復

使用道具 舉報

ID:497328 發表于 2020-2-2 20:11 | 顯示全部樓層
這么好的貼子不頂不行
回復

使用道具 舉報

ID:689598 發表于 2020-2-3 01:00 | 顯示全部樓層
不具通用性,只能在特殊場景里使用
回復

使用道具 舉報

ID:692149 發表于 2020-2-15 13:18 | 顯示全部樓層
這個方法好,學習了
回復

使用道具 舉報

ID:575679 發表于 2020-2-15 15:07 | 顯示全部樓層
謝謝大佬 學習了
回復

使用道具 舉報

ID:507431 發表于 2020-2-20 13:32 | 顯示全部樓層
有意思
回復

使用道具 舉報

ID:702102 發表于 2020-3-11 07:45 | 顯示全部樓層
過來學習!
回復

使用道具 舉報

ID:695749 發表于 2020-3-15 19:59 | 顯示全部樓層
先學習這個方法,在實踐中運用,感謝大家的分享!
回復

使用道具 舉報

ID:284107 發表于 2020-3-15 21:19 來自手機 | 顯示全部樓層
兩次對同一個數異或還等于自己
回復

使用道具 舉報

ID:234355 發表于 2020-3-22 13:53 | 顯示全部樓層
int x,y;
x=x+y;
y=x-y;
x=x-y;
回復

使用道具 舉報

ID:265584 發表于 2020-4-12 11:04 | 顯示全部樓層
學習學習,感謝!
回復

使用道具 舉報

ID:311846 發表于 2020-4-21 13:54 | 顯示全部樓層
rotga 發表于 2019-12-16 08:51
這種交換方法有一個前提,就是aa和bb不能相等,如果相等,則會得出錯誤的結果。所以在做異或運算前,需要進 ...

你的基礎不行啊,樓主這么詳細的說明了你都還沒明白么?
回復

使用道具 舉報

ID:311846 發表于 2020-4-21 13:57 | 顯示全部樓層
wanghz12 發表于 2020-3-22 13:53
int x,y;
x=x+y;
y=x-y;

這個的前提是相加不能超出int范圍
回復

使用道具 舉報

ID:716413 發表于 2020-4-22 20:26 | 顯示全部樓層
天才算法!
回復

使用道具 舉報

ID:741805 發表于 2020-4-30 16:52 | 顯示全部樓層
把加法換為減法不就可以了?減法不會溢出,也比異或效率高
回復

使用道具 舉報

ID:741805 發表于 2020-4-30 16:54 | 顯示全部樓層
a=3;b=5;
a=a-b;
b=a+b;
a=b-a;
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久亚洲一区二区 | 天天干天天插 | 中文字幕一区二区三区精彩视频 | 久久精品国产99国产 | 亚洲精品视频在线观看免费 | 麻豆视频在线看 | 国产综合一区二区 | 免费在线观看一区二区 | a级片www | 五月免费视频 | 成年无码av片在线 | 亚洲成人免费观看 | 在线91 | 亚洲一区二区三区免费在线观看 | 国产高清无av久久 | 久久av一区二区三区 | 97avcc| 天堂资源| 国产精品视频一区二区三区 | 亚洲少妇综合网 | 成人精品区 | 国产情品| 蜜臀久久 | 国产综合在线视频 | 久久成人人人人精品欧 | 亚洲欧美日韩国产综合 | 国产精品国色综合久久 | 国产91丝袜在线18 | 精品国产乱码久久久久久图片 | 在线天堂免费中文字幕视频 | 欧美国产精品一区二区 | 婷婷久久网 | 欧美激情精品久久久久久 | 亚洲国产成人精品女人久久久 | 亚洲精品乱码久久久久久按摩观 | 亚洲精品日韩欧美 | 国产成人免费 | 亚洲精品乱码久久久久久久久 | 亚洲欧洲综合av | 一区二区av | 亚洲国产一区在线 |