我在读c++老师的课堂笔记,他是这样写的:
使用缩进// OK
永远不要依赖运算符优先级-总是使用括号// OK
总是使用{}块-即使是单行//不可以,为什么??
Const对象在比较的左边// OK
对>= 0的变量使用unsigned,这是个不错的技巧
删除后将指针设置为NULL -双重删除保护//不错
第三种方法我不清楚:放一行进去能得到什么
A{…} ?
例如,下面这段奇怪的代码:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0)
{
j++;
}
}
将其替换为:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
使用第一个版本的好处是什么?
我喜欢卢钦公认的答案。事实上,我经过艰苦的学习才知道他是对的,所以我总是使用大括号,即使是单行块。然而,就我个人而言,我在编写过滤器时做了一个例外,就像您在示例中所做的那样。这样的:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0)
{
j++;
}
}
在我看来很混乱。它将'for'循环和'if'语句分离为单独的操作,而实际上你的目的是一个操作:计算所有能被2整除的整数。在更有表现力的语言中,可以这样写:
j = [1..100].filter(_%2 == 0).Count
在缺少闭包的语言中,过滤器不能用单个语句表示,而必须是一个for循环,后面跟着一个if语句。然而,这仍然是程序员心中的一个动作,我相信这应该反映在代码中,如下所示:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
{
j++;
}
纵观答案,没有人明确地说明了我习惯的那种实践,讲述你的代码的故事:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0)
{
j++;
}
}
就变成:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0) j++;
}
将j++放在与if should相同的行上,向其他任何人发出信号:“我只想让这个块永远增加j”。当然,只有在行代码尽可能简单的情况下,这样做才有意义,因为在这里设置断点,正如前面提到的,并不是很有用。
事实上,我刚刚遇到了Twitter Storm API的一部分,它在Java中有这种“类型”代码。以下是执行代码的相关片段,在本幻灯片的第43页:
...
Integer Count = counts.get(word);
if (Count=null) count=0;
count++
...
for循环块中有两个东西,所以我不会内联那个代码。也就是说,从来没有:
int j = 0;
for (int i = 0 ; i < 100 ; ++i) if (i % 2 == 0) j++;
这很糟糕,我甚至不知道它是否有效(如预期的那样);不要这样做。新行和大括号有助于区分独立但相关的代码段,就像散文中的逗号或分号一样。上面的块是一个很长的句子,里面有几个从句和一些其他的语句,从来没有中断或暂停来区分不同的部分。
如果你真的想要向其他人发送一个只有一行的任务,请使用三元操作符或?:form:
for (int i = 0 ; i < 100 ; ++i) (i%2 ? 0 : >0) j++;
但这几乎是代码高尔夫,我认为这不是很好的实践(我不清楚是否应该将j++放在:的一侧)。注意,我以前没有在c++中运行过三元运算符,我不知道这是否有效,但它确实存在。
简而言之:
想象一下您的读者(即维护代码的人)如何解释您的故事(代码)。让他们尽可能清楚地知道。如果您知道新手程序员/学生正在维护这个,甚至可能留下尽可能多的{},这样他们就不会感到困惑。
在“总是使用牙套”的营地呆了10年之后,我最近开始不怎么使用牙套了。
主要是受到Bob叔叔关于如何编写干净代码的争论的启发,我现在相信不使用大括号编写代码更具有可读性。
if(guardClause)
throw new SomeException(..)
Bob大叔认为,在if/for语句中编写多行代码是潜在的可读性问题。
e.g.
if(someCondition)
{
doTechnicalThingX();
doTechnicalThingY();
doTechnicalThingZ();
}
应该被重构为
if(someCondition)
doFunctionalThingA();
对我来说,不把大括号放在那里是有帮助的,因为我得到提醒,我在if块中写了太多代码。
正如其他人所提到的,我相信代码风格是团队决策。
让我们尝试在增加j时也修改i:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
i++;
噢,不!来自Python,这看起来不错,但实际上不是,因为它相当于:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
i++;
当然,这是一个愚蠢的错误,但即使是有经验的程序员也会犯这个错误。
在ta.speot中指出了另一个很好的理由。的回答。
我能想到的第三个是嵌套的if:
if (cond1)
if (cond2)
doSomething();
现在,假设您现在想在未满足cond1时执行somethingelse()(新特性)。所以:
if (cond1)
if (cond2)
doSomething();
else
doSomethingElse();
这显然是错误的,因为else与内部的if相关联。
编辑:既然这引起了一些关注,我将澄清我的观点。我想回答的问题是
使用第一个版本的好处是什么?
我已经描述过了。有一些好处。但是,在我看来,“总是”的规则并不总是适用。所以我并不完全支持
总是使用{}块-即使是单行//不可以,为什么??
我并不是说总是使用{}块。如果这是一个足够简单的条件和行为,那就不要。如果你怀疑有人可能稍后会来修改你的代码来增加功能,那就这么做。
我对这位讲师的能力表示怀疑。考虑到他
点:
OK
Would anyone really write (or want to read) (b*b) - ((4*a)*c)?
Some precedences are obvious (or should be), and the extra parentheses
just add to confusion. (On the other hand, you _should_ use the
parentheses in less obvious cases, even if you know that they're not
needed.)
Sort of. There are two wide spread conventions for formatting
conditionals and loops:
if ( cond ) {
code;
}
and:
if ( cond )
{
code;
}
In the first, I'd agree with him. The opening { is not that visible,
so it's best to assume it's always there. In the second, however, I
(and most of the people I've worked with) have no problem with omitting
the braces for a single statement. (Provided, of course, that the
indentation is systematic and that you use this style consistently.
(And a lot of very good programmers, writing very readable code, omit
the braces even when formatting the first way.)
NO. Things like if ( NULL == ptr ) are ugly enough to hinder
readability. Write the comparisons intuitively. (Which in many cases
results in the constant on the right.) His 4 is bad advice; anything
which makes the code unnatural makes it less readable.
NO. Anything but int is reserved for special cases. To
experienced C and C++ programmers, the use of unsigned signals bit
operators. C++ doesn't have a real cardinal type (or any other
effective subrange type); unsigned doesn't work for numeric values,
because of the promotion rules. Numerical values on which no
arithmetic operations would make sense, like serial numbers, could
presumably be unsigned. I'd argue against it, however, because it
sends the wrong message: bitwise operations don't make sense either.
The basic rule is that integral types are int, _unless_ there is a
significant reason for using another type.
NO. Doing this systematically is misleading, and doesn't actually
protect against anything. In strict OO code, delete this; is often
the most frequent case (and you can't set this to NULL), and
otherwise, most delete are in destructors, so you can't access the
pointer later anyway. And setting it to NULL doesn't do anything
about any other pointers floating around. Setting the pointer
systematically to NULL gives a false sense of security, and doesn't
really buy you anything.
查看任何典型参考文献中的代码。Stroustrup违反
除了第一条,你给出的每一条规则。
我建议你换个讲师。一个真正知道什么的人
他说的是。