青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

不用臨時變量也可以交換變量的值

當要交換兩個數的值時,通常的做法是定義一個臨時變量,然后再進行交換。那么能不能不用臨時變量而交換兩個數的值呢?可以的!C語言提供的異或運算就可以實現這樣的操作。

異或運算符^也稱XOR運算符,它的規則是若參加運算的兩個二進位同號,則結果為0(假);異號為1(真)。即0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0 

例:

#include <stdio.h>

int main(int argc, char *argv[])
{
   
int a = 2, b = 6;

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

   
printf("a = %d b = %d\n", a, b);

   
return 0;
}

結果如下:

a = 6 b = 2

分析:

前兩個賦值語句:“a = a ^ b“b = b ^ a相當于b = b ^ (a ^ b),而b ^ a ^ b等于a ^ b ^ bb ^ b的結果為0,因為同一個數與相向相^,結果必為0。因此b的值等于a ^ 0,即a,其值為2

再執行第三個賦值語句:“a = a ^ b”。由于a的值等于(a ^ b)b的值等于(b ^ a ^ b),因此,相當于a = a ^ b ^ b ^ a ^ b,即a的值等于a ^ a ^ b ^ b ^ b,等于b

今天又發現另外兩種方法,特補上。 

方法一

void swap(int *p, int *q)
{
   
*p = *p + *q;
   
*q = *p - *q;
   
*p = *p - *q;
}

方法二

void swap(int *p, int *q)
{
   
*p = *p + *q - (*q = *p);
}

原理為算術運算符的結合順序為自左至右。

2007.06.18

 

可以把異或的三條語句壓縮為一條: 

a ^= b ^= a ^= b;

要交換三個變量的值,可以用以下語句:

c = a + c - (a = b, b = c);

2007.09.11

謝謝網友cool8jay指出上面紅色部分的錯誤,下面來分析一下,先看一個示例程序,如下:

#include <stdio.h>

int main(int argc, char *argv[])
{
   
int a = 1;
   
int b = 2;
   
int c = 3;

    c
= a + c - (a = b, b = c);

   
printf("a = %d\n", a);
   
printf("b = %d\n", b);
   
printf("c = %d\n", c);

   
return 0;
}

編譯運行,結果如下:

a = 2 b = 3 c = 2

可見,最初目標中的c = 1部分沒能實現。于是分析原因:

The C Programming Language·Second EditionP205介紹說,“The additive operators + and - group left-to-right”,即附加運算符加號和減號的結合順序是自左向右;P209介紹說,“A pair of expressions separated by a comma is evaluated left-to-right, and the value of the left expression is discarded. The type and value of the result are the type and value of the right operand”,即逗號表達式的計算順序是從左向右,逗號左邊表達式的值被舍棄,表達式結果的類型和數值是逗號右邊表達式的類型和數值。

既然如此,那結果應該是正確的,為什么還會出錯呢?再來看一下VC6.0下編譯產生的匯編代碼:

7: int a = 1;
00401028
mov dword ptr [ebp-4],1
8
: int b = 2;
0040102F
mov dword ptr [ebp-8],2
9
: int c = 3;
00401036
mov dword ptr [ebp-0Ch],3
10
:
11
: c = a + c - (a = b, b = c);
0040103D
mov eax,dword ptr [ebp-8]
00401040
mov dword ptr [ebp-4],eax
00401043
mov ecx,dword ptr [ebp-4]
00401046
add ecx,dword ptr [ebp-0Ch]
00401049
mov edx,dword ptr [ebp-0Ch]
0040104C
mov dword ptr [ebp-8],edx
0040104F
sub ecx,dword ptr [ebp-8]
00401052
mov dword ptr [ebp-0Ch],ecx

可以看到,第11行代碼的執行過程如下:

先把b的值賦給a,再把ac的值相加,結果放在寄存器ecx中,然后把c的值賦給b,最后再把ecxb的值相減,結果賦給c。分解為C語句為:

a = b; /* a = 2, b = 2 */
ecx
= a + c; /* ecx = 5, a = 2, c = 3 */
b
= c; /* b = 3, c = 3 */
c
= ecx - b; /* c = 2, ecx = 5, b = 3 */

這下就清楚了,原來程序運行時先把逗號左邊表達式的值計算出來丟棄掉,然后再做其它的運算,最開始的錯誤也就錯在了這里。

好了,既然上面的式子有問題,那有沒有其它正確的方法能一條語句實現三個變量的值的交換呢?恕本人愚鈍,還沒有想出來。如果誰知道,請給我留言。在此先致謝!

還有一個問題,也是網友cool8jay提出來的,就是交換三個變量的值(每個變量值都要改變)應該有兩種情況,123可以變為231312。我當時想到過,只是覺得可以類比就沒有說明,現在看來可能會誤導讀者,這里說明一下。

不用臨時變量順次交換N個變量的值

 

 

NN>=2)個變量,不使用臨時變量,如何順次交換它們的值?能否只用一條語句實現?如

 

+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+

 

要把它變為

 

+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 2 | 3 | 4 | 5 | 1 |
+---+---+---+---+---+

 

怎樣實現?

 

首先,我們考慮用異或實現兩個變量的交換,可參考我的這篇文章《不用臨時變量交換兩個數的值》。用C++寫函數如下:

 

int &swap(int &a, int &b)
{
    b
= b ^ a;
    a
= a ^ b;
    b
= b ^ a;

   
return b;
}

然后可以把代碼優化為:

int &swap(int &a, int &b)
{
    b ^
= a;
    a ^
= b;
    b ^
= a;

   
return b;
}

繼續優化,把三句壓縮為一句,如下:

int &swap(int &a, int &b)
{
    b ^
= a ^= b ^= a;
   
   
return b;
}

還可再優化,如下:

int &swap(int &a, int &b)
{
   
return (b ^= a ^= b ^= a);
}

現在來順次交換5個變量的值,如下:

swap(a, b);        //返回b

swap(b, c);        //返回c

swap(c, d);        //返回d

swap(d, e);       

既然有返回值,那么可以寫成鏈式的,如下:

swap(a, b);                                 //返回b

swap(swap(a, b), c);                        //返回c

swap(swap(swap(a, b), c), d);               //返回d

swap(swap(swap(swap(a, b), c), d), e);       

現在,讓我們來把swap函數依次用相應的函數體替換掉,如下:

e ^= d ^= e ^= swap(swap(swap(a, b), c), d);

e ^
= d ^= e ^= d ^= c ^= d ^= swap(swap(a, b), c);

e ^
= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= swap(a, b);

e ^
= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;

好了,最后一個語句就實現了順次交換五個變量的值,寫程序驗證如下:

/******************************************************************
* Copyright (c) 2005-2007 CUG-CS
* All rights reserved
*
*
文件名稱:xor.c
*
簡要描述:實現五個變量的順次交換
*
*
當前版本:1.0
*
作 者:raincatss
*
完成日期:2007-10-18
* 開發環境:Windows XP Sp2 + VC6.0
*
個人博客:http://raincatss.cublog.cn/
******************************************************************/


#include <stdio.h>

#define PRINT(A) do {\
   
printf("%d\n", A);\
   
} while (0)

int main()
{
   
int a = 1;
   
int b = 2;
   
int c = 3;
   
int d = 4;
   
int e = 5;

//    b ^= a ^= b ^= a;        // swap(a, b)

//    c ^= b ^= c ^= b;        // swap(b, c)

//    d ^= c ^= d ^= c;        // swap(c, d)

//    e ^= d ^= e ^= d;        // swap(d, e)


    e ^
= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;

    PRINT
(a);
    PRINT
(b);
    PRINT
(c);
    PRINT
(d);
    PRINT
(e);

   
return 0;
}

運行結果如下:

2 3 4 5 1

測試結果正確,達到預定目標。

 

posted on 2008-11-07 23:06 肥仔 閱讀(1914) 評論(1)  編輯 收藏 引用 所屬分類: C++ 基礎

評論

# re: 不用臨時變量也可以交換變量的值  回復  更多評論   

c = a + c - (a = b, b = c);

改成c = a + b- (a = b, b = c);看可不可以
2008-11-18 10:16 | qun454
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区精品视频| 一区二区三区亚洲| 午夜精品婷婷| 一本色道久久综合亚洲精品高清| 欧美黄色日本| 亚洲成人在线网站| 欧美激情一区二区| 亚洲精品国产精品国产自| 亚洲美女黄色片| 亚洲精品一区二区在线| 亚洲一区成人| 久久成人18免费观看| 久久精品一区中文字幕| 欧美国产日韩一二三区| 欧美三级乱人伦电影| 国产亚洲精品bt天堂精选| 伊人成人在线| 99视频在线观看一区三区| 亚洲综合第一| 欧美jizz19性欧美| 亚洲人成亚洲人成在线观看图片 | 亚洲国产视频一区| 亚洲人成网站777色婷婷| 亚洲一区二区精品| 欧美日韩国产成人在线免费| 国产精品久久精品日日| 国产夜色精品一区二区av| 亚洲精品中文字幕有码专区| 午夜精品一区二区三区四区| 亚洲第一毛片| 午夜亚洲福利| 欧美人与禽猛交乱配视频| 国产中文一区| 亚洲欧美日本伦理| 亚洲国产精品va在线看黑人动漫| 亚洲综合成人婷婷小说| 欧美精品一二三| 狠狠爱www人成狠狠爱综合网| 国产精品99久久久久久www| 久久综合五月| 亚洲女与黑人做爰| 欧美日韩伊人| 亚洲欧洲日本在线| 久久久久国产成人精品亚洲午夜| 亚洲精品偷拍| 美玉足脚交一区二区三区图片| 国产美女一区| 亚洲综合三区| 99综合视频| 免费美女久久99| 国产一级一区二区| 亚洲一区二区三区色| 亚洲娇小video精品| 欧美成人免费va影院高清| 在线精品亚洲| 免费亚洲网站| 久久久免费观看视频| 国产一区二区三区在线播放免费观看| 亚洲欧美国产日韩天堂区| 中文精品一区二区三区 | 国产视频在线观看一区| 亚洲欧美精品在线| 99精品99久久久久久宅男| 欧美精品99| 99精品久久久| 国产精品99久久不卡二区| 欧美日韩直播| 午夜国产精品影院在线观看| 一本久道久久综合婷婷鲸鱼| 欧美日韩精品免费观看| 中日韩男男gay无套| 亚洲毛片播放| 国产精品国产一区二区| 亚洲免费在线视频| 午夜精品视频| 亚洲福利免费| 亚洲福利一区| 欧美日韩精品高清| 亚洲欧美成人在线| 午夜精品99久久免费| 一区免费在线| 亚洲精品视频免费在线观看| 欧美色视频一区| 曰韩精品一区二区| 欧美黄色日本| 欧美性大战久久久久久久蜜臀| 亚洲小少妇裸体bbw| 亚洲综合国产| 亚洲激情视频在线观看| 亚洲精品少妇30p| 国产伦精品一区二区三区照片91| 久久久精品一区二区三区| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲美女黄色| 亚洲一区综合| 亚洲欧洲日产国产网站| 亚洲字幕在线观看| 91久久久久久久久| 9人人澡人人爽人人精品| 韩日欧美一区| 在线性视频日韩欧美| 亚洲东热激情| 午夜精品一区二区三区电影天堂 | 国产农村妇女精品一二区| 久热成人在线视频| 欧美日韩中文在线观看| 久久三级视频| 欧美日韩亚洲系列| 久热这里只精品99re8久| 国产精品福利影院| 亚洲国产裸拍裸体视频在线观看乱了| 欧美日韩一区二区三区在线观看免| 久久综合狠狠综合久久综青草| 欧美日韩一区二区三| 美腿丝袜亚洲色图| 国产精品一区久久久| 亚洲精品影院在线观看| 国产一区二区久久精品| 亚洲天堂av电影| 一二三四社区欧美黄| 蜜桃av噜噜一区| 久久久久久电影| 国产乱码精品一区二区三区忘忧草| 亚洲日本成人| 亚洲欧洲一区二区三区久久| 亚洲一区二区在线免费观看| 亚洲手机视频| 欧美日韩亚洲综合一区| 欧美激情亚洲| 日韩视频欧美视频| 欧美精品久久一区| 亚洲日本欧美| 99精品欧美一区二区三区 | 亚洲一区二区免费视频| 亚洲午夜电影网| 欧美日韩中文| 亚洲视频专区在线| 亚洲欧美日韩精品在线| 国产精品久久久久久影院8一贰佰| 日韩亚洲综合在线| 亚洲一级黄色av| 国产精品入口| 欧美在现视频| 欧美成人免费播放| 嫩草伊人久久精品少妇av杨幂| 久久亚洲影音av资源网| 精品福利av| 模特精品裸拍一区| 亚洲黄色影院| 妖精成人www高清在线观看| 欧美另类高清视频在线| 日韩小视频在线观看| 欧美一区二区三区的| 国产日韩欧美高清免费| 久久国产精品毛片| 欧美黄在线观看| 一区二区冒白浆视频| 国产精品人成在线观看免费| 欧美一区三区二区在线观看| 久久青青草综合| 99成人在线| 国产色爱av资源综合区| 久久米奇亚洲| 日韩写真在线| 久久久精品tv| 亚洲久久成人| 国产精品日本| 久久一区二区视频| 一本一本a久久| 久久综合久色欧美综合狠狠| **欧美日韩vr在线| 欧美三级日本三级少妇99| 欧美一区二区视频在线| 亚洲国产日韩美| 午夜精品福利视频| 亚洲黄色免费| 国产日韩欧美在线播放| 欧美激情国产精品| 亚洲一区国产视频| 亚洲破处大片| 久久综合九色| 亚洲性视频h| 亚洲第一偷拍| 国产欧美日韩在线| 欧美片在线播放| 久久精品日韩欧美| 亚洲靠逼com| 蜜桃av噜噜一区二区三区| 午夜精品久久久久久99热| 亚洲黄色片网站| 国产热re99久久6国产精品| 欧美激情精品久久久久久变态| 欧美在线视频二区| 亚洲欧美日韩国产一区二区| 亚洲第一精品福利| 久久手机精品视频| 久久久精品国产免费观看同学 | 免费在线观看日韩欧美| 亚洲一区二区免费看| 日韩视频在线永久播放|