为什么一些有经验的程序员会在变量之前写出比较值?

时间:2010-07-22 13:03:28

标签: c++ c coding-style

  

可能重复:
  How to check for equals? (0 == i) or (i == 0)
  Why does one often see “null != variable” instead of “variable != null” in C#?

我一直在看一个奇怪的教程以及一些DirectX代码,并注意到许多有经验的C ++程序员以下列方式编写表达式:

(<constant> == <variable>)

而不是我的传统智慧似乎更喜欢:

(<variable> == <constant>)

E.g。 if (NULL == ptr)而不是if (ptr == NULL)。我更喜欢第二种选择,如果没有其他原因选择前者,我的理由是变量似乎是表达式的“接收”端。

但我怀疑前者用于避免使用=而不是==无意中将常量的值赋给变量。这是对的吗?

13 个答案:

答案 0 :(得分:28)

以前就是这种情况,是的。当然,现在几乎所有编译器都警告if()条件下的赋值,所以只有那些经常抑制警告的人才有优势。

答案 1 :(得分:25)

是的,这是正确的。它是检测=而不是==的拼写错误。

答案 2 :(得分:9)

这被称为“Yoda Conditional”!

请参阅此处https://stackoverflow.com/questions/2349378/new-programming-jargon-you-coined

我非常喜欢这个词,因为:

if(Light::On == light)

读作:

  

“如果点亮了”

如前所述,这用于防止错误分配。可以说这种做法是基于现代IDE的陈旧,但我仍然认为这是一种很好的做法。

答案 3 :(得分:6)

因为你不能为一个常量赋值,所以如果错误地你放=而不是==,编译器就会抛出一个错误,提醒你

答案 4 :(得分:5)

这是一个常见的理由,因为你不想用一个冗长的表达式将常量推到屏幕的最右边。后一种说法对我来说从未听起来特别有说服力,前者现在并不是真正有效,因为任何自尊的编译器都会发出警告(你会编译警告 - 错误,不是吗?:-)

编辑:我刚刚看到了新的Xcode 4预览版,只看他们选择的示例来展示他们新的“Fix-it”功能!

alt text http://devimages.apple.com/technologies/tools/images/new_autocorrect20100721.jpg

答案 5 :(得分:4)

了解分配和比较之间的区别。

如果你的意思是:

if (ptr == foo)

但输入

if (ptr = foo)

如果仍然是有效代码,因为ptr = fooptr设置为foo的值后将评估为{{1}}上的布尔检查。显然,你不想要这个。

然而,我发现它大大损害了可读性,并且鉴于大多数IDE和预处理器无论如何都会抓住它,所以永远不要使用这种风格。

答案 6 :(得分:2)

它避免你写var = NULL。写NULL = var会产生错误。所以你说得对: - )

答案 7 :(得分:2)

查看此问题的最高评价答案。

https://stackoverflow.com/questions/2349378/new-programming-jargon-you-coined

他们称这种编码风格为“尤达条件”。

答案 8 :(得分:1)

捕获赋值是使用Yoda条件的主要原因,但还有其他一些:在C ++中,在LHS操作数上调用运算符。由于常数通常为const(duh)或基元,因此限制了非感知操作的可能性。一个示例是原始文字上的=,例如给出的常见原因(1 = a),但这将包括operator=() const,或者用于非POD类型的任何运算符。

答案 9 :(得分:1)

使用VB 6.0之类的语言,它没有明确的赋值和比较运算符,

a = 2

'将编译,无论你是指一个被分配2还是你要比较一个2   如果您的意思是比较,则可能会出现运行时错误。

'如果你总是写

的作业

a = 2

'如果你总是在写作

2 = a

'消除了编译成功和运行时错误的情况。

但是,这只是一个提示:当你有一个像

这样的表达式时,视觉提示是不可用的

a = b'比较或分配?

C#有: - 不同的任务(=)&amp;比较(==)符号 - 比较必须用括号括起来。

然后这就成了一个问题。

答案 10 :(得分:1)

你是对的 - 如果你将“==”输入为“=”,则会触发编译器错误,因为赋值总是返回true。虽然这通常很容易被注意和调试,但偶尔它会变成一个非常难以检测的错误,请想一想:

#define OK 2 // Or something...
[...]
while(status = OK){
    // This loop will never end
    // Even if you change the value of status within it
    [...]
}

这可能是一个令人讨厌的错误,特别是如果属于违规语句的块很长(想象一下寻找状态始终保持正常的所有可能原因)。

如果另一方面你使用了:

while(OK = status){

这会抛出编译器错误,因为您无法为常量赋值。

这种做法有时被称为尤达条件,因为它将对象与主体并置。比如“如果状态正常”vs“如果状态良好”和“天空是蓝色的”vs“蓝色是天空” - 后者是尤达可能会说的。

答案 11 :(得分:0)

因为他们知道他们在做什么:P

答案 12 :(得分:-2)

作为一名java开发人员,我倾向于编写这样的表达式:

   //primitive check
   if(constant == variable)

   //Object check
   if(constant.equals(variable))

这对于对象尤其重要,因为如果变量为null,则表达式不会出错。如果表达式是另一个顺序,则null变量将出错。我保持一致性并对基元执行相同的顺序。