换一种方式,交换两个变量的值
PHP / 2 月前

换一种方式,交换两个变量的值

在日常编程中,我们经常涉及到交换两个变量的值,常见实现如下。 ```go func inplaceSwap(a, b int) (int, int) { c := a a = b b = c return a, b } func main() { println(inplaceSwap(1,2)) } // output 2 1 ``` 利用中间变量,**快速简单**又快速的实现了变量的交换。但今天发现一种高逼格的实现,虽然并没什么用,如下: ```go func inplaceSwap(*a, *b int) (*int, *int) { *b = *a ^ *b *a = *a ^ *b *b = *a ^ *b return a, b } func main() { a := 1 b := 2 inplaceSwap2(&a, &b) fmt.Printf("a=%v, b=%v\n", a, b) // a=2, b=1 } ``` 在此过程中,没有用到任何临时变量,而是由下面这特性完成的。 > 对于任意向量 a,有 a ^ a = 0 我们假设变量 a 的内存地址为 0x80,变量 b 的内存地址为 0x90,则换算成二进制为: ```go a := 0x80 b := 0x90 // a = 1000 0000 // b = 1001 0000 // a ^ b = 0001 0000 ``` 则对于上面的三行运算 ```go // 第一行 *b = *a ^ *b // 1000 0000 ^ 1001 0000 => *b = 0001 0000 // 第二行,这行计算完成后,变量 a 的内存地址已成功换为变量 b 的地址 *a = *a ^ *b // 1000 0000 ^ 0001 0000 => *a = 1001 0000 // 第三行,这行计算完成后,变量 b 的内存地址已成功换为变量 a 的地址 *b = *a ^ *b // 1001 0000 ^ 0001 0000 => *b = 1000 0000 ``` 至此,通过上三行代码,我们成功的将两个变量的内存地址交换,且没有用到零时变量。 这种交换的方式并没有性能上的优势,它仅仅是一个智力游戏。 — 深入理解计算机系统 但是这种有一个严重的弊端,当变量 a 和 b 是同一个变量时,将会导致其值为 0。 ```go a := 0x80 b := 0x80 // a ^ b = 10000000 ^ 10000000 = 00000000 // 这将导致变量 b 的指针地址指向的值为 0 // *b = *a ^ *b => *b = 0 // 而 a 和 b 指向的同一个地址,故 &a = 0, // 后面即使再多操作,也只是在操作 0,本质不会发生变化。 ``` ---
  • package main
    
    import (
    	"fmt"
    )
    
    func main() {
        a := 1
        b := 2
    	
        a,b = b,a
    	
    	
        fmt.Println(a, b) // 2 1
    }
    

    优秀如你,

    2020-08-29 10:32:07 +0000 UTC

Godruoyi