我在读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++;
使用第一个版本的好处是什么?
为了补充之前回答中非常明智的建议,我在重构一些代码时遇到的一个例子是:我正在修改一个非常大的代码库,从一个API切换到另一个API。第一个API调用设置Company Id,如下:
setCompIds( const std::string& compId, const std::string& compSubId );
而替换需要两次调用:
setCompId( const std::string& compId );
setCompSubId( const std::string& compSubId );
我开始使用正则表达式来改变这种情况,这非常成功。我们还通过样式传递代码,这确实使它更易于阅读。然后,在审查过程中,我发现在某些条件下,它正在改变:
if ( condition )
setCompIds( compId, compSubId );
:
if ( condition )
setCompId( compId );
setCompSubId( compSubId );
这显然不是我们所需要的。我不得不回到一开始,再次将替换处理为完全在一个块内,然后手动修改任何最终看起来愚蠢的东西(至少它不会是不正确的)。
我注意到style现在有了一个选项——add-括号,它允许你在没有括号的地方添加括号,如果你发现自己处于和我一样的位置,我强烈建议你这样做。
除了一些明显的情况外,我在任何地方都使用{}。单行是其中一种情况:
if(condition) return; // OK
if(condition) //
return; // and this is not a one-liner
当你在返回之前添加一些方法时,它可能会伤害你。缩进表示当条件满足时执行return,但它总是返回。
c#中using语句的其他例子
using (D d = new D()) // OK
using (C c = new C(d))
{
c.UseLimitedResource();
}
这相当于
using (D d = new D())
{
using (C c = new C(d))
{
c.UseLimitedResource();
}
}
让我们尝试在增加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相关联。
编辑:既然这引起了一些关注,我将澄清我的观点。我想回答的问题是
使用第一个版本的好处是什么?
我已经描述过了。有一些好处。但是,在我看来,“总是”的规则并不总是适用。所以我并不完全支持
总是使用{}块-即使是单行//不可以,为什么??
我并不是说总是使用{}块。如果这是一个足够简单的条件和行为,那就不要。如果你怀疑有人可能稍后会来修改你的代码来增加功能,那就这么做。
在“总是使用牙套”的营地呆了10年之后,我最近开始不怎么使用牙套了。
主要是受到Bob叔叔关于如何编写干净代码的争论的启发,我现在相信不使用大括号编写代码更具有可读性。
if(guardClause)
throw new SomeException(..)
Bob大叔认为,在if/for语句中编写多行代码是潜在的可读性问题。
e.g.
if(someCondition)
{
doTechnicalThingX();
doTechnicalThingY();
doTechnicalThingZ();
}
应该被重构为
if(someCondition)
doFunctionalThingA();
对我来说,不把大括号放在那里是有帮助的,因为我得到提醒,我在if块中写了太多代码。
正如其他人所提到的,我相信代码风格是团队决策。
我必须承认,我并不总是在单行中使用{},但这是一种很好的练习。
假设你写的代码没有括号,看起来像这样:
For (int I = 0;I < 100;+ + i)
For (int j = 0;J < 100;+ + j)
DoSingleStuff ();
过了一段时间,你想在j循环中添加一些其他东西,你只是通过对齐来做,忘记添加括号。
Memory deallocation is faster. Let’s say you have a big scope and create big arrays inside (without new so they are on the stack). Those arrays are removed from memory just after you leave the scope. But it is possible that you use that array in one place and it will be on the stack for a while and be some kind of rubbish. As a stack have limited and quite small size, it is possible to exceed the stack size. So in some cases it is better to write {} to preventing that. Note that this is not for a single line, but for such situations:
if (...)
{
//SomeStuff...
{//we have no if, while, etc.
//SomeOtherStuff
}
//SomeMoreStuff
}
The third way to use is similar to the second. It is just not to make the stack cleaner, but to open some functions. If you use mutex in long functions usually it is better to lock and unlock just before accessing data and just after finishing reading/writing that. Note: This way is used if you have some of your own class or struct with a constructor and destructor to lock memory.
What is more:
if (...)
if (...)
SomeStuff();
else
SomeOtherStuff(); // Goes to the second if, but alignment shows it is on first...
总而言之,我不能说,总是使用{}的最佳方式是单行,但这样做并没有什么不好。
如果你编写的是编译代码,但是如果你的代码是被解释的,那么你的代码就会非常非常慢。非常轻微。