`
huadi223
  • 浏览: 21642 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

由swap引发的表达式赋值问题

 
阅读更多

交换两个变量的值, 是很简单的一件事, 只需要有一个临时变量:

int x = 19;
int y = 86;

int temp = x;
x = y;
y = temp;

在long long ago, 当使用寄存器是一件很奢侈的事情的时候, 人们发现有那么一种方法, 可以不使用临时变量:

int x = 19;
int y = 86;

x = x ^ y;
y = x ^ y;
x = x ^ y;

给忘了异或操作的同学复习一下, 省得你们再去Google(当然, 我就是属于忘了现去Google的...): 1 ^ 1 = 0, 0 ^ 0 = 0, 1 ^ 0 = 1, 0 ^ 1 = 1. 不同为1相同为0.

当我们使用某种写作技巧交换2个int的值时:

int x = 19;
int y = 86;

x ^= y ^= x ^= y;

悲剧发生了.

实际上, x = 0, y = 19.

由此, 引发了一个问题, 就是Java中对于x ^= expression这种操作, 是先提取出x的值, 而后计算与expression的异或.

简单来说, Java计算x ^= y ^= x ^= y时:

1.遇到第一个x读出19, 遇到第一个y读出86, 遇到第二个x读出19, 遇到第二个y读出86.

19 ^ 86 ^ (19 ^ 86)

2.计算(第二个x的值)19异或(第二个y的值)86(结果是69)赋给第二个x(注意此时第一个x仍然是19).

19 ^ (86 ^ 69) // 此时, x的值已被更新, 正确的逻辑应当是 69 ^ (86 ^ 69)

3.计算(第一个y的值)86异或(第二个x当前的新值)69(结果是19)赋给第一个y.

19 ^ 19 // 在这里, y的值被正确更新为19, 就是第二个19

4.计算(第一个x的值)19异或(y的新值)19, 得出0并赋给x.

问题就出现在第一次异或之后, 第一个x的值并没有被更新.

分享到:
评论

相关推荐

    C++引用 。.

    - 当我们调用 `swap(a, b)` 时,`a` 和 `b` 的值会被交换。 - 使用引用传递参数可以避免复制大量的数据,从而提高效率。 **2. 常引用** - **定义:** 常引用是在声明时加上 `const` 关键字的引用,它不允许通过...

    c语言面试问题.pdf

    7. 操作符优先级和条件表达式:文档中还涉及了C语言中的操作符优先级问题,以及条件表达式的使用。特别地,文档提到了在if语句中常见的错误,如错误地使用赋值操作符“=”代替相等比较操作符“==”。 8. 常量定义和...

    《C语言程序设计》试题

    【C语言程序设计试题】 ...这些题目涵盖了C语言的基础语法,包括赋值运算、循环控制、输入输出、结构体操作、逻辑表达式求值、函数调用以及字符串处理等多个方面。解决这些问题需要对C语言有深入的理解。

    基于C语言的计算机编程技术探讨.pdf

    这里,作者提醒程序员在使用标准库函数时要注意参数的正确性和可能引发的安全问题。 由于文档内容是通过OCR扫描技术生成的,文档中不可避免地存在一些扫描错误和信息缺失,例如文献引用部分包含了一些不完整的引用...

    c语言程序设计期末试题A(含答案).pdf

    6. **复合赋值运算符**:`x += x -= x + x`涉及复合赋值运算符,首先计算右侧的表达式,然后根据左侧的运算符进行相应的操作。 【程序阅读与结果预测】 1. **函数调用与局部变量**:`f`函数内部的静态变量`c`会在...

    Java程序设计:第6章_方法.ppt

    `这里的`max(10, 100)`就是一个方法调用表达式,返回值被赋值给变量`big`。 2. **方法调用语句**:对于`void`方法,调用通常以语句形式出现,不返回任何值,如`System.out.println("welcome to java");`。 在方法...

    c语言程序设计期末试题A(含答案).doc

    swap(a[0],a[1]);}后,a[0]=2,a[1]=1。 知识点:C 语言函数、函数的参数传递、函数的返回值。 4. k 的值是 16。 知识点:C 语言宏定义、宏扩展、宏的使用。 5. 语句求 a, b 两个数的最大值 max 可以写作:max =...

    Java8 新特性.rar

    Lambda表达式可以作为参数传递给方法,或者被赋值给变量,使得代码更加紧凑且易于理解。 **2. 函数式接口** 函数式接口是具有一个抽象方法的接口,可以用作Lambda表达式的目标类型。Java8提供了一些内置的函数式...

    c语言程序设计教程书后练习题答案.docx

    【C语言程序设计教程书后练习题答案】 C语言是一种基础的编程语言,广泛应用于系统开发、软件工程、嵌入式系统...同时,解决实际问题的能力也能得到提升,例如理解表达式的计算规则、熟悉字符串处理和输入输出操作等。

    C++Primer课后习题解答完整版

    第五章 表达式:涵盖了算术、比较和逻辑表达式,以及赋值和自增自减运算符,还讲解了C++中的类型转换规则。 第六章 语句:包括控制流语句,如条件(if-else)、循环(for, while, do-while)和跳转语句(break, ...

    C语言基础与提高学习教案.pptx

    《C语言基础与提高》的学习教案涵盖了C语言的基础概念和高级技巧。...深入学习和实践,包括指针的算术运算、动态内存分配以及指针在数组、结构体和函数中的应用,将有助于提升编程技能和解决复杂问题的能力。

    数组和指针练习题目(精选)

    ` 则在以下正确的赋值表达式是 `pb=&x`。因为 `&x` 是变量 `x` 的内存地址,所以 `pb` 将存储变量 `x` 的内存地址。 [8.2] 程序的输出结果是 `0`。因为 `NULL` 在C语言中定义为 `0`,所以 `printf("%d\n",NULL);` ...

    -C++参考大全(第四版) (2010 年度畅销榜

    40.2 分析表达式:问题 40.3 分析一个表达式 40.4 parser类 40.5 剖析一个表达式 40.6 一个简单的表达式分析器 40.7 向分析器中添加变量 40.8 递归下降分析器中的语法检查 40.9 构建一个通用的分析器 40.10 需要试验...

    计算机程序设计基础II第2次月考试卷1

    - 题目41223指出,函数的返回值类型是在定义函数时指定的,不是由return语句的表达式类型决定,也不是由主调函数或系统临时决定的。 5. 变量的作用域与存储类别: - 题目41234的程序展示了静态变量(static)在...

    C语言上机试题及答案1[参考].pdf

    在C语言中,形参...最后的表达式 `(a+b)/5.0`的结果类型是`float`,因为`a`和`b`都是整型,但除以浮点数会导致整个表达式提升为浮点类型。因此,表达式的结果会被转换为浮点数,即使`a`和`b`的初始值为整数。

    Effective C++ & More Effective C++

    《Effective C++》和《More Effective C++》是C++编程领域中的两本经典之作,由世界知名C++专家Scott Meyers撰写。这两本书对于深入理解C++语言、提升编程技巧以及掌握最佳实践有着极其重要的指导意义。在这里,我们...

Global site tag (gtag.js) - Google Analytics