示例:交换两个号码的简单程序。
int a = 10;
int b = 20;
a = a+b;
b = a-b;
a = a-b;
现在在下面的代码中:
a=a+b-(b=a);
我的意思是这两个代码有什么区别?
加法:如果这两者的加法超过了在 Java 和 C++ 的情况下不同的整数的合法限制怎么办?
这些对我来说都不好看。可读性是关键。如果要交换值,最“明显”的方法是通过临时值:
int a = 10;
int b = 20;
int tmp = a;
a = b;
b = tmp;
我既不知道也不通常关心这是否与涉及算术的“聪明”方法一样有效。在有人证明实际应用程序中的性能差异显着之前,我会以尽可能简单的代码为目标。不仅在这里,而且适用于所有代码。确定您需要它执行多好(以及在哪些维度上),对其进行测试,并在需要时将其更改为更复杂但更高效。
(当然,如果您swap
的平台内有可用的操作,请改用它……更清楚。)
在 C++ 中,代码会产生未定义的行为,因为没有序列点,a+b-(b=a)
并且您正在更改b
并从中读取。
您最好使用std::swap(a,b)
,它针对速度进行了优化,并且比您那里的可读性强得多。
由于您的特定代码已经被评论,我只想添加一个一般方面。编写一个衬里并不重要,因为在指令级别,您无法逃避您的程序集将转换为机器代码的步骤数。大多数编译器已经进行了相应的优化。
也就是说,除非一个班轮实际上使用不同的机制来实现目标,例如在交换两个变量的情况下,如果您不使用第三个变量并且可以避免诸如类型溢出等所有障碍并使用按位运算符例如,您可能已经保存了一个内存位置,从而可以访问它。
在实践中,这几乎没有任何价值,并且正如其他答案中已经提到的那样,对于可读性来说是个麻烦。专业程序需要由人维护,因此它们应该易于理解。
好的代码的一个定义是代码实际上做了它看起来正在做的事情
如果将代码巧妙地编写为一些缩短但复杂的操作,即使您自己也会发现很难修复自己的代码。应始终优先考虑可读性,并且在大多数情况下,真正需要的效率来自改进设计、方法或更好的数据结构/算法,而不是短线。
引用Dijkstra的话:称职的程序员完全清楚自己头骨的有限大小。因此,他以完全谦逊的态度处理他的任务,并避免像瘟疫这样的聪明伎俩。
几点:
在这方面,最具描述性、直观、最快的代码是:
std::swap(a, b);
可读性和即时理解能力是我在编写和阅读代码时个人评价(以及其他几个人可能投票赞成的)。它提高了可维护性。在提供的特定示例中,很难立即理解作者在这几行中试图实现的目标。单行代码:a=a+b-(b=a);
虽然很聪明,但并没有将作者的意图传达给其他人。
在效率方面,编译器的优化无论如何都会实现。
至少在 java 方面,我记得读过 JVM 已针对正常的直接使用进行了优化,所以如果你尝试做这样的事情,你经常会自欺欺人。
此外,它看起来很糟糕。
好的,试试这个。下次遇到奇怪的错误时,首先将尽可能多的代码压缩成单行。
等待几个星期,这样你就忘记了它应该如何工作。
尝试调试它。
当然,这取决于编译器。虽然我无法预见任何惊天动地的差异。深奥的代码是主要的。