1. 程式人生 > >關於通過異或交換兩個元素的值的一個陷阱

關於通過異或交換兩個元素的值的一個陷阱

#include <stdio.h>
#include <iostream>
using namespace std;

void swap(int *a,int *b){
	*a = *a ^ *b;
	*b = *a ^ *b;//將a的值賦給了b
	*a = *b ^ *a;//將b的值賦給了a
}
int main(int argc, char *argv[])
{
	int a[] = {1,1};
	int b[] = {1,2,3,4,5};
	swap(&a[0],&a[1]);
	//將陣列b中的元素通過異或函式反轉
	for(int i = 0,j = 4;i<=j;i++,j--){
		swap(&b[i],&b[j]);
	}
	//輸出a,b兩個陣列中的值
	cout<<a[0]<<a[1]<<endl;//輸出的結果是11
	cout<<b[0]<<b[1]<<b[2]<<b[3]<<b[4]<<endl;//輸出的結果是54021
	return 0;
}

相信很多人學c的時候都會接觸到一個用異或來交換兩個變數的值的函式,但是如果將這個函式應用到奇數長度的陣列中的陣列元素的反轉中,則會出現一個意外的情況,那就是陣列中間的那個元素會置為0,如果陣列長度是偶數,那麼則不會出現這種情況,如果是兩個相等的變數進行異或交換的話,也同樣不會出現這種情況,我查閱了一些資料,寫下自己的一些理解。

如果像上面的陣列中最中間的那個元素一樣,自己跟自己異或的話,那麼顯然是會置位0的,自己跟自己異或三次,結果顯然是0,但是如果是陣列中的兩個相等的元素進行異或交換的話,那麼則不會出現這種情況,那麼我們可以總結成以下一點:

如果兩個變數是同一個物件的話,那麼用異或進行交換是會被置為0的,如果兩個變數是不同的兩個變數,那麼則不會出現這種情況,因為一個不同的變數在記憶體中的地址並不是相同的,一個變數的值的變換並不會影響另外一個變數的值,而如果是自己跟自己異或,那麼在異或的函式中的第一步就會將自己置位0,顯然結果就是0,這就是異或函式的陷阱!

相關推薦

關於通過交換元素一個陷阱

#include <stdio.h> #include <iostream> using namespace std; void swap(int *a,int *b){ *a = *a ^ *b; *b = *a ^ *b;//將a的值賦給了

交換變數的

通常做法 #include<stdio.h> #include<stdlib.h> int main() {     int a=10, b=20,temp;     temp=a;     a=b;

交換整數的陷阱

前面我們談到了,可用通過異或運算交換兩個數,而不需要任何的中間變數。 如下面: void exchange(int&a,int&b) {     a ^=b;     b ^=a;     a ^=b; } 然而,這裡面卻存在著一個非常隱蔽的陷阱。通常我們

交換

span clas style pre 二進制 簡單 技巧 異或運算 pan 從左神算法視頻裏get到一個小技巧: 通過異或運算來交換兩數 看上去瞬間逼格高了不少 int a=11; int b=12; int temp=a^b; a=temp^a; b=temp^b

java常見邏輯練習題,用三杯水、加法、交換個數

題目:用三杯水、加法、異或交換兩個數 分析:三杯水原理交換直接用第三個變數交換即可,即: 三杯水 int a = 4; int b = 5; int c = a; a = b; b = c; System.out.println(a);

【BUG】交換元素的時候遇到的坑!

交換元素的方式無非有這麼三種: //愚蠢且多空間的中間量法 temp = a; a = b; b = temp; //異或法 a = a^b; b = a^b; a = a^b; //

【c++程式】通過指標來交換個數的

/* *檔名稱:pointer.cpp *作 者:Zhao Tilu *完成日期:2014年10月14日 *問題描述:通過指標來交換兩個數的值 */ #include<iostream> using namespace std; void s

jquery交換元素之間的位置

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD> <TITLE> New Document </TITLE> &

js 交換元素的位置,動畫效果

今天做了個 兩個元素互換位置 的動畫 ,記錄一下 首先 獲得兩個元素得絕對座標定位 然後通過animation 實現移動 其他效果 按自己喜好新增 (function($){ $.extend({ animationExchange:function(srcObj,des

巨集定義開關和debug printf,巨集定義使用交換

1、巨集定義開關和debug printf #define DEBUG_PRINT 1 #ifdef DEBUG_PRINT #define DEBUG(format, ...) printf("FILE: "__FILE__", LINE: %d: "format"\

深思通過運算交換變數

平常程式設計的時候交換兩個數的需求很常見,比如說氣泡排序裡面的位置交換,我們一般都會使用下面這種方法: public void swap(int a, int b){ int temp = a; a = b; b = temp; } 最近右發現一個抖機靈的方法,看著逼格很

Leetcode421. 找出陣列中元素的最大

Leetcode421. Maximum XOR of Two Numbers in an Array 題目 Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai

使用運算交換變數位置的演算法非常低!

看了很多程式設計方面的知識,在慕課網上的一個關於二進位制的視訊中,偶然聽見老師說採用異或運算的方法交換兩個數字的順序可以提高效率,原因是位運算是直接對二進位制位進行運算,而二進位制位更接近底層。 因此,我一直信誓旦旦的給朋友們普及異或運算的高效率,直到被別人反駁之後,我去網上搜了很多相關的文章。

【Python】通過的方法交換a,b的

python中一道經典的面試題: a = 3, b = 5,不使用中間變數交換 a 和 b 的值? 最簡潔的辦法: a, b = b, a 使用異或,python中用^表示異或運算: a = a ^ b b = b ^ a a =

操作符交換整數

異或:相同為0 不同為1 例:一位二進位制異或取值表 取值 取值 結果 0 0 0 0 1 1 1 0 1 1 1 0 那麼我們交換一個兩個整數值就不需要使用中間值了 public static void main(String[] args) { int a = 2; //二進

交換陣列元素的地址可以交換它們的嗎?

#include<stdio.h> void SWAP(int *a,int *b) {int *e; e=a; a=b; b=e; } void main() {int i; int A[

如何通過而不是引用交換類物件?

如何通過值而不是引用交換兩個類物件? StackOverFlow 使用語言:VB.NET 原網頁: 問題描述 我想交換List中有兩個引用型別物件的值,而不是引用。比如,List1(1)在交換前後引用了一個

交換變數更耗時

FROM:陳碩 http://blog.csdn.net/solstice/article/details/5166912  翻轉一個字串,例如把 "12345" 變成 "54321",這是一個最簡單的不過的編碼任務,即便是 C 語言初學者的也能毫不費力地寫出類似如下的程式

p62 練習3.3 通過只調整指標(而不是資料)來交換相鄰的元素,使用:

由於兩種資料結構的結點結構體都較為簡單,這裡就不列出了 a.單鏈表 List creatList1(List T,int n) //建立單鏈表 (頭插法) { int x;Position S; T = new struct Node; T->Next = NULL;

關於交換變數的不用第三變數 的問題

void my_swa22p(int &a, int &b) {     a = a^b;     b = a^b;     a = a^b;} 這個是經典的 不用第三個變數進行交換的方式; 但是這個有個 問題··· int a = 3; my_swa2