i,j = 1真的令人误解吗?[关闭]


11

关于在一个内衬中进行多个变量初始化的普遍争论是:

考虑例如int i,j = 1; 这可能会导致某些人错误地认为两个变量都已初始化

我们可以争辩说,某人应该足够了解他的语言的语法,不要对此有所误解。另一个说法可能是,随着开发人员学习了太多的语言,我们可能会在语言之间的特殊性之间犯错误。

但是对于这种非常特殊的情况,我想知道以下内容是否甚至存在一种语法i,j = 1初始化两个变量的语言?

如果不是,则该参数不适用。


2
如果您的语言是理智的,则潜在的混淆是无害的,因为访问未初始化的变量会触发编译器错误。
CodesInChaos

4
@CodesInChaos您是在说C不是理智的吗?
Baldrickk

2
仅仅因为一种语言允许某件事并不意味着您就不会给人类造成不必要的痛苦。该代码唯一需要的地方是在旨在惩罚那些没有记住语言规范的人的测验中。我总是无法回答这类问题。eh
candied_orange

2
在Visual Basic 6中Dim Apple, Orange, Pear as Fruit是合法声明。假设您不了解VB。您的第一印象Apple是类型Fruit吗?它不是。请记住,不是由该语言专家组成的人们通常会阅读语言。如果您是专家,请明智地使用该语言,甚至向非专家清楚地传达您的意图。我从不使用任何语言进行多次初始化。
埃里克·利珀特

13
同样:考虑var x = 1, y = 1.5; 这是否与相同int x = 1; double y = 1.5;或相同double x = 1, y = 1.5;?当我们添加var到C#3.0中时,我进行了一次调查,发现大约一半的人认为第一个“明显”正确,而另一半认为另一个“明显”正确,因此我们将其定为非法。误导整个人口一半的功能是一个坏功能。
埃里克·利珀特

Answers:


37

我认为不是,但这不是重点。关键是i, j = 0很容易被误认为是i = j = 0,它会同时初始化两者。清晰度是对源代码的最重要要求,其次才是正确性,甚至出现此问题的事实也证明了清晰度不够理想。


3
我还认为,如果这样的语句不能同时初始化两个语句,为什么它甚至存在?
Berin Loritsch

2
@BerinLoritsch取决于语言。由于使用了声明声明,因此经常在JavaScript中完成此操作:许多人认为,最好在变量可用范围的顶部声明变量,即使您直到在代码中使用它们时才对其进行初始化。 。几乎所有代码转换工具都以这种方式输出。
贾里德·史密斯

1
我想如果代码输出工具执行此操作是一回事,因为这应该是值得信任的。但是,对于人类,我建议不要将它的声明和初始化仅在一行上结合使用。看起来就像是一个等待发生的错误。
Berin Loritsch

2
@JaredSmith除了Maple之外,我想不出目前需要哪种语言,即使C现在也更喜欢范围(例如C ++和大多数其他具有一半静态静态编译器的语言),因为它具有停止潜在错误的优点,并且允许只要功能不变,编译器就可以决定如何处理该变量,这可能会带来更好的优化,因为您可以减少寄存器的数量。
WHN

6
无论使用哪种语言,人们都应该问:“ 相对于(甚至更好的是,单独的行)写作有什么好处?” int i, j=1int i; int j = 1
chepner

2

我认为,您可以为任何一方辩护:

  • Kontra i, j = 0
    数学家确实用它来表示ij都为零。

  • Pro i, j = 0
    了解操作员的优先级很简单。而且,如果您对它们的优先顺序感到怀疑,现在是时候进行查询了。

    这就是为什么我们写a.b += c[i]*d[i];没有括号的东西的原因。当然,这等效于(a.b) += ((c[i])*(d[i]));,但是可以期望程序员真正了解最常用的运算符的优先级,并且在不确定时可以查询运算符的优先级。因此,括号通常被认为是无用的,除非它们强制使用与运算符优先级不同的评估顺序。

    当然,也有例外。在这两种情况下,<<和的优先顺序+通常都足以使括号含糊不清。但这是证明规则的例外。

我一方面将更多地放在Pro方面,但我准备遵守任何禁止此类声明的样式指南。这只是不值得斗争的问题。


7
我注意到其中int i, j = 0;没有运算符。该语句中唯一的表达式是,因此运算符优先级不会出现在表达式中。解析器不将其视为逗号或赋值运算符;而是这些是声明语句的语法部分。0,=
埃里克·利珀特

@EricLippert就优先规则而言,这种区别是无关紧要的:我知道的任何C风格语言在声明中都使用与其他表达式相同的优先级。其他任何事情都会带来灾难。
cmaster-恢复莫妮卡

but programmers can be expected to know the precedence of the most used operators by heart, 你说。在您给出的示例中,我不确定大多数(平均)程序员将成员访问运算符或数组索引运算符完全理解为数学意义上的运算符,而是更多地将它们视为自然语言名词和乘法运算符作为动词。这就是为什么int i, j, k = 0;有这样一个怪异的构造,因为它表现为“ int变量i,j和k被声明并应设置为0”的自然语言类似物!
史蒂夫(Steve)

@Steve作为程序员,您如何记住优先级规则完全取决于您。如果它可以帮助您将它们视为语言的名词,请执行此操作。但是,在那种情况下,当您看到诸如之类的东西时,您会遇到问题*a[i],我认为您无法用“名词”类比来充分解析它。至于int i, j, k = 0;,如果您不查找规则,那可能意味着什么:第三种解释是声明int i,评估j然后最终赋值k = 0。除非您知道语言的语法,否则无法解析此类构造。无论如何,这是您的问题。
cmaster-恢复莫妮卡

@cmaster,我没有表达我的具体记忆策略哈哈。我不是C程序员,所以我对C中的运算符优先级很熟悉。但是在查看您的示例时,我注意到的是,我什至没有想到乘法运算符相对于数组索引运算符具有相对优先级。也就是说,我没有读a[i]作应用于的索引运算符a,而是将它们作为不可约的语法元素(指定乘法运算符的操作数)一起阅读,因此甚至没有提示我评估优先级。(1/2)
史蒂夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.